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 "meshRefinement.H"
00027 #include <autoMesh/trackedParticle.H>
00028 #include <OpenFOAM/syncTools.H>
00029 #include <OpenFOAM/Time.H>
00030 #include <autoMesh/refinementSurfaces.H>
00031 #include <autoMesh/shellSurfaces.H>
00032 #include <meshTools/faceSet.H>
00033 #include <decompositionMethods/decompositionMethod.H>
00034 #include <dynamicMesh/fvMeshDistribute.H>
00035 #include <dynamicMesh/polyTopoChange.H>
00036 #include <OpenFOAM/mapDistributePolyMesh.H>
00037 #include <edgeMesh/featureEdgeMesh.H>
00038 #include <lagrangian/Cloud.H>
00039
00040
00041
00042
00043
00044
00045
00046
00047 Foam::labelList Foam::meshRefinement::getChangedFaces
00048 (
00049 const mapPolyMesh& map,
00050 const labelList& oldCellsToRefine
00051 )
00052 {
00053 const polyMesh& mesh = map.mesh();
00054
00055 labelList changedFaces;
00056 {
00057
00058
00059
00060
00061
00062
00063
00064
00065 const labelList& faceOwner = mesh.faceOwner();
00066 const labelList& faceNeighbour = mesh.faceNeighbour();
00067 const cellList& cells = mesh.cells();
00068 const label nInternalFaces = mesh.nInternalFaces();
00069
00070
00071 PackedBoolList oldRefineCell(map.nOldCells());
00072
00073 forAll(oldCellsToRefine, i)
00074 {
00075 oldRefineCell.set(oldCellsToRefine[i], 1u);
00076 }
00077
00078
00079 PackedBoolList refinedInternalFace(nInternalFaces);
00080
00081
00082
00083 for (label faceI = 0; faceI < nInternalFaces; faceI++)
00084 {
00085 label oldOwn = map.cellMap()[faceOwner[faceI]];
00086 label oldNei = map.cellMap()[faceNeighbour[faceI]];
00087
00088 if
00089 (
00090 oldOwn >= 0
00091 && oldRefineCell.get(oldOwn) == 0u
00092 && oldNei >= 0
00093 && oldRefineCell.get(oldNei) == 0u
00094 )
00095 {
00096
00097 }
00098 else
00099 {
00100 refinedInternalFace.set(faceI, 1u);
00101 }
00102 }
00103
00104
00105
00106
00107 boolList refinedBoundaryFace(mesh.nFaces()-nInternalFaces, false);
00108
00109 forAll(mesh.boundaryMesh(), patchI)
00110 {
00111 const polyPatch& pp = mesh.boundaryMesh()[patchI];
00112
00113 label faceI = pp.start();
00114
00115 forAll(pp, i)
00116 {
00117 label oldOwn = map.cellMap()[faceOwner[faceI]];
00118
00119 if (oldOwn >= 0 && oldRefineCell.get(oldOwn) == 0u)
00120 {
00121
00122 }
00123 else
00124 {
00125 refinedBoundaryFace[faceI-nInternalFaces] = true;
00126 }
00127 faceI++;
00128 }
00129 }
00130
00131
00132 syncTools::syncBoundaryFaceList
00133 (
00134 mesh,
00135 refinedBoundaryFace,
00136 orEqOp<bool>(),
00137 false
00138 );
00139
00140
00141
00142
00143
00144 boolList changedFace(mesh.nFaces(), false);
00145
00146 forAll(refinedInternalFace, faceI)
00147 {
00148 if (refinedInternalFace.get(faceI) == 1u)
00149 {
00150 const cell& ownFaces = cells[faceOwner[faceI]];
00151 forAll(ownFaces, ownI)
00152 {
00153 changedFace[ownFaces[ownI]] = true;
00154 }
00155 const cell& neiFaces = cells[faceNeighbour[faceI]];
00156 forAll(neiFaces, neiI)
00157 {
00158 changedFace[neiFaces[neiI]] = true;
00159 }
00160 }
00161 }
00162
00163 forAll(refinedBoundaryFace, i)
00164 {
00165 if (refinedBoundaryFace[i])
00166 {
00167 const cell& ownFaces = cells[faceOwner[i+nInternalFaces]];
00168 forAll(ownFaces, ownI)
00169 {
00170 changedFace[ownFaces[ownI]] = true;
00171 }
00172 }
00173 }
00174
00175 syncTools::syncFaceList
00176 (
00177 mesh,
00178 changedFace,
00179 orEqOp<bool>(),
00180 false
00181 );
00182
00183
00184
00185
00186
00187 label nChanged = 0;
00188
00189 forAll(changedFace, faceI)
00190 {
00191 if (changedFace[faceI])
00192 {
00193 nChanged++;
00194 }
00195 }
00196
00197 changedFaces.setSize(nChanged);
00198 nChanged = 0;
00199
00200 forAll(changedFace, faceI)
00201 {
00202 if (changedFace[faceI])
00203 {
00204 changedFaces[nChanged++] = faceI;
00205 }
00206 }
00207 }
00208
00209 label nChangedFaces = changedFaces.size();
00210 reduce(nChangedFaces, sumOp<label>());
00211
00212 if (debug)
00213 {
00214 Pout<< "getChangedFaces : Detected "
00215 << " local:" << changedFaces.size()
00216 << " global:" << nChangedFaces
00217 << " changed faces out of " << mesh.globalData().nTotalFaces()
00218 << endl;
00219
00220 faceSet changedFacesSet(mesh, "changedFaces", changedFaces);
00221 Pout<< "getChangedFaces : Writing " << changedFaces.size()
00222 << " changed faces to faceSet " << changedFacesSet.name()
00223 << endl;
00224 changedFacesSet.write();
00225 }
00226
00227 return changedFaces;
00228 }
00229
00230
00231
00232
00233
00234 bool Foam::meshRefinement::markForRefine
00235 (
00236 const label markValue,
00237 const label nAllowRefine,
00238
00239 label& cellValue,
00240 label& nRefine
00241 )
00242 {
00243 if (cellValue == -1)
00244 {
00245 cellValue = markValue;
00246 nRefine++;
00247 }
00248
00249 return nRefine <= nAllowRefine;
00250 }
00251
00252
00253
00254 Foam::label Foam::meshRefinement::markFeatureRefinement
00255 (
00256 const point& keepPoint,
00257 const PtrList<featureEdgeMesh>& featureMeshes,
00258 const labelList& featureLevels,
00259 const label nAllowRefine,
00260
00261 labelList& refineCell,
00262 label& nRefine
00263 ) const
00264 {
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 Cloud<trackedParticle> cloud(mesh_, IDLList<trackedParticle>());
00282
00283
00284 label cellI = mesh_.findCell(keepPoint);
00285
00286 if (cellI != -1)
00287 {
00288 forAll(featureMeshes, featI)
00289 {
00290 const featureEdgeMesh& featureMesh = featureMeshes[featI];
00291 const labelListList& pointEdges = featureMesh.pointEdges();
00292
00293 forAll(pointEdges, pointI)
00294 {
00295 if (pointEdges[pointI].size() != 2)
00296 {
00297 if (debug)
00298 {
00299 Pout<< "Adding particle from point:" << pointI
00300 << " coord:" << featureMesh.points()[pointI]
00301 << " pEdges:" << pointEdges[pointI]
00302 << endl;
00303 }
00304
00305
00306 cloud.addParticle
00307 (
00308 new trackedParticle
00309 (
00310 cloud,
00311 keepPoint,
00312 cellI,
00313 featureMesh.points()[pointI],
00314 featureLevels[featI],
00315 featI,
00316 pointI
00317 )
00318 );
00319 }
00320 }
00321 }
00322 }
00323
00324
00325
00326 labelList maxFeatureLevel(mesh_.nCells(), -1);
00327
00328
00329 trackedParticle::trackData td(cloud, maxFeatureLevel);
00330
00331
00332 cloud.move(td);
00333
00334
00335 maxFeatureLevel = -1;
00336
00337
00338 List<PackedBoolList> featureEdgeVisited(featureMeshes.size());
00339
00340 forAll(featureMeshes, featI)
00341 {
00342 featureEdgeVisited[featI].setSize(featureMeshes[featI].edges().size());
00343 featureEdgeVisited[featI] = 0u;
00344 }
00345
00346 while (true)
00347 {
00348 label nParticles = 0;
00349
00350
00351 forAllIter(Cloud<trackedParticle>, cloud, iter)
00352 {
00353 trackedParticle& tp = iter();
00354
00355 label featI = tp.i();
00356 label pointI = tp.j();
00357
00358 const featureEdgeMesh& featureMesh = featureMeshes[featI];
00359 const labelList& pEdges = featureMesh.pointEdges()[pointI];
00360
00361
00362
00363
00364 bool keepParticle = false;
00365
00366 forAll(pEdges, i)
00367 {
00368 label edgeI = pEdges[i];
00369
00370 if (featureEdgeVisited[featI].set(edgeI, 1u))
00371 {
00372
00373
00374
00375 const edge& e = featureMesh.edges()[edgeI];
00376 label otherPointI = e.otherVertex(pointI);
00377
00378 tp.end() = featureMesh.points()[otherPointI];
00379 tp.j() = otherPointI;
00380 keepParticle = true;
00381 break;
00382 }
00383 }
00384
00385 if (!keepParticle)
00386 {
00387
00388
00389 cloud.deleteParticle(tp);
00390 }
00391 else
00392 {
00393
00394 nParticles++;
00395 }
00396 }
00397
00398 reduce(nParticles, sumOp<label>());
00399 if (nParticles == 0)
00400 {
00401 break;
00402 }
00403
00404
00405 cloud.move(td);
00406 }
00407
00408
00409
00410
00411
00412 const labelList& cellLevel = meshCutter_.cellLevel();
00413
00414 label oldNRefine = nRefine;
00415
00416 forAll(maxFeatureLevel, cellI)
00417 {
00418 if (maxFeatureLevel[cellI] > cellLevel[cellI])
00419 {
00420
00421 if
00422 (
00423 !markForRefine
00424 (
00425 0,
00426 nAllowRefine,
00427 refineCell[cellI],
00428 nRefine
00429 )
00430 )
00431 {
00432
00433 break;
00434 }
00435 }
00436 }
00437
00438 if
00439 (
00440 returnReduce(nRefine, sumOp<label>())
00441 > returnReduce(nAllowRefine, sumOp<label>())
00442 )
00443 {
00444 Info<< "Reached refinement limit." << endl;
00445 }
00446
00447 return returnReduce(nRefine-oldNRefine, sumOp<label>());
00448 }
00449
00450
00451
00452 Foam::label Foam::meshRefinement::markInternalRefinement
00453 (
00454 const label nAllowRefine,
00455
00456 labelList& refineCell,
00457 label& nRefine
00458 ) const
00459 {
00460 const labelList& cellLevel = meshCutter_.cellLevel();
00461 const pointField& cellCentres = mesh_.cellCentres();
00462
00463 label oldNRefine = nRefine;
00464
00465
00466 pointField testCc(cellLevel.size()-nRefine);
00467 labelList testLevels(cellLevel.size()-nRefine);
00468 label testI = 0;
00469
00470 forAll(cellLevel, cellI)
00471 {
00472 if (refineCell[cellI] == -1)
00473 {
00474 testCc[testI] = cellCentres[cellI];
00475 testLevels[testI] = cellLevel[cellI];
00476 testI++;
00477 }
00478 }
00479
00480
00481 labelList maxLevel;
00482 shells_.findHigherLevel(testCc, testLevels, maxLevel);
00483
00484
00485
00486 testI = 0;
00487 forAll(cellLevel, cellI)
00488 {
00489 if (refineCell[cellI] == -1)
00490 {
00491 if (maxLevel[testI] > testLevels[testI])
00492 {
00493 bool reachedLimit = !markForRefine
00494 (
00495 maxLevel[testI],
00496 nAllowRefine,
00497 refineCell[cellI],
00498 nRefine
00499 );
00500
00501 if (reachedLimit)
00502 {
00503 if (debug)
00504 {
00505 Pout<< "Stopped refining internal cells"
00506 << " since reaching my cell limit of "
00507 << mesh_.nCells()+7*nRefine << endl;
00508 }
00509 break;
00510 }
00511 }
00512 testI++;
00513 }
00514 }
00515
00516 if
00517 (
00518 returnReduce(nRefine, sumOp<label>())
00519 > returnReduce(nAllowRefine, sumOp<label>())
00520 )
00521 {
00522 Info<< "Reached refinement limit." << endl;
00523 }
00524
00525 return returnReduce(nRefine-oldNRefine, sumOp<label>());
00526 }
00527
00528
00529
00530
00531 Foam::labelList Foam::meshRefinement::getRefineCandidateFaces
00532 (
00533 const labelList& refineCell
00534 ) const
00535 {
00536 labelList testFaces(mesh_.nFaces());
00537
00538 label nTest = 0;
00539
00540 forAll(surfaceIndex_, faceI)
00541 {
00542 if (surfaceIndex_[faceI] != -1)
00543 {
00544 label own = mesh_.faceOwner()[faceI];
00545
00546 if (mesh_.isInternalFace(faceI))
00547 {
00548 label nei = mesh_.faceNeighbour()[faceI];
00549
00550 if (refineCell[own] == -1 || refineCell[nei] == -1)
00551 {
00552 testFaces[nTest++] = faceI;
00553 }
00554 }
00555 else
00556 {
00557 if (refineCell[own] == -1)
00558 {
00559 testFaces[nTest++] = faceI;
00560 }
00561 }
00562 }
00563 }
00564 testFaces.setSize(nTest);
00565
00566 return testFaces;
00567 }
00568
00569
00570
00571 Foam::label Foam::meshRefinement::markSurfaceRefinement
00572 (
00573 const label nAllowRefine,
00574 const labelList& neiLevel,
00575 const pointField& neiCc,
00576
00577 labelList& refineCell,
00578 label& nRefine
00579 ) const
00580 {
00581 const labelList& cellLevel = meshCutter_.cellLevel();
00582 const pointField& cellCentres = mesh_.cellCentres();
00583
00584 label oldNRefine = nRefine;
00585
00586
00587
00588
00589
00590
00591
00592 labelList testFaces(getRefineCandidateFaces(refineCell));
00593
00594
00595
00596
00597 pointField start(testFaces.size());
00598 pointField end(testFaces.size());
00599 labelList minLevel(testFaces.size());
00600
00601 forAll(testFaces, i)
00602 {
00603 label faceI = testFaces[i];
00604
00605 label own = mesh_.faceOwner()[faceI];
00606
00607 if (mesh_.isInternalFace(faceI))
00608 {
00609 label nei = mesh_.faceNeighbour()[faceI];
00610
00611 start[i] = cellCentres[own];
00612 end[i] = cellCentres[nei];
00613 minLevel[i] = min(cellLevel[own], cellLevel[nei]);
00614 }
00615 else
00616 {
00617 label bFaceI = faceI - mesh_.nInternalFaces();
00618
00619 start[i] = cellCentres[own];
00620 end[i] = neiCc[bFaceI];
00621 minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
00622 }
00623 }
00624
00625
00626
00627
00628
00629 labelList surfaceHit;
00630 labelList surfaceMinLevel;
00631 surfaces_.findHigherIntersection
00632 (
00633 start,
00634 end,
00635 minLevel,
00636
00637 surfaceHit,
00638 surfaceMinLevel
00639 );
00640
00641
00642
00643
00644
00645 forAll(testFaces, i)
00646 {
00647 label faceI = testFaces[i];
00648
00649 label surfI = surfaceHit[i];
00650
00651 if (surfI != -1)
00652 {
00653
00654
00655
00656
00657
00658
00659 label own = mesh_.faceOwner()[faceI];
00660
00661 if (surfaceMinLevel[i] > cellLevel[own])
00662 {
00663
00664 if
00665 (
00666 !markForRefine
00667 (
00668 surfI,
00669 nAllowRefine,
00670 refineCell[own],
00671 nRefine
00672 )
00673 )
00674 {
00675 break;
00676 }
00677 }
00678
00679 if (mesh_.isInternalFace(faceI))
00680 {
00681 label nei = mesh_.faceNeighbour()[faceI];
00682 if (surfaceMinLevel[i] > cellLevel[nei])
00683 {
00684
00685 if
00686 (
00687 !markForRefine
00688 (
00689 surfI,
00690 nAllowRefine,
00691 refineCell[nei],
00692 nRefine
00693 )
00694 )
00695 {
00696 break;
00697 }
00698 }
00699 }
00700 }
00701 }
00702
00703 if
00704 (
00705 returnReduce(nRefine, sumOp<label>())
00706 > returnReduce(nAllowRefine, sumOp<label>())
00707 )
00708 {
00709 Info<< "Reached refinement limit." << endl;
00710 }
00711
00712 return returnReduce(nRefine-oldNRefine, sumOp<label>());
00713 }
00714
00715
00716
00717
00718
00719
00720 bool Foam::meshRefinement::checkCurvature
00721 (
00722 const scalar curvature,
00723 const label nAllowRefine,
00724
00725 const label surfaceLevel,
00726 const vector& surfaceNormal,
00727
00728 const label cellI,
00729
00730 label& cellMaxLevel,
00731 vector& cellMaxNormal,
00732
00733 labelList& refineCell,
00734 label& nRefine
00735 ) const
00736 {
00737 const labelList& cellLevel = meshCutter_.cellLevel();
00738
00739
00740 if (surfaceLevel > cellLevel[cellI])
00741 {
00742 if (cellMaxLevel == -1)
00743 {
00744
00745 cellMaxLevel = surfaceLevel;
00746 cellMaxNormal = surfaceNormal;
00747 }
00748 else
00749 {
00750
00751 if ((cellMaxNormal & surfaceNormal) < curvature)
00752 {
00753 return markForRefine
00754 (
00755 surfaceLevel,
00756 nAllowRefine,
00757 refineCell[cellI],
00758 nRefine
00759 );
00760 }
00761
00762
00763
00764 if (surfaceLevel > cellMaxLevel)
00765 {
00766 cellMaxLevel = surfaceLevel;
00767 cellMaxNormal = surfaceNormal;
00768 }
00769 }
00770 }
00771
00772
00773 return true;
00774 }
00775
00776
00777
00778 Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
00779 (
00780 const scalar curvature,
00781 const label nAllowRefine,
00782 const labelList& neiLevel,
00783 const pointField& neiCc,
00784
00785 labelList& refineCell,
00786 label& nRefine
00787 ) const
00788 {
00789 const labelList& cellLevel = meshCutter_.cellLevel();
00790 const pointField& cellCentres = mesh_.cellCentres();
00791
00792 label oldNRefine = nRefine;
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 labelList testFaces(getRefineCandidateFaces(refineCell));
00804
00805
00806 pointField start(testFaces.size());
00807 pointField end(testFaces.size());
00808 labelList minLevel(testFaces.size());
00809
00810 forAll(testFaces, i)
00811 {
00812 label faceI = testFaces[i];
00813
00814 label own = mesh_.faceOwner()[faceI];
00815
00816 if (mesh_.isInternalFace(faceI))
00817 {
00818 label nei = mesh_.faceNeighbour()[faceI];
00819
00820 start[i] = cellCentres[own];
00821 end[i] = cellCentres[nei];
00822 minLevel[i] = min(cellLevel[own], cellLevel[nei]);
00823 }
00824 else
00825 {
00826 label bFaceI = faceI - mesh_.nInternalFaces();
00827
00828 start[i] = cellCentres[own];
00829 end[i] = neiCc[bFaceI];
00830 minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
00831 }
00832 }
00833
00834
00835
00836
00837 labelList cellMaxLevel(mesh_.nCells(), -1);
00838 vectorField cellMaxNormal(mesh_.nCells(), vector::zero);
00839
00840 {
00841
00842 List<vectorList> surfaceNormal;
00843
00844 labelListList surfaceLevel;
00845
00846 surfaces_.findAllHigherIntersections
00847 (
00848 start,
00849 end,
00850 minLevel,
00851
00852 surfaceNormal,
00853 surfaceLevel
00854 );
00855
00856 start.clear();
00857 end.clear();
00858 minLevel.clear();
00859
00860
00861 forAll(testFaces, i)
00862 {
00863 label faceI = testFaces[i];
00864 label own = mesh_.faceOwner()[faceI];
00865
00866 const vectorList& fNormals = surfaceNormal[i];
00867 const labelList& fLevels = surfaceLevel[i];
00868
00869 forAll(fLevels, hitI)
00870 {
00871 checkCurvature
00872 (
00873 curvature,
00874 nAllowRefine,
00875
00876 fLevels[hitI],
00877 fNormals[hitI],
00878
00879 own,
00880 cellMaxLevel[own],
00881 cellMaxNormal[own],
00882
00883 refineCell,
00884 nRefine
00885 );
00886 }
00887
00888 if (mesh_.isInternalFace(faceI))
00889 {
00890 label nei = mesh_.faceNeighbour()[faceI];
00891
00892 forAll(fLevels, hitI)
00893 {
00894 checkCurvature
00895 (
00896 curvature,
00897 nAllowRefine,
00898
00899 fLevels[hitI],
00900 fNormals[hitI],
00901
00902 nei,
00903 cellMaxLevel[nei],
00904 cellMaxNormal[nei],
00905
00906 refineCell,
00907 nRefine
00908 );
00909 }
00910 }
00911 }
00912 }
00913
00914
00915
00916
00917 labelList neiBndMaxLevel(mesh_.nFaces()-mesh_.nInternalFaces());
00918 vectorField neiBndMaxNormal(mesh_.nFaces()-mesh_.nInternalFaces());
00919
00920 for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
00921 {
00922 label bFaceI = faceI-mesh_.nInternalFaces();
00923 label own = mesh_.faceOwner()[faceI];
00924
00925 neiBndMaxLevel[bFaceI] = cellMaxLevel[own];
00926 neiBndMaxNormal[bFaceI] = cellMaxNormal[own];
00927 }
00928 syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLevel, false);
00929 syncTools::swapBoundaryFaceList(mesh_, neiBndMaxNormal, false);
00930
00931
00932
00933
00934 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
00935 {
00936 label own = mesh_.faceOwner()[faceI];
00937 label nei = mesh_.faceNeighbour()[faceI];
00938
00939 if (cellMaxLevel[own] != -1 && cellMaxLevel[nei] != -1)
00940 {
00941
00942 if ((cellMaxNormal[own] & cellMaxNormal[nei]) < curvature)
00943 {
00944
00945 if (cellLevel[own] < cellMaxLevel[own])
00946 {
00947 if
00948 (
00949 !markForRefine
00950 (
00951 cellMaxLevel[own],
00952 nAllowRefine,
00953 refineCell[own],
00954 nRefine
00955 )
00956 )
00957 {
00958 if (debug)
00959 {
00960 Pout<< "Stopped refining since reaching my cell"
00961 << " limit of " << mesh_.nCells()+7*nRefine
00962 << endl;
00963 }
00964 break;
00965 }
00966 }
00967
00968 if (cellLevel[nei] < cellMaxLevel[nei])
00969 {
00970 if
00971 (
00972 !markForRefine
00973 (
00974 cellMaxLevel[nei],
00975 nAllowRefine,
00976 refineCell[nei],
00977 nRefine
00978 )
00979 )
00980 {
00981 if (debug)
00982 {
00983 Pout<< "Stopped refining since reaching my cell"
00984 << " limit of " << mesh_.nCells()+7*nRefine
00985 << endl;
00986 }
00987 break;
00988 }
00989 }
00990 }
00991 }
00992 }
00993
00994 for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
00995 {
00996 label own = mesh_.faceOwner()[faceI];
00997 label bFaceI = faceI - mesh_.nInternalFaces();
00998
00999 if (cellLevel[own] < cellMaxLevel[own] && neiBndMaxLevel[bFaceI] != -1)
01000 {
01001
01002 if ((cellMaxNormal[own] & neiBndMaxNormal[bFaceI]) < curvature)
01003 {
01004 if
01005 (
01006 !markForRefine
01007 (
01008 cellMaxLevel[own],
01009 nAllowRefine,
01010 refineCell[own],
01011 nRefine
01012 )
01013 )
01014 {
01015 if (debug)
01016 {
01017 Pout<< "Stopped refining since reaching my cell"
01018 << " limit of " << mesh_.nCells()+7*nRefine
01019 << endl;
01020 }
01021 break;
01022 }
01023 }
01024 }
01025 }
01026
01027 if
01028 (
01029 returnReduce(nRefine, sumOp<label>())
01030 > returnReduce(nAllowRefine, sumOp<label>())
01031 )
01032 {
01033 Info<< "Reached refinement limit." << endl;
01034 }
01035
01036 return returnReduce(nRefine-oldNRefine, sumOp<label>());
01037 }
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 Foam::labelList Foam::meshRefinement::refineCandidates
01048 (
01049 const point& keepPoint,
01050 const scalar curvature,
01051
01052 const PtrList<featureEdgeMesh>& featureMeshes,
01053 const labelList& featureLevels,
01054
01055 const bool featureRefinement,
01056 const bool internalRefinement,
01057 const bool surfaceRefinement,
01058 const bool curvatureRefinement,
01059 const label maxGlobalCells,
01060 const label maxLocalCells
01061 ) const
01062 {
01063 label totNCells = mesh_.globalData().nTotalCells();
01064
01065 labelList cellsToRefine;
01066
01067 if (totNCells >= maxGlobalCells)
01068 {
01069 Info<< "No cells marked for refinement since reached limit "
01070 << maxGlobalCells << '.' << endl;
01071 }
01072 else
01073 {
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095 label nAllowRefine = labelMax / Pstream::nProcs();
01096
01097
01098
01099 labelList refineCell(mesh_.nCells(), -1);
01100 label nRefine = 0;
01101
01102
01103
01104 labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
01105 pointField neiCc(mesh_.nFaces()-mesh_.nInternalFaces());
01106 calcNeighbourData(neiLevel, neiCc);
01107
01108
01109
01110
01111
01112
01113 if (featureRefinement)
01114 {
01115 label nFeatures = markFeatureRefinement
01116 (
01117 keepPoint,
01118 featureMeshes,
01119 featureLevels,
01120 nAllowRefine,
01121
01122 refineCell,
01123 nRefine
01124 );
01125
01126 Info<< "Marked for refinement due to explicit features : "
01127 << nFeatures << " cells." << endl;
01128 }
01129
01130
01131
01132
01133 if (internalRefinement)
01134 {
01135 label nShell = markInternalRefinement
01136 (
01137 nAllowRefine,
01138
01139 refineCell,
01140 nRefine
01141 );
01142 Info<< "Marked for refinement due to refinement shells : "
01143 << nShell << " cells." << endl;
01144 }
01145
01146
01147
01148
01149 if (surfaceRefinement)
01150 {
01151 label nSurf = markSurfaceRefinement
01152 (
01153 nAllowRefine,
01154 neiLevel,
01155 neiCc,
01156
01157 refineCell,
01158 nRefine
01159 );
01160 Info<< "Marked for refinement due to surface intersection : "
01161 << nSurf << " cells." << endl;
01162 }
01163
01164
01165
01166
01167 if
01168 (
01169 curvatureRefinement
01170 && (curvature >= -1 && curvature <= 1)
01171 && (surfaces_.minLevel() != surfaces_.maxLevel())
01172 )
01173 {
01174 label nCurv = markSurfaceCurvatureRefinement
01175 (
01176 curvature,
01177 nAllowRefine,
01178 neiLevel,
01179 neiCc,
01180
01181 refineCell,
01182 nRefine
01183 );
01184 Info<< "Marked for refinement due to curvature/regions : "
01185 << nCurv << " cells." << endl;
01186 }
01187
01188
01189
01190
01191 cellsToRefine.setSize(nRefine);
01192 nRefine = 0;
01193
01194 forAll(refineCell, cellI)
01195 {
01196 if (refineCell[cellI] != -1)
01197 {
01198 cellsToRefine[nRefine++] = cellI;
01199 }
01200 }
01201 }
01202
01203 return cellsToRefine;
01204 }
01205
01206
01207 Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::refine
01208 (
01209 const labelList& cellsToRefine
01210 )
01211 {
01212
01213 polyTopoChange meshMod(mesh_);
01214
01215
01216 meshCutter_.setRefinement(cellsToRefine, meshMod);
01217
01218
01219 autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false);
01220
01221
01222 mesh_.updateMesh(map);
01223
01224
01225 if (map().hasMotionPoints())
01226 {
01227 mesh_.movePoints(map().preMotionPoints());
01228 }
01229 else
01230 {
01231
01232 mesh_.clearOut();
01233 }
01234
01235 if (overwrite())
01236 {
01237 mesh_.setInstance(oldInstance());
01238 }
01239
01240
01241 updateMesh(map, getChangedFaces(map, cellsToRefine));
01242
01243 return map;
01244 }
01245
01246
01247
01248
01249 Foam::autoPtr<Foam::mapDistributePolyMesh>
01250 Foam::meshRefinement::refineAndBalance
01251 (
01252 const string& msg,
01253 decompositionMethod& decomposer,
01254 fvMeshDistribute& distributor,
01255 const labelList& cellsToRefine,
01256 const scalar maxLoadUnbalance
01257 )
01258 {
01259
01260 refine(cellsToRefine);
01261
01262 if (debug)
01263 {
01264 Pout<< "Writing refined but unbalanced " << msg
01265 << " mesh to time " << timeName() << endl;
01266 write
01267 (
01268 debug,
01269 mesh_.time().path()
01270 /timeName()
01271 );
01272 Pout<< "Dumped debug data in = "
01273 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01274
01275
01276 checkData();
01277 }
01278
01279 Info<< "Refined mesh in = "
01280 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01281 printMeshInfo(debug, "After refinement " + msg);
01282
01283
01284
01285
01286
01287 autoPtr<mapDistributePolyMesh> distMap;
01288
01289 if (Pstream::nProcs() > 1)
01290 {
01291 scalar nIdealCells =
01292 mesh_.globalData().nTotalCells()
01293 / Pstream::nProcs();
01294
01295 scalar unbalance = returnReduce
01296 (
01297 mag(1.0-mesh_.nCells()/nIdealCells),
01298 maxOp<scalar>()
01299 );
01300
01301 if (unbalance <= maxLoadUnbalance)
01302 {
01303 Info<< "Skipping balancing since max unbalance " << unbalance
01304 << " is less than allowable " << maxLoadUnbalance
01305 << endl;
01306 }
01307 else
01308 {
01309 scalarField cellWeights(mesh_.nCells(), 1);
01310
01311 distMap = balance
01312 (
01313 false,
01314 false,
01315 cellWeights,
01316 decomposer,
01317 distributor
01318 );
01319
01320 Info<< "Balanced mesh in = "
01321 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01322
01323 printMeshInfo(debug, "After balancing " + msg);
01324
01325
01326 if (debug)
01327 {
01328 Pout<< "Writing balanced " << msg
01329 << " mesh to time " << timeName() << endl;
01330 write
01331 (
01332 debug,
01333 mesh_.time().path()/timeName()
01334 );
01335 Pout<< "Dumped debug data in = "
01336 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01337
01338
01339 checkData();
01340 }
01341 }
01342 }
01343
01344 return distMap;
01345 }
01346
01347
01348
01349 Foam::autoPtr<Foam::mapDistributePolyMesh>
01350 Foam::meshRefinement::balanceAndRefine
01351 (
01352 const string& msg,
01353 decompositionMethod& decomposer,
01354 fvMeshDistribute& distributor,
01355 const labelList& initCellsToRefine,
01356 const scalar maxLoadUnbalance
01357 )
01358 {
01359 labelList cellsToRefine(initCellsToRefine);
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388 autoPtr<mapDistributePolyMesh> distMap;
01389
01390 if (Pstream::nProcs() > 1)
01391 {
01392
01393
01394 scalar nNewCells = scalar(mesh_.nCells() + 7*cellsToRefine.size());
01395 scalar nIdealNewCells =
01396 returnReduce(nNewCells, sumOp<scalar>())
01397 / Pstream::nProcs();
01398 scalar unbalance = returnReduce
01399 (
01400 mag(1.0-nNewCells/nIdealNewCells),
01401 maxOp<scalar>()
01402 );
01403
01404 if (unbalance <= maxLoadUnbalance)
01405 {
01406 Info<< "Skipping balancing since max unbalance " << unbalance
01407 << " is less than allowable " << maxLoadUnbalance
01408 << endl;
01409 }
01410 else
01411 {
01412 scalarField cellWeights(mesh_.nCells(), 1);
01413 forAll(cellsToRefine, i)
01414 {
01415 cellWeights[cellsToRefine[i]] += 7;
01416 }
01417
01418 distMap = balance
01419 (
01420 false,
01421 false,
01422 cellWeights,
01423 decomposer,
01424 distributor
01425 );
01426
01427
01428 distMap().distributeCellIndices(cellsToRefine);
01429
01430 Info<< "Balanced mesh in = "
01431 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01432 }
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446 printMeshInfo(debug, "After balancing " + msg);
01447
01448 if (debug)
01449 {
01450 Pout<< "Writing balanced " << msg
01451 << " mesh to time " << timeName() << endl;
01452 write
01453 (
01454 debug,
01455 mesh_.time().path()/timeName()
01456 );
01457 Pout<< "Dumped debug data in = "
01458 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01459
01460
01461 checkData();
01462 }
01463 }
01464
01465
01466
01467
01468
01469 refine(cellsToRefine);
01470
01471 if (debug)
01472 {
01473 Pout<< "Writing refined " << msg
01474 << " mesh to time " << timeName() << endl;
01475 write
01476 (
01477 debug,
01478 mesh_.time().path()
01479 /timeName()
01480 );
01481 Pout<< "Dumped debug data in = "
01482 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01483
01484
01485 checkData();
01486 }
01487
01488 Info<< "Refined mesh in = "
01489 << mesh_.time().cpuTimeIncrement() << " s" << endl;
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503 printMeshInfo(debug, "After refinement " + msg);
01504
01505 return distMap;
01506 }
01507
01508
01509