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 "hexRef8.H"
00027
00028 #include <OpenFOAM/polyMesh.H>
00029 #include "polyTopoChange.H"
00030 #include <meshTools/meshTools.H>
00031 #include <dynamicMesh/polyAddFace.H>
00032 #include <dynamicMesh/polyAddPoint.H>
00033 #include <dynamicMesh/polyAddCell.H>
00034 #include <dynamicMesh/polyModifyFace.H>
00035 #include <OpenFOAM/syncTools.H>
00036 #include <meshTools/faceSet.H>
00037 #include <meshTools/cellSet.H>
00038 #include <meshTools/pointSet.H>
00039 #include <OpenFOAM/OFstream.H>
00040 #include <OpenFOAM/Time.H>
00041 #include <OpenFOAM/FaceCellWave.H>
00042 #include <OpenFOAM/mapDistributePolyMesh.H>
00043 #include "refinementData.H"
00044 #include "refinementDistanceData.H"
00045
00046
00047
00048 namespace Foam
00049 {
00050 defineTypeNameAndDebug(hexRef8, 0);
00051
00052
00053 template<int value>
00054 class ifEqEqOp
00055 {
00056 public:
00057 void operator()(label& x, const label& y) const
00058 {
00059 x = (x==y) ? x : value;
00060 }
00061 };
00062 }
00063
00064
00065
00066
00067 void Foam::hexRef8::reorder
00068 (
00069 const labelList& map,
00070 const label len,
00071 const label null,
00072 labelList& elems
00073 )
00074 {
00075 labelList newElems(len, null);
00076
00077 forAll(elems, i)
00078 {
00079 label newI = map[i];
00080
00081 if (newI >= len)
00082 {
00083 FatalErrorIn("hexRef8::reorder(..)") << abort(FatalError);
00084 }
00085
00086 if (newI >= 0)
00087 {
00088 newElems[newI] = elems[i];
00089 }
00090 }
00091
00092 elems.transfer(newElems);
00093 }
00094
00095
00096 void Foam::hexRef8::getFaceInfo
00097 (
00098 const label faceI,
00099 label& patchID,
00100 label& zoneID,
00101 label& zoneFlip
00102 ) const
00103 {
00104 patchID = -1;
00105
00106 if (!mesh_.isInternalFace(faceI))
00107 {
00108 patchID = mesh_.boundaryMesh().whichPatch(faceI);
00109 }
00110
00111 zoneID = mesh_.faceZones().whichZone(faceI);
00112
00113 zoneFlip = false;
00114
00115 if (zoneID >= 0)
00116 {
00117 const faceZone& fZone = mesh_.faceZones()[zoneID];
00118
00119 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
00120 }
00121 }
00122
00123
00124
00125 Foam::label Foam::hexRef8::addFace
00126 (
00127 polyTopoChange& meshMod,
00128 const label faceI,
00129 const face& newFace,
00130 const label own,
00131 const label nei
00132 ) const
00133 {
00134 label patchID, zoneID, zoneFlip;
00135
00136 getFaceInfo(faceI, patchID, zoneID, zoneFlip);
00137
00138 label newFaceI = -1;
00139
00140 if ((nei == -1) || (own < nei))
00141 {
00142
00143 newFaceI = meshMod.setAction
00144 (
00145 polyAddFace
00146 (
00147 newFace,
00148 own,
00149 nei,
00150 -1,
00151 -1,
00152 faceI,
00153 false,
00154 patchID,
00155 zoneID,
00156 zoneFlip
00157 )
00158 );
00159 }
00160 else
00161 {
00162
00163 newFaceI = meshMod.setAction
00164 (
00165 polyAddFace
00166 (
00167 newFace.reverseFace(),
00168 nei,
00169 own,
00170 -1,
00171 -1,
00172 faceI,
00173 false,
00174 patchID,
00175 zoneID,
00176 zoneFlip
00177 )
00178 );
00179 }
00180 return newFaceI;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190 Foam::label Foam::hexRef8::addInternalFace
00191 (
00192 polyTopoChange& meshMod,
00193 const label meshFaceI,
00194 const label meshPointI,
00195 const face& newFace,
00196 const label own,
00197 const label nei
00198 ) const
00199 {
00200 if (mesh_.isInternalFace(meshFaceI))
00201 {
00202 return meshMod.setAction
00203 (
00204 polyAddFace
00205 (
00206 newFace,
00207 own,
00208 nei,
00209 -1,
00210 -1,
00211 meshFaceI,
00212 false,
00213 -1,
00214 -1,
00215 false
00216 )
00217 );
00218 }
00219 else
00220 {
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 return meshMod.setAction
00231 (
00232 polyAddFace
00233 (
00234 newFace,
00235 own,
00236 nei,
00237 -1,
00238 -1,
00239 -1,
00240 false,
00241 -1,
00242 -1,
00243 false
00244 )
00245 );
00246
00247
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 }
00282 }
00283
00284
00285
00286 void Foam::hexRef8::modFace
00287 (
00288 polyTopoChange& meshMod,
00289 const label faceI,
00290 const face& newFace,
00291 const label own,
00292 const label nei
00293 ) const
00294 {
00295 label patchID, zoneID, zoneFlip;
00296
00297 getFaceInfo(faceI, patchID, zoneID, zoneFlip);
00298
00299 if
00300 (
00301 (own != mesh_.faceOwner()[faceI])
00302 || (
00303 mesh_.isInternalFace(faceI)
00304 && (nei != mesh_.faceNeighbour()[faceI])
00305 )
00306 || (newFace != mesh_.faces()[faceI])
00307 )
00308 {
00309 if ((nei == -1) || (own < nei))
00310 {
00311 meshMod.setAction
00312 (
00313 polyModifyFace
00314 (
00315 newFace,
00316 faceI,
00317 own,
00318 nei,
00319 false,
00320 patchID,
00321 false,
00322 zoneID,
00323 zoneFlip
00324 )
00325 );
00326 }
00327 else
00328 {
00329 meshMod.setAction
00330 (
00331 polyModifyFace
00332 (
00333 newFace.reverseFace(),
00334 faceI,
00335 nei,
00336 own,
00337 false,
00338 patchID,
00339 false,
00340 zoneID,
00341 zoneFlip
00342 )
00343 );
00344 }
00345 }
00346 }
00347
00348
00349
00350 Foam::scalar Foam::hexRef8::getLevel0EdgeLength() const
00351 {
00352 if (cellLevel_.size() != mesh_.nCells())
00353 {
00354 FatalErrorIn
00355 (
00356 "hexRef8::getLevel0EdgeLength() const"
00357 ) << "Number of cells in mesh:" << mesh_.nCells()
00358 << " does not equal size of cellLevel:" << cellLevel_.size()
00359 << endl
00360 << "This might be because of a restart with inconsistent cellLevel."
00361 << abort(FatalError);
00362 }
00363
00364
00365
00366
00367 const scalar GREAT2 = sqr(GREAT);
00368
00369 label nLevels = gMax(cellLevel_)+1;
00370
00371 scalarField typEdgeLenSqr(nLevels, GREAT2);
00372
00373
00374
00375
00376
00377 {
00378
00379
00380 labelList edgeLevel(mesh_.nEdges(), -1);
00381
00382 forAll(cellLevel_, cellI)
00383 {
00384 const label cLevel = cellLevel_[cellI];
00385
00386 const labelList& cEdges = mesh_.cellEdges(cellI);
00387
00388 forAll(cEdges, i)
00389 {
00390 label edgeI = cEdges[i];
00391
00392 if (edgeLevel[edgeI] == -1)
00393 {
00394 edgeLevel[edgeI] = cLevel;
00395 }
00396 else if (edgeLevel[edgeI] == labelMax)
00397 {
00398
00399 }
00400 else if (edgeLevel[edgeI] != cLevel)
00401 {
00402 edgeLevel[edgeI] = labelMax;
00403 }
00404 }
00405 }
00406
00407
00408
00409
00410 syncTools::syncEdgeList
00411 (
00412 mesh_,
00413 edgeLevel,
00414 ifEqEqOp<labelMax>(),
00415 labelMin,
00416 false
00417 );
00418
00419
00420
00421 forAll(edgeLevel, edgeI)
00422 {
00423 const label eLevel = edgeLevel[edgeI];
00424
00425 if (eLevel >= 0 && eLevel < labelMax)
00426 {
00427 const edge& e = mesh_.edges()[edgeI];
00428
00429 scalar edgeLenSqr = magSqr(e.vec(mesh_.points()));
00430
00431 typEdgeLenSqr[eLevel] = min(typEdgeLenSqr[eLevel], edgeLenSqr);
00432 }
00433 }
00434 }
00435
00436
00437
00438 Pstream::listCombineGather(typEdgeLenSqr, minEqOp<scalar>());
00439 Pstream::listCombineScatter(typEdgeLenSqr);
00440
00441 if (debug)
00442 {
00443 Pout<< "hexRef8::getLevel0EdgeLength() :"
00444 << " After phase1: Edgelengths (squared) per refinementlevel:"
00445 << typEdgeLenSqr << endl;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455 scalarField maxEdgeLenSqr(nLevels, -GREAT2);
00456
00457 forAll(cellLevel_, cellI)
00458 {
00459 const label cLevel = cellLevel_[cellI];
00460
00461 const labelList& cEdges = mesh_.cellEdges(cellI);
00462
00463 forAll(cEdges, i)
00464 {
00465 const edge& e = mesh_.edges()[cEdges[i]];
00466
00467 scalar edgeLenSqr = magSqr(e.vec(mesh_.points()));
00468
00469 maxEdgeLenSqr[cLevel] = max(maxEdgeLenSqr[cLevel], edgeLenSqr);
00470 }
00471 }
00472
00473 Pstream::listCombineGather(maxEdgeLenSqr, maxEqOp<scalar>());
00474 Pstream::listCombineScatter(maxEdgeLenSqr);
00475
00476 if (debug)
00477 {
00478 Pout<< "hexRef8::getLevel0EdgeLength() :"
00479 << " Crappy Edgelengths (squared) per refinementlevel:"
00480 << maxEdgeLenSqr << endl;
00481 }
00482
00483
00484
00485
00486
00487 forAll(typEdgeLenSqr, levelI)
00488 {
00489 if (typEdgeLenSqr[levelI] == GREAT2 && maxEdgeLenSqr[levelI] >= 0)
00490 {
00491 typEdgeLenSqr[levelI] = maxEdgeLenSqr[levelI];
00492 }
00493 }
00494
00495 if (debug)
00496 {
00497 Pout<< "hexRef8::getLevel0EdgeLength() :"
00498 << " Final Edgelengths (squared) per refinementlevel:"
00499 << typEdgeLenSqr << endl;
00500 }
00501
00502
00503 scalar level0Size = -1;
00504
00505 forAll(typEdgeLenSqr, levelI)
00506 {
00507 scalar lenSqr = typEdgeLenSqr[levelI];
00508
00509 if (lenSqr < GREAT2)
00510 {
00511 level0Size = Foam::sqrt(lenSqr)*(1<<levelI);
00512
00513 if (debug)
00514 {
00515 Pout<< "hexRef8::getLevel0EdgeLength() :"
00516 << " For level:" << levelI
00517 << " have edgeLen:" << Foam::sqrt(lenSqr)
00518 << " with equivalent level0 len:" << level0Size
00519 << endl;
00520 }
00521 break;
00522 }
00523 }
00524
00525 if (level0Size == -1)
00526 {
00527 FatalErrorIn("hexRef8::getLevel0EdgeLength()")
00528 << "Problem : typEdgeLenSqr:" << typEdgeLenSqr << abort(FatalError);
00529 }
00530
00531 return level0Size;
00532 }
00533
00534
00535
00536
00537 Foam::label Foam::hexRef8::getAnchorCell
00538 (
00539 const labelListList& cellAnchorPoints,
00540 const labelListList& cellAddedCells,
00541 const label cellI,
00542 const label faceI,
00543 const label pointI
00544 ) const
00545 {
00546 if (cellAnchorPoints[cellI].size())
00547 {
00548 label index = findIndex(cellAnchorPoints[cellI], pointI);
00549
00550 if (index != -1)
00551 {
00552 return cellAddedCells[cellI][index];
00553 }
00554
00555
00556
00557
00558
00559 const face& f = mesh_.faces()[faceI];
00560
00561 forAll(f, fp)
00562 {
00563 label index = findIndex(cellAnchorPoints[cellI], f[fp]);
00564
00565 if (index != -1)
00566 {
00567 return cellAddedCells[cellI][index];
00568 }
00569 }
00570
00571
00572 dumpCell(cellI);
00573 Perr<< "cell:" << cellI << " anchorPoints:" << cellAnchorPoints[cellI]
00574 << endl;
00575
00576 FatalErrorIn("hexRef8::getAnchorCell(..)")
00577 << "Could not find point " << pointI
00578 << " in the anchorPoints for cell " << cellI << endl
00579 << "Does your original mesh obey the 2:1 constraint and"
00580 << " did you use consistentRefinement to make your cells to refine"
00581 << " obey this constraint as well?"
00582 << abort(FatalError);
00583
00584 return -1;
00585 }
00586 else
00587 {
00588 return cellI;
00589 }
00590 }
00591
00592
00593
00594 void Foam::hexRef8::getFaceNeighbours
00595 (
00596 const labelListList& cellAnchorPoints,
00597 const labelListList& cellAddedCells,
00598 const label faceI,
00599 const label pointI,
00600
00601 label& own,
00602 label& nei
00603 ) const
00604 {
00605
00606 own = getAnchorCell
00607 (
00608 cellAnchorPoints,
00609 cellAddedCells,
00610 mesh_.faceOwner()[faceI],
00611 faceI,
00612 pointI
00613 );
00614
00615 if (mesh_.isInternalFace(faceI))
00616 {
00617 nei = getAnchorCell
00618 (
00619 cellAnchorPoints,
00620 cellAddedCells,
00621 mesh_.faceNeighbour()[faceI],
00622 faceI,
00623 pointI
00624 );
00625 }
00626 else
00627 {
00628 nei = -1;
00629 }
00630 }
00631
00632
00633
00634 Foam::label Foam::hexRef8::findMinLevel(const labelList& f) const
00635 {
00636 label minLevel = labelMax;
00637 label minFp = -1;
00638
00639 forAll(f, fp)
00640 {
00641 label level = pointLevel_[f[fp]];
00642
00643 if (level < minLevel)
00644 {
00645 minLevel = level;
00646 minFp = fp;
00647 }
00648 }
00649
00650 return minFp;
00651 }
00652
00653
00654
00655 Foam::label Foam::hexRef8::findMaxLevel(const labelList& f) const
00656 {
00657 label maxLevel = labelMin;
00658 label maxFp = -1;
00659
00660 forAll(f, fp)
00661 {
00662 label level = pointLevel_[f[fp]];
00663
00664 if (level > maxLevel)
00665 {
00666 maxLevel = level;
00667 maxFp = fp;
00668 }
00669 }
00670
00671 return maxFp;
00672 }
00673
00674
00675 Foam::label Foam::hexRef8::countAnchors
00676 (
00677 const labelList& f,
00678 const label anchorLevel
00679 ) const
00680 {
00681 label nAnchors = 0;
00682
00683 forAll(f, fp)
00684 {
00685 if (pointLevel_[f[fp]] <= anchorLevel)
00686 {
00687 nAnchors++;
00688 }
00689 }
00690 return nAnchors;
00691 }
00692
00693
00694 void Foam::hexRef8::dumpCell(const label cellI) const
00695 {
00696 OFstream str(mesh_.time().path()/"cell_" + Foam::name(cellI) + ".obj");
00697 Pout<< "hexRef8 : Dumping cell as obj to " << str.name() << endl;
00698
00699 const cell& cFaces = mesh_.cells()[cellI];
00700
00701 Map<label> pointToObjVert;
00702 label objVertI = 0;
00703
00704 forAll(cFaces, i)
00705 {
00706 const face& f = mesh_.faces()[cFaces[i]];
00707
00708 forAll(f, fp)
00709 {
00710 if (pointToObjVert.insert(f[fp], objVertI))
00711 {
00712 meshTools::writeOBJ(str, mesh_.points()[f[fp]]);
00713 objVertI++;
00714 }
00715 }
00716 }
00717
00718 forAll(cFaces, i)
00719 {
00720 const face& f = mesh_.faces()[cFaces[i]];
00721
00722 forAll(f, fp)
00723 {
00724 label pointI = f[fp];
00725 label nexPointI = f[f.fcIndex(fp)];
00726
00727 str << "l " << pointToObjVert[pointI]+1
00728 << ' ' << pointToObjVert[nexPointI]+1 << nl;
00729 }
00730 }
00731 }
00732
00733
00734
00735 Foam::label Foam::hexRef8::findLevel
00736 (
00737 const label faceI,
00738 const face& f,
00739 const label startFp,
00740 const bool searchForward,
00741 const label wantedLevel
00742 ) const
00743 {
00744 label fp = startFp;
00745
00746 forAll(f, i)
00747 {
00748 label pointI = f[fp];
00749
00750 if (pointLevel_[pointI] < wantedLevel)
00751 {
00752 dumpCell(mesh_.faceOwner()[faceI]);
00753 if (mesh_.isInternalFace(faceI))
00754 {
00755 dumpCell(mesh_.faceNeighbour()[faceI]);
00756 }
00757
00758 FatalErrorIn("hexRef8::findLevel(..)")
00759 << "face:" << f
00760 << " level:" << UIndirectList<label>(pointLevel_, f)()
00761 << " startFp:" << startFp
00762 << " wantedLevel:" << wantedLevel
00763 << abort(FatalError);
00764 }
00765 else if (pointLevel_[pointI] == wantedLevel)
00766 {
00767 return fp;
00768 }
00769
00770 if (searchForward)
00771 {
00772 fp = f.fcIndex(fp);
00773 }
00774 else
00775 {
00776 fp = f.rcIndex(fp);
00777 }
00778 }
00779
00780 dumpCell(mesh_.faceOwner()[faceI]);
00781 if (mesh_.isInternalFace(faceI))
00782 {
00783 dumpCell(mesh_.faceNeighbour()[faceI]);
00784 }
00785
00786 FatalErrorIn("hexRef8::findLevel(..)")
00787 << "face:" << f
00788 << " level:" << UIndirectList<label>(pointLevel_, f)()
00789 << " startFp:" << startFp
00790 << " wantedLevel:" << wantedLevel
00791 << abort(FatalError);
00792
00793 return -1;
00794 }
00795
00796
00797
00798 Foam::label Foam::hexRef8::getAnchorLevel(const label faceI) const
00799 {
00800 const face& f = mesh_.faces()[faceI];
00801
00802 if (f.size() <= 4)
00803 {
00804 return pointLevel_[f[findMaxLevel(f)]];
00805 }
00806 else
00807 {
00808 label ownLevel = cellLevel_[mesh_.faceOwner()[faceI]];
00809
00810 if (countAnchors(f, ownLevel) == 4)
00811 {
00812 return ownLevel;
00813 }
00814 else if (countAnchors(f, ownLevel+1) == 4)
00815 {
00816 return ownLevel+1;
00817 }
00818 else
00819 {
00820 return -1;
00821 }
00822 }
00823 }
00824
00825
00826 void Foam::hexRef8::checkInternalOrientation
00827 (
00828 polyTopoChange& meshMod,
00829 const label cellI,
00830 const label faceI,
00831 const point& ownPt,
00832 const point& neiPt,
00833 const face& newFace
00834 )
00835 {
00836 face compactFace(identity(newFace.size()));
00837 pointField compactPoints(meshMod.points(), newFace);
00838
00839 vector n(compactFace.normal(compactPoints));
00840
00841 vector dir(neiPt - ownPt);
00842
00843 if ((dir & n) < 0)
00844 {
00845 FatalErrorIn("checkInternalOrientation(..)")
00846 << "cell:" << cellI << " old face:" << faceI
00847 << " newFace:" << newFace << endl
00848 << " coords:" << compactPoints
00849 << " ownPt:" << ownPt
00850 << " neiPt:" << neiPt
00851 << abort(FatalError);
00852 }
00853
00854 vector fcToOwn(compactFace.centre(compactPoints) - ownPt);
00855
00856 scalar s = (fcToOwn&n) / (dir&n);
00857
00858 if (s < 0.1 || s > 0.9)
00859 {
00860 FatalErrorIn("checkInternalOrientation(..)")
00861 << "cell:" << cellI << " old face:" << faceI
00862 << " newFace:" << newFace << endl
00863 << " coords:" << compactPoints
00864 << " ownPt:" << ownPt
00865 << " neiPt:" << neiPt
00866 << " s:" << s
00867 << abort(FatalError);
00868 }
00869 }
00870
00871
00872 void Foam::hexRef8::checkBoundaryOrientation
00873 (
00874 polyTopoChange& meshMod,
00875 const label cellI,
00876 const label faceI,
00877 const point& ownPt,
00878 const point& boundaryPt,
00879 const face& newFace
00880 )
00881 {
00882 face compactFace(identity(newFace.size()));
00883 pointField compactPoints(meshMod.points(), newFace);
00884
00885 vector n(compactFace.normal(compactPoints));
00886
00887 vector dir(boundaryPt - ownPt);
00888
00889 if ((dir & n) < 0)
00890 {
00891 FatalErrorIn("checkBoundaryOrientation(..)")
00892 << "cell:" << cellI << " old face:" << faceI
00893 << " newFace:" << newFace
00894 << " coords:" << compactPoints
00895 << " ownPt:" << ownPt
00896 << " boundaryPt:" << boundaryPt
00897 << abort(FatalError);
00898 }
00899
00900 vector fcToOwn(compactFace.centre(compactPoints) - ownPt);
00901
00902 scalar s = (fcToOwn&dir) / magSqr(dir);
00903
00904 if (s < 0.7 || s > 1.3)
00905 {
00906 WarningIn("checkBoundaryOrientation(..)")
00907 << "cell:" << cellI << " old face:" << faceI
00908 << " newFace:" << newFace
00909 << " coords:" << compactPoints
00910 << " ownPt:" << ownPt
00911 << " boundaryPt:" << boundaryPt
00912 << " s:" << s
00913 << endl;
00914
00915 }
00916 }
00917
00918
00919
00920
00921 void Foam::hexRef8::insertEdgeSplit
00922 (
00923 const labelList& edgeMidPoint,
00924 const label p0,
00925 const label p1,
00926 DynamicList<label>& verts
00927 ) const
00928 {
00929 if (p0 < mesh_.nPoints() && p1 < mesh_.nPoints())
00930 {
00931 label edgeI = meshTools::findEdge(mesh_, p0, p1);
00932
00933 if (edgeI != -1 && edgeMidPoint[edgeI] != -1)
00934 {
00935 verts.append(edgeMidPoint[edgeI]);
00936 }
00937 }
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 Foam::label Foam::hexRef8::storeMidPointInfo
00950 (
00951 const labelListList& cellAnchorPoints,
00952 const labelListList& cellAddedCells,
00953 const labelList& cellMidPoint,
00954 const labelList& edgeMidPoint,
00955 const label cellI,
00956 const label faceI,
00957 const bool faceOrder,
00958 const label edgeMidPointI,
00959 const label anchorPointI,
00960 const label faceMidPointI,
00961
00962 Map<edge>& midPointToAnchors,
00963 Map<edge>& midPointToFaceMids,
00964 polyTopoChange& meshMod
00965 ) const
00966 {
00967
00968
00969 bool changed = false;
00970 bool haveTwoAnchors = false;
00971
00972 Map<edge>::iterator edgeMidFnd = midPointToAnchors.find(edgeMidPointI);
00973
00974 if (edgeMidFnd == midPointToAnchors.end())
00975 {
00976 midPointToAnchors.insert(edgeMidPointI, edge(anchorPointI, -1));
00977 }
00978 else
00979 {
00980 edge& e = edgeMidFnd();
00981
00982 if (anchorPointI != e[0])
00983 {
00984 if (e[1] == -1)
00985 {
00986 e[1] = anchorPointI;
00987 changed = true;
00988 }
00989 }
00990
00991 if (e[0] != -1 && e[1] != -1)
00992 {
00993 haveTwoAnchors = true;
00994 }
00995 }
00996
00997 bool haveTwoFaceMids = false;
00998
00999 Map<edge>::iterator faceMidFnd = midPointToFaceMids.find(edgeMidPointI);
01000
01001 if (faceMidFnd == midPointToFaceMids.end())
01002 {
01003 midPointToFaceMids.insert(edgeMidPointI, edge(faceMidPointI, -1));
01004 }
01005 else
01006 {
01007 edge& e = faceMidFnd();
01008
01009 if (faceMidPointI != e[0])
01010 {
01011 if (e[1] == -1)
01012 {
01013 e[1] = faceMidPointI;
01014 changed = true;
01015 }
01016 }
01017
01018 if (e[0] != -1 && e[1] != -1)
01019 {
01020 haveTwoFaceMids = true;
01021 }
01022 }
01023
01024
01025
01026
01027 if (changed && haveTwoAnchors && haveTwoFaceMids)
01028 {
01029 const edge& anchors = midPointToAnchors[edgeMidPointI];
01030 const edge& faceMids = midPointToFaceMids[edgeMidPointI];
01031
01032 label otherFaceMidPointI = faceMids.otherVertex(faceMidPointI);
01033
01034
01035
01036
01037
01038
01039 DynamicList<label> newFaceVerts(4);
01040 if (faceOrder == (mesh_.faceOwner()[faceI] == cellI))
01041 {
01042 newFaceVerts.append(faceMidPointI);
01043
01044
01045 insertEdgeSplit
01046 (
01047 edgeMidPoint,
01048 faceMidPointI,
01049 edgeMidPointI,
01050 newFaceVerts
01051 );
01052
01053 newFaceVerts.append(edgeMidPointI);
01054
01055 insertEdgeSplit
01056 (
01057 edgeMidPoint,
01058 edgeMidPointI,
01059 otherFaceMidPointI,
01060 newFaceVerts
01061 );
01062
01063 newFaceVerts.append(otherFaceMidPointI);
01064 newFaceVerts.append(cellMidPoint[cellI]);
01065 }
01066 else
01067 {
01068 newFaceVerts.append(otherFaceMidPointI);
01069
01070 insertEdgeSplit
01071 (
01072 edgeMidPoint,
01073 otherFaceMidPointI,
01074 edgeMidPointI,
01075 newFaceVerts
01076 );
01077
01078 newFaceVerts.append(edgeMidPointI);
01079
01080 insertEdgeSplit
01081 (
01082 edgeMidPoint,
01083 edgeMidPointI,
01084 faceMidPointI,
01085 newFaceVerts
01086 );
01087
01088 newFaceVerts.append(faceMidPointI);
01089 newFaceVerts.append(cellMidPoint[cellI]);
01090 }
01091
01092 face newFace;
01093 newFace.transfer(newFaceVerts);
01094
01095 label anchorCell0 = getAnchorCell
01096 (
01097 cellAnchorPoints,
01098 cellAddedCells,
01099 cellI,
01100 faceI,
01101 anchorPointI
01102 );
01103 label anchorCell1 = getAnchorCell
01104 (
01105 cellAnchorPoints,
01106 cellAddedCells,
01107 cellI,
01108 faceI,
01109 anchors.otherVertex(anchorPointI)
01110 );
01111
01112
01113 label own, nei;
01114 point ownPt, neiPt;
01115
01116 if (anchorCell0 < anchorCell1)
01117 {
01118 own = anchorCell0;
01119 nei = anchorCell1;
01120
01121 ownPt = mesh_.points()[anchorPointI];
01122 neiPt = mesh_.points()[anchors.otherVertex(anchorPointI)];
01123
01124 }
01125 else
01126 {
01127 own = anchorCell1;
01128 nei = anchorCell0;
01129 newFace = newFace.reverseFace();
01130
01131 ownPt = mesh_.points()[anchors.otherVertex(anchorPointI)];
01132 neiPt = mesh_.points()[anchorPointI];
01133 }
01134
01135 if (debug)
01136 {
01137 point ownPt, neiPt;
01138
01139 if (anchorCell0 < anchorCell1)
01140 {
01141 ownPt = mesh_.points()[anchorPointI];
01142 neiPt = mesh_.points()[anchors.otherVertex(anchorPointI)];
01143 }
01144 else
01145 {
01146 ownPt = mesh_.points()[anchors.otherVertex(anchorPointI)];
01147 neiPt = mesh_.points()[anchorPointI];
01148 }
01149
01150 checkInternalOrientation
01151 (
01152 meshMod,
01153 cellI,
01154 faceI,
01155 ownPt,
01156 neiPt,
01157 newFace
01158 );
01159 }
01160
01161 return addInternalFace
01162 (
01163 meshMod,
01164 faceI,
01165 anchorPointI,
01166 newFace,
01167 own,
01168 nei
01169 );
01170 }
01171 else
01172 {
01173 return -1;
01174 }
01175 }
01176
01177
01178
01179 void Foam::hexRef8::createInternalFaces
01180 (
01181 const labelListList& cellAnchorPoints,
01182 const labelListList& cellAddedCells,
01183 const labelList& cellMidPoint,
01184 const labelList& faceMidPoint,
01185 const labelList& faceAnchorLevel,
01186 const labelList& edgeMidPoint,
01187 const label cellI,
01188
01189 polyTopoChange& meshMod
01190 ) const
01191 {
01192
01193
01194
01195 const cell& cFaces = mesh_.cells()[cellI];
01196 const label cLevel = cellLevel_[cellI];
01197
01198
01199 Map<edge> midPointToAnchors(24);
01200
01201 Map<edge> midPointToFaceMids(24);
01202
01203
01204 DynamicList<label> storage;
01205
01206
01207
01208 label nFacesAdded = 0;
01209
01210 forAll(cFaces, i)
01211 {
01212 label faceI = cFaces[i];
01213
01214 const face& f = mesh_.faces()[faceI];
01215 const labelList& fEdges = mesh_.faceEdges(faceI, storage);
01216
01217
01218
01219
01220 label faceMidPointI = -1;
01221
01222 label nAnchors = countAnchors(f, cLevel);
01223
01224 if (nAnchors == 1)
01225 {
01226
01227
01228
01229
01230 label anchorFp = -1;
01231
01232 forAll(f, fp)
01233 {
01234 if (pointLevel_[f[fp]] <= cLevel)
01235 {
01236 anchorFp = fp;
01237 break;
01238 }
01239 }
01240
01241
01242 label edgeMid = findLevel
01243 (
01244 faceI,
01245 f,
01246 f.fcIndex(anchorFp),
01247 true,
01248 cLevel+1
01249 );
01250 label faceMid = findLevel
01251 (
01252 faceI,
01253 f,
01254 f.fcIndex(edgeMid),
01255 true,
01256 cLevel+1
01257 );
01258
01259 faceMidPointI = f[faceMid];
01260 }
01261 else if (nAnchors == 4)
01262 {
01263
01264
01265
01266 faceMidPointI = faceMidPoint[faceI];
01267 }
01268 else
01269 {
01270 dumpCell(mesh_.faceOwner()[faceI]);
01271 if (mesh_.isInternalFace(faceI))
01272 {
01273 dumpCell(mesh_.faceNeighbour()[faceI]);
01274 }
01275
01276 FatalErrorIn("createInternalFaces(..)")
01277 << "nAnchors:" << nAnchors
01278 << " faceI:" << faceI
01279 << abort(FatalError);
01280 }
01281
01282
01283
01284
01285
01286
01287
01288 forAll(f, fp0)
01289 {
01290 label point0 = f[fp0];
01291
01292 if (pointLevel_[point0] <= cLevel)
01293 {
01294
01295
01296
01297
01298
01299
01300
01301 label edgeMidPointI = -1;
01302
01303 label fp1 = f.fcIndex(fp0);
01304
01305 if (pointLevel_[f[fp1]] <= cLevel)
01306 {
01307
01308 label edgeI = fEdges[fp0];
01309
01310 edgeMidPointI = edgeMidPoint[edgeI];
01311
01312 if (edgeMidPointI == -1)
01313 {
01314 dumpCell(cellI);
01315
01316 const labelList& cPoints = mesh_.cellPoints(cellI);
01317
01318 FatalErrorIn("createInternalFaces(..)")
01319 << "cell:" << cellI << " cLevel:" << cLevel
01320 << " cell points:" << cPoints
01321 << " pointLevel:"
01322 << UIndirectList<label>(pointLevel_, cPoints)()
01323 << " face:" << faceI
01324 << " f:" << f
01325 << " pointLevel:"
01326 << UIndirectList<label>(pointLevel_, f)()
01327 << " faceAnchorLevel:" << faceAnchorLevel[faceI]
01328 << " faceMidPoint:" << faceMidPoint[faceI]
01329 << " faceMidPointI:" << faceMidPointI
01330 << " fp:" << fp0
01331 << abort(FatalError);
01332 }
01333 }
01334 else
01335 {
01336
01337 label edgeMid = findLevel(faceI, f, fp1, true, cLevel+1);
01338
01339 edgeMidPointI = f[edgeMid];
01340 }
01341
01342 label newFaceI = storeMidPointInfo
01343 (
01344 cellAnchorPoints,
01345 cellAddedCells,
01346 cellMidPoint,
01347 edgeMidPoint,
01348
01349 cellI,
01350 faceI,
01351 true,
01352 edgeMidPointI,
01353 point0,
01354 faceMidPointI,
01355
01356 midPointToAnchors,
01357 midPointToFaceMids,
01358 meshMod
01359 );
01360
01361 if (newFaceI != -1)
01362 {
01363 nFacesAdded++;
01364
01365 if (nFacesAdded == 12)
01366 {
01367 break;
01368 }
01369 }
01370
01371
01372
01373
01374
01375
01376 label fpMin1 = f.rcIndex(fp0);
01377
01378 if (pointLevel_[f[fpMin1]] <= cLevel)
01379 {
01380
01381 label edgeI = fEdges[fpMin1];
01382
01383 edgeMidPointI = edgeMidPoint[edgeI];
01384
01385 if (edgeMidPointI == -1)
01386 {
01387 dumpCell(cellI);
01388
01389 const labelList& cPoints = mesh_.cellPoints(cellI);
01390
01391 FatalErrorIn("createInternalFaces(..)")
01392 << "cell:" << cellI << " cLevel:" << cLevel
01393 << " cell points:" << cPoints
01394 << " pointLevel:"
01395 << UIndirectList<label>(pointLevel_, cPoints)()
01396 << " face:" << faceI
01397 << " f:" << f
01398 << " pointLevel:"
01399 << UIndirectList<label>(pointLevel_, f)()
01400 << " faceAnchorLevel:" << faceAnchorLevel[faceI]
01401 << " faceMidPoint:" << faceMidPoint[faceI]
01402 << " faceMidPointI:" << faceMidPointI
01403 << " fp:" << fp0
01404 << abort(FatalError);
01405 }
01406 }
01407 else
01408 {
01409
01410 label edgeMid = findLevel
01411 (
01412 faceI,
01413 f,
01414 fpMin1,
01415 false,
01416 cLevel+1
01417 );
01418
01419 edgeMidPointI = f[edgeMid];
01420 }
01421
01422 newFaceI = storeMidPointInfo
01423 (
01424 cellAnchorPoints,
01425 cellAddedCells,
01426 cellMidPoint,
01427 edgeMidPoint,
01428
01429 cellI,
01430 faceI,
01431 false,
01432 edgeMidPointI,
01433 point0,
01434 faceMidPointI,
01435
01436 midPointToAnchors,
01437 midPointToFaceMids,
01438 meshMod
01439 );
01440
01441 if (newFaceI != -1)
01442 {
01443 nFacesAdded++;
01444
01445 if (nFacesAdded == 12)
01446 {
01447 break;
01448 }
01449 }
01450 }
01451 }
01452
01453 if (nFacesAdded == 12)
01454 {
01455 break;
01456 }
01457 }
01458 }
01459
01460
01461 void Foam::hexRef8::walkFaceToMid
01462 (
01463 const labelList& edgeMidPoint,
01464 const label cLevel,
01465 const label faceI,
01466 const label startFp,
01467 DynamicList<label>& faceVerts
01468 ) const
01469 {
01470 const face& f = mesh_.faces()[faceI];
01471 const labelList& fEdges = mesh_.faceEdges(faceI);
01472
01473 label fp = startFp;
01474
01475
01476
01477
01478 while (true)
01479 {
01480 if (edgeMidPoint[fEdges[fp]] >= 0)
01481 {
01482 faceVerts.append(edgeMidPoint[fEdges[fp]]);
01483 }
01484
01485 fp = f.fcIndex(fp);
01486
01487 if (pointLevel_[f[fp]] <= cLevel)
01488 {
01489
01490
01491 return;
01492 }
01493 else if (pointLevel_[f[fp]] == cLevel+1)
01494 {
01495
01496 faceVerts.append(f[fp]);
01497
01498 return;
01499 }
01500 else if (pointLevel_[f[fp]] == cLevel+2)
01501 {
01502
01503 faceVerts.append(f[fp]);
01504 }
01505 }
01506 }
01507
01508
01509
01510 void Foam::hexRef8::walkFaceFromMid
01511 (
01512 const labelList& edgeMidPoint,
01513 const label cLevel,
01514 const label faceI,
01515 const label startFp,
01516 DynamicList<label>& faceVerts
01517 ) const
01518 {
01519 const face& f = mesh_.faces()[faceI];
01520 const labelList& fEdges = mesh_.faceEdges(faceI);
01521
01522 label fp = f.rcIndex(startFp);
01523
01524 while (true)
01525 {
01526 if (pointLevel_[f[fp]] <= cLevel)
01527 {
01528
01529 break;
01530 }
01531 else if (pointLevel_[f[fp]] == cLevel+1)
01532 {
01533
01534 faceVerts.append(f[fp]);
01535 break;
01536 }
01537 else if (pointLevel_[f[fp]] == cLevel+2)
01538 {
01539
01540 }
01541 fp = f.rcIndex(fp);
01542 }
01543
01544
01545 while (true)
01546 {
01547 if (edgeMidPoint[fEdges[fp]] >= 0)
01548 {
01549 faceVerts.append(edgeMidPoint[fEdges[fp]]);
01550 }
01551
01552 fp = f.fcIndex(fp);
01553
01554 if (fp == startFp)
01555 {
01556 break;
01557 }
01558 faceVerts.append(f[fp]);
01559 }
01560 }
01561
01562
01563
01564
01565 Foam::label Foam::hexRef8::faceConsistentRefinement
01566 (
01567 const bool maxSet,
01568 PackedBoolList& refineCell
01569 ) const
01570 {
01571 label nChanged = 0;
01572
01573
01574 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
01575 {
01576 label own = mesh_.faceOwner()[faceI];
01577 label ownLevel = cellLevel_[own] + refineCell.get(own);
01578
01579 label nei = mesh_.faceNeighbour()[faceI];
01580 label neiLevel = cellLevel_[nei] + refineCell.get(nei);
01581
01582 if (ownLevel > (neiLevel+1))
01583 {
01584 if (maxSet)
01585 {
01586 refineCell.set(nei, 1);
01587 }
01588 else
01589 {
01590 refineCell.set(own, 0);
01591 }
01592 nChanged++;
01593 }
01594 else if (neiLevel > (ownLevel+1))
01595 {
01596 if (maxSet)
01597 {
01598 refineCell.set(own, 1);
01599 }
01600 else
01601 {
01602 refineCell.set(nei, 0);
01603 }
01604 nChanged++;
01605 }
01606 }
01607
01608
01609
01610
01611 labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
01612
01613 forAll(neiLevel, i)
01614 {
01615 label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
01616
01617 neiLevel[i] = cellLevel_[own] + refineCell.get(own);
01618 }
01619
01620
01621 syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
01622
01623
01624 forAll(neiLevel, i)
01625 {
01626 label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
01627 label ownLevel = cellLevel_[own] + refineCell.get(own);
01628
01629 if (ownLevel > (neiLevel[i]+1))
01630 {
01631 if (!maxSet)
01632 {
01633 refineCell.set(own, 0);
01634 nChanged++;
01635 }
01636 }
01637 else if (neiLevel[i] > (ownLevel+1))
01638 {
01639 if (maxSet)
01640 {
01641 refineCell.set(own, 1);
01642 nChanged++;
01643 }
01644 }
01645 }
01646
01647 return nChanged;
01648 }
01649
01650
01651
01652 void Foam::hexRef8::checkWantedRefinementLevels
01653 (
01654 const labelList& cellsToRefine
01655 ) const
01656 {
01657 PackedBoolList refineCell(mesh_.nCells());
01658 forAll(cellsToRefine, i)
01659 {
01660 refineCell.set(cellsToRefine[i], 1);
01661 }
01662
01663 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
01664 {
01665 label own = mesh_.faceOwner()[faceI];
01666 label ownLevel = cellLevel_[own] + refineCell.get(own);
01667
01668 label nei = mesh_.faceNeighbour()[faceI];
01669 label neiLevel = cellLevel_[nei] + refineCell.get(nei);
01670
01671 if (mag(ownLevel-neiLevel) > 1)
01672 {
01673 dumpCell(own);
01674 dumpCell(nei);
01675 FatalErrorIn
01676 (
01677 "hexRef8::checkWantedRefinementLevels(const labelList&)"
01678 ) << "cell:" << own
01679 << " current level:" << cellLevel_[own]
01680 << " level after refinement:" << ownLevel
01681 << nl
01682 << "neighbour cell:" << nei
01683 << " current level:" << cellLevel_[nei]
01684 << " level after refinement:" << neiLevel
01685 << nl
01686 << "which does not satisfy 2:1 constraints anymore."
01687 << abort(FatalError);
01688 }
01689 }
01690
01691
01692
01693 labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
01694
01695 forAll(neiLevel, i)
01696 {
01697 label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
01698
01699 neiLevel[i] = cellLevel_[own] + refineCell.get(own);
01700 }
01701
01702
01703 syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
01704
01705
01706 forAll(neiLevel, i)
01707 {
01708 label faceI = i + mesh_.nInternalFaces();
01709
01710 label own = mesh_.faceOwner()[faceI];
01711 label ownLevel = cellLevel_[own] + refineCell.get(own);
01712
01713 if (mag(ownLevel - neiLevel[i]) > 1)
01714 {
01715 label patchI = mesh_.boundaryMesh().whichPatch(faceI);
01716
01717 dumpCell(own);
01718 FatalErrorIn
01719 (
01720 "hexRef8::checkWantedRefinementLevels(const labelList&)"
01721 ) << "Celllevel does not satisfy 2:1 constraint."
01722 << " On coupled face "
01723 << faceI
01724 << " on patch " << patchI << " "
01725 << mesh_.boundaryMesh()[patchI].name()
01726 << " owner cell " << own
01727 << " current level:" << cellLevel_[own]
01728 << " level after refinement:" << ownLevel
01729 << nl
01730 << " (coupled) neighbour cell will get refinement "
01731 << neiLevel[i]
01732 << abort(FatalError);
01733 }
01734 }
01735 }
01736
01737
01738
01739 void Foam::hexRef8::setInstance(const fileName& inst)
01740 {
01741 if (debug)
01742 {
01743 Pout<< "hexRef8::setInstance(const fileName& inst) : "
01744 << "Resetting file instance to " << inst << endl;
01745 }
01746
01747 cellLevel_.instance() = inst;
01748 pointLevel_.instance() = inst;
01749 history_.instance() = inst;
01750 }
01751
01752
01753
01754
01755
01756 Foam::hexRef8::hexRef8(const polyMesh& mesh)
01757 :
01758 mesh_(mesh),
01759 cellLevel_
01760 (
01761 IOobject
01762 (
01763 "cellLevel",
01764 mesh_.facesInstance(),
01765 polyMesh::meshSubDir,
01766 mesh_,
01767 IOobject::READ_IF_PRESENT,
01768 IOobject::AUTO_WRITE
01769 ),
01770 labelList(mesh_.nCells(), 0)
01771 ),
01772 pointLevel_
01773 (
01774 IOobject
01775 (
01776 "pointLevel",
01777 mesh_.facesInstance(),
01778 polyMesh::meshSubDir,
01779 mesh_,
01780 IOobject::READ_IF_PRESENT,
01781 IOobject::AUTO_WRITE
01782 ),
01783 labelList(mesh_.nPoints(), 0)
01784 ),
01785 level0Edge_(getLevel0EdgeLength()),
01786 history_
01787 (
01788 IOobject
01789 (
01790 "refinementHistory",
01791 mesh_.facesInstance(),
01792 polyMesh::meshSubDir,
01793 mesh_,
01794 IOobject::READ_IF_PRESENT,
01795 IOobject::AUTO_WRITE
01796 ),
01797 mesh_.nCells()
01798 ),
01799 faceRemover_(mesh_, GREAT),
01800 savedPointLevel_(0),
01801 savedCellLevel_(0)
01802 {
01803 if (history_.active() && history_.visibleCells().size() != mesh_.nCells())
01804 {
01805 FatalErrorIn
01806 (
01807 "hexRef8::hexRef8(const polyMesh&)"
01808 ) << "History enabled but number of visible cells in it "
01809 << history_.visibleCells().size()
01810 << " is not equal to the number of cells in the mesh "
01811 << mesh_.nCells()
01812 << abort(FatalError);
01813 }
01814
01815 if
01816 (
01817 cellLevel_.size() != mesh_.nCells()
01818 || pointLevel_.size() != mesh_.nPoints()
01819 )
01820 {
01821 FatalErrorIn
01822 (
01823 "hexRef8::hexRef8(const polyMesh&)"
01824 ) << "Restarted from inconsistent cellLevel or pointLevel files."
01825 << endl
01826 << "Number of cells in mesh:" << mesh_.nCells()
01827 << " does not equal size of cellLevel:" << cellLevel_.size() << endl
01828 << "Number of points in mesh:" << mesh_.nPoints()
01829 << " does not equal size of pointLevel:" << pointLevel_.size()
01830 << abort(FatalError);
01831 }
01832
01833
01834
01835 checkRefinementLevels(-1, labelList(0));
01836
01837
01838
01839
01840
01841 {
01842 checkMesh();
01843 }
01844 }
01845
01846
01847
01848 Foam::hexRef8::hexRef8
01849 (
01850 const polyMesh& mesh,
01851 const labelList& cellLevel,
01852 const labelList& pointLevel,
01853 const refinementHistory& history
01854 )
01855 :
01856 mesh_(mesh),
01857 cellLevel_
01858 (
01859 IOobject
01860 (
01861 "cellLevel",
01862 mesh_.facesInstance(),
01863 polyMesh::meshSubDir,
01864 mesh_,
01865 IOobject::NO_READ,
01866 IOobject::AUTO_WRITE
01867 ),
01868 cellLevel
01869 ),
01870 pointLevel_
01871 (
01872 IOobject
01873 (
01874 "pointLevel",
01875 mesh_.facesInstance(),
01876 polyMesh::meshSubDir,
01877 mesh_,
01878 IOobject::NO_READ,
01879 IOobject::AUTO_WRITE
01880 ),
01881 pointLevel
01882 ),
01883 level0Edge_(getLevel0EdgeLength()),
01884 history_
01885 (
01886 IOobject
01887 (
01888 "refinementHistory",
01889 mesh_.facesInstance(),
01890 polyMesh::meshSubDir,
01891 mesh_,
01892 IOobject::NO_READ,
01893 IOobject::AUTO_WRITE
01894 ),
01895 history
01896 ),
01897 faceRemover_(mesh_, GREAT),
01898 savedPointLevel_(0),
01899 savedCellLevel_(0)
01900 {
01901 if (history_.active() && history_.visibleCells().size() != mesh_.nCells())
01902 {
01903 FatalErrorIn
01904 (
01905 "hexRef8::hexRef8(const polyMesh&, const labelList&"
01906 ", const labelList&, const refinementHistory&)"
01907 ) << "History enabled but number of visible cells in it "
01908 << history_.visibleCells().size()
01909 << " is not equal to the number of cells in the mesh "
01910 << mesh_.nCells() << abort(FatalError);
01911 }
01912
01913 if
01914 (
01915 cellLevel_.size() != mesh_.nCells()
01916 || pointLevel_.size() != mesh_.nPoints()
01917 )
01918 {
01919 FatalErrorIn
01920 (
01921 "hexRef8::hexRef8(const polyMesh&, const labelList&"
01922 ", const labelList&, const refinementHistory&)"
01923 ) << "Incorrect cellLevel or pointLevel size." << endl
01924 << "Number of cells in mesh:" << mesh_.nCells()
01925 << " does not equal size of cellLevel:" << cellLevel_.size() << endl
01926 << "Number of points in mesh:" << mesh_.nPoints()
01927 << " does not equal size of pointLevel:" << pointLevel_.size()
01928 << abort(FatalError);
01929 }
01930
01931
01932 checkRefinementLevels(-1, labelList(0));
01933
01934
01935
01936
01937
01938 {
01939 checkMesh();
01940 }
01941 }
01942
01943
01944
01945 Foam::hexRef8::hexRef8
01946 (
01947 const polyMesh& mesh,
01948 const labelList& cellLevel,
01949 const labelList& pointLevel
01950 )
01951 :
01952 mesh_(mesh),
01953 cellLevel_
01954 (
01955 IOobject
01956 (
01957 "cellLevel",
01958 mesh_.facesInstance(),
01959 polyMesh::meshSubDir,
01960 mesh_,
01961 IOobject::NO_READ,
01962 IOobject::AUTO_WRITE
01963 ),
01964 cellLevel
01965 ),
01966 pointLevel_
01967 (
01968 IOobject
01969 (
01970 "pointLevel",
01971 mesh_.facesInstance(),
01972 polyMesh::meshSubDir,
01973 mesh_,
01974 IOobject::NO_READ,
01975 IOobject::AUTO_WRITE
01976 ),
01977 pointLevel
01978 ),
01979 level0Edge_(getLevel0EdgeLength()),
01980 history_
01981 (
01982 IOobject
01983 (
01984 "refinementHistory",
01985 mesh_.facesInstance(),
01986 polyMesh::meshSubDir,
01987 mesh_,
01988 IOobject::NO_READ,
01989 IOobject::AUTO_WRITE
01990 ),
01991 List<refinementHistory::splitCell8>(0),
01992 labelList(0)
01993 ),
01994 faceRemover_(mesh_, GREAT),
01995 savedPointLevel_(0),
01996 savedCellLevel_(0)
01997 {
01998 if
01999 (
02000 cellLevel_.size() != mesh_.nCells()
02001 || pointLevel_.size() != mesh_.nPoints()
02002 )
02003 {
02004 FatalErrorIn
02005 (
02006 "hexRef8::hexRef8(const polyMesh&, const labelList&"
02007 ", const labelList&)"
02008 ) << "Incorrect cellLevel or pointLevel size." << endl
02009 << "Number of cells in mesh:" << mesh_.nCells()
02010 << " does not equal size of cellLevel:" << cellLevel_.size() << endl
02011 << "Number of points in mesh:" << mesh_.nPoints()
02012 << " does not equal size of pointLevel:" << pointLevel_.size()
02013 << abort(FatalError);
02014 }
02015
02016
02017 checkRefinementLevels(-1, labelList(0));
02018
02019
02020
02021
02022 {
02023 checkMesh();
02024 }
02025 }
02026
02027
02028
02029
02030 Foam::labelList Foam::hexRef8::consistentRefinement
02031 (
02032 const labelList& cellsToRefine,
02033 const bool maxSet
02034 ) const
02035 {
02036
02037
02038
02039
02040
02041
02042 PackedBoolList refineCell(mesh_.nCells());
02043 forAll(cellsToRefine, i)
02044 {
02045 refineCell.set(cellsToRefine[i], 1);
02046 }
02047
02048 while (true)
02049 {
02050 label nChanged = faceConsistentRefinement(maxSet, refineCell);
02051
02052 reduce(nChanged, sumOp<label>());
02053
02054 if (debug)
02055 {
02056 Pout<< "hexRef8::consistentRefinement : Changed " << nChanged
02057 << " refinement levels due to 2:1 conflicts."
02058 << endl;
02059 }
02060
02061 if (nChanged == 0)
02062 {
02063 break;
02064 }
02065 }
02066
02067
02068
02069 label nRefined = 0;
02070
02071 forAll(refineCell, cellI)
02072 {
02073 if (refineCell.get(cellI) == 1)
02074 {
02075 nRefined++;
02076 }
02077 }
02078
02079 labelList newCellsToRefine(nRefined);
02080 nRefined = 0;
02081
02082 forAll(refineCell, cellI)
02083 {
02084 if (refineCell.get(cellI) == 1)
02085 {
02086 newCellsToRefine[nRefined++] = cellI;
02087 }
02088 }
02089
02090 if (debug)
02091 {
02092 checkWantedRefinementLevels(newCellsToRefine);
02093 }
02094
02095 return newCellsToRefine;
02096 }
02097
02098
02099
02100
02101
02102
02103
02104
02105 Foam::labelList Foam::hexRef8::consistentSlowRefinement
02106 (
02107 const label maxFaceDiff,
02108 const labelList& cellsToRefine,
02109 const labelList& facesToCheck,
02110 const label maxPointDiff,
02111 const labelList& pointsToCheck
02112 ) const
02113 {
02114 const labelList& faceOwner = mesh_.faceOwner();
02115 const labelList& faceNeighbour = mesh_.faceNeighbour();
02116
02117
02118 if (maxFaceDiff <= 0)
02119 {
02120 FatalErrorIn
02121 (
02122 "hexRef8::consistentSlowRefinement"
02123 "(const label, const labelList&, const labelList&"
02124 ", const label, const labelList&)"
02125 ) << "Illegal maxFaceDiff " << maxFaceDiff << nl
02126 << "Value should be >= 1" << exit(FatalError);
02127 }
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139 List<refinementData> allCellInfo(mesh_.nCells());
02140
02141
02142 List<refinementData> allFaceInfo(mesh_.nFaces());
02143
02144 forAll(allCellInfo, cellI)
02145 {
02146
02147
02148 allCellInfo[cellI] = refinementData
02149 (
02150 maxFaceDiff*(cellLevel_[cellI]+1),
02151 maxFaceDiff*cellLevel_[cellI]
02152 );
02153 }
02154
02155
02156 forAll(cellsToRefine, i)
02157 {
02158 label cellI = cellsToRefine[i];
02159
02160 allCellInfo[cellI].count() = allCellInfo[cellI].refinementCount();
02161 }
02162
02163
02164
02165 DynamicList<label> seedFaces(mesh_.nFaces()/100);
02166
02167 DynamicList<refinementData> seedFacesInfo(mesh_.nFaces()/100);
02168
02169
02170
02171
02172
02173 forAll(facesToCheck, i)
02174 {
02175 label faceI = facesToCheck[i];
02176
02177 if (allFaceInfo[faceI].valid())
02178 {
02179
02180 FatalErrorIn
02181 (
02182 "hexRef8::consistentSlowRefinement"
02183 "(const label, const labelList&, const labelList&"
02184 ", const label, const labelList&)"
02185 ) << "Argument facesToCheck seems to have duplicate entries!"
02186 << endl
02187 << "face:" << faceI << " occurs at positions "
02188 << findIndices(facesToCheck, faceI)
02189 << abort(FatalError);
02190 }
02191
02192
02193 const refinementData& ownData = allCellInfo[faceOwner[faceI]];
02194
02195 if (mesh_.isInternalFace(faceI))
02196 {
02197
02198
02199
02200 const refinementData& neiData = allCellInfo[faceNeighbour[faceI]];
02201
02202 label faceCount;
02203 label faceRefineCount;
02204 if (neiData.count() > ownData.count())
02205 {
02206 faceCount = neiData.count() + maxFaceDiff;
02207 faceRefineCount = faceCount + maxFaceDiff;
02208 }
02209 else
02210 {
02211 faceCount = ownData.count() + maxFaceDiff;
02212 faceRefineCount = faceCount + maxFaceDiff;
02213 }
02214
02215 seedFaces.append(faceI);
02216 seedFacesInfo.append
02217 (
02218 refinementData
02219 (
02220 faceRefineCount,
02221 faceCount
02222 )
02223 );
02224 allFaceInfo[faceI] = seedFacesInfo[seedFacesInfo.size()-1];
02225 }
02226 else
02227 {
02228 label faceCount = ownData.count() + maxFaceDiff;
02229 label faceRefineCount = faceCount + maxFaceDiff;
02230
02231 seedFaces.append(faceI);
02232 seedFacesInfo.append
02233 (
02234 refinementData
02235 (
02236 faceRefineCount,
02237 faceCount
02238 )
02239 );
02240 allFaceInfo[faceI] = seedFacesInfo[seedFacesInfo.size()-1];
02241 }
02242 }
02243
02244
02245
02246
02247
02248 forAll(faceNeighbour, faceI)
02249 {
02250
02251 if (!allFaceInfo[faceI].valid())
02252 {
02253 label own = faceOwner[faceI];
02254 label nei = faceNeighbour[faceI];
02255
02256
02257
02258 if (allCellInfo[own].count() > allCellInfo[nei].count())
02259 {
02260 allFaceInfo[faceI].updateFace
02261 (
02262 mesh_,
02263 faceI,
02264 own,
02265 allCellInfo[own],
02266 FaceCellWave<refinementData>::propagationTol()
02267 );
02268 seedFaces.append(faceI);
02269 seedFacesInfo.append(allFaceInfo[faceI]);
02270 }
02271 else if (allCellInfo[own].count() < allCellInfo[nei].count())
02272 {
02273 allFaceInfo[faceI].updateFace
02274 (
02275 mesh_,
02276 faceI,
02277 nei,
02278 allCellInfo[nei],
02279 FaceCellWave<refinementData>::propagationTol()
02280 );
02281 seedFaces.append(faceI);
02282 seedFacesInfo.append(allFaceInfo[faceI]);
02283 }
02284 }
02285 }
02286
02287
02288
02289
02290 for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
02291 {
02292
02293 if (!allFaceInfo[faceI].valid())
02294 {
02295 label own = faceOwner[faceI];
02296
02297
02298 refinementData faceData;
02299 faceData.updateFace
02300 (
02301 mesh_,
02302 faceI,
02303 own,
02304 allCellInfo[own],
02305 FaceCellWave<refinementData>::propagationTol()
02306 );
02307 seedFaces.append(faceI);
02308 seedFacesInfo.append(faceData);
02309 }
02310 }
02311
02312
02313
02314 FaceCellWave<refinementData> levelCalc
02315 (
02316 mesh_,
02317 allFaceInfo,
02318 allCellInfo
02319 );
02320
02321 while(true)
02322 {
02323 if (debug)
02324 {
02325 Pout<< "hexRef8::consistentSlowRefinement : Seeded "
02326 << seedFaces.size() << " faces between cells with different"
02327 << " refinement level." << endl;
02328 }
02329
02330
02331 levelCalc.setFaceInfo(seedFaces.shrink(), seedFacesInfo.shrink());
02332 seedFaces.clear();
02333 seedFacesInfo.clear();
02334
02335
02336 levelCalc.iterate(mesh_.globalData().nTotalFaces());
02337
02338
02339
02340
02341
02342
02343
02344 if (maxPointDiff == -1)
02345 {
02346
02347 break;
02348 }
02349
02350
02351
02352 labelList maxPointCount(mesh_.nPoints(), 0);
02353
02354 forAll(maxPointCount, pointI)
02355 {
02356 label& pLevel = maxPointCount[pointI];
02357
02358 const labelList& pCells = mesh_.pointCells(pointI);
02359
02360 forAll(pCells, i)
02361 {
02362 pLevel = max(pLevel, allCellInfo[pCells[i]].count());
02363 }
02364 }
02365
02366
02367 syncTools::syncPointList
02368 (
02369 mesh_,
02370 maxPointCount,
02371 maxEqOp<label>(),
02372 labelMin,
02373 false
02374 );
02375
02376
02377
02378
02379
02380 Map<refinementData> changedFacesInfo(pointsToCheck.size());
02381
02382 forAll(pointsToCheck, i)
02383 {
02384 label pointI = pointsToCheck[i];
02385
02386
02387
02388
02389 const labelList& pCells = mesh_.pointCells(pointI);
02390
02391 forAll(pCells, pCellI)
02392 {
02393 label cellI = pCells[pCellI];
02394
02395 refinementData& cellInfo = allCellInfo[cellI];
02396
02397 if
02398 (
02399 !cellInfo.isRefined()
02400 && (
02401 maxPointCount[pointI]
02402 > cellInfo.count() + maxFaceDiff*maxPointDiff
02403 )
02404 )
02405 {
02406
02407 cellInfo.count() = cellInfo.refinementCount();
02408
02409
02410 const cell& cFaces = mesh_.cells()[cellI];
02411
02412 forAll(cFaces, cFaceI)
02413 {
02414 label faceI = cFaces[cFaceI];
02415
02416 refinementData faceData;
02417 faceData.updateFace
02418 (
02419 mesh_,
02420 faceI,
02421 cellI,
02422 cellInfo,
02423 FaceCellWave<refinementData>::propagationTol()
02424 );
02425
02426 if (faceData.count() > allFaceInfo[faceI].count())
02427 {
02428 changedFacesInfo.insert(faceI, faceData);
02429 }
02430 }
02431 }
02432 }
02433 }
02434
02435 label nChanged = changedFacesInfo.size();
02436 reduce(nChanged, sumOp<label>());
02437
02438 if (nChanged == 0)
02439 {
02440 break;
02441 }
02442
02443
02444
02445 seedFaces.setCapacity(changedFacesInfo.size());
02446 seedFacesInfo.setCapacity(changedFacesInfo.size());
02447
02448 forAllConstIter(Map<refinementData>, changedFacesInfo, iter)
02449 {
02450 seedFaces.append(iter.key());
02451 seedFacesInfo.append(iter());
02452 }
02453 }
02454
02455
02456 if (debug)
02457 {
02458 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
02459 {
02460 label own = mesh_.faceOwner()[faceI];
02461 label ownLevel =
02462 cellLevel_[own]
02463 + (allCellInfo[own].isRefined() ? 1 : 0);
02464
02465 label nei = mesh_.faceNeighbour()[faceI];
02466 label neiLevel =
02467 cellLevel_[nei]
02468 + (allCellInfo[nei].isRefined() ? 1 : 0);
02469
02470 if (mag(ownLevel-neiLevel) > 1)
02471 {
02472 dumpCell(own);
02473 dumpCell(nei);
02474 FatalErrorIn
02475 (
02476 "hexRef8::consistentSlowRefinement"
02477 "(const label, const labelList&, const labelList&"
02478 ", const label, const labelList&)"
02479 ) << "cell:" << own
02480 << " current level:" << cellLevel_[own]
02481 << " current refData:" << allCellInfo[own]
02482 << " level after refinement:" << ownLevel
02483 << nl
02484 << "neighbour cell:" << nei
02485 << " current level:" << cellLevel_[nei]
02486 << " current refData:" << allCellInfo[nei]
02487 << " level after refinement:" << neiLevel
02488 << nl
02489 << "which does not satisfy 2:1 constraints anymore." << nl
02490 << "face:" << faceI << " faceRefData:" << allFaceInfo[faceI]
02491 << abort(FatalError);
02492 }
02493 }
02494
02495
02496
02497
02498
02499 labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
02500 labelList neiCount(mesh_.nFaces()-mesh_.nInternalFaces());
02501 labelList neiRefCount(mesh_.nFaces()-mesh_.nInternalFaces());
02502
02503 forAll(neiLevel, i)
02504 {
02505 label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
02506 neiLevel[i] = cellLevel_[own];
02507 neiCount[i] = allCellInfo[own].count();
02508 neiRefCount[i] = allCellInfo[own].refinementCount();
02509 }
02510
02511
02512 syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
02513 syncTools::swapBoundaryFaceList(mesh_, neiCount, false);
02514 syncTools::swapBoundaryFaceList(mesh_, neiRefCount, false);
02515
02516
02517 forAll(neiLevel, i)
02518 {
02519 label faceI = i+mesh_.nInternalFaces();
02520
02521 label own = mesh_.faceOwner()[faceI];
02522 label ownLevel =
02523 cellLevel_[own]
02524 + (allCellInfo[own].isRefined() ? 1 : 0);
02525
02526 label nbrLevel =
02527 neiLevel[i]
02528 + ((neiCount[i] >= neiRefCount[i]) ? 1 : 0);
02529
02530 if (mag(ownLevel - nbrLevel) > 1)
02531 {
02532 dumpCell(own);
02533 label patchI = mesh_.boundaryMesh().whichPatch(faceI);
02534
02535 FatalErrorIn
02536 (
02537 "hexRef8::consistentSlowRefinement"
02538 "(const label, const labelList&, const labelList&"
02539 ", const label, const labelList&)"
02540 ) << "Celllevel does not satisfy 2:1 constraint."
02541 << " On coupled face "
02542 << faceI
02543 << " refData:" << allFaceInfo[faceI]
02544 << " on patch " << patchI << " "
02545 << mesh_.boundaryMesh()[patchI].name() << nl
02546 << "owner cell " << own
02547 << " current level:" << cellLevel_[own]
02548 << " current count:" << allCellInfo[own].count()
02549 << " current refCount:"
02550 << allCellInfo[own].refinementCount()
02551 << " level after refinement:" << ownLevel
02552 << nl
02553 << "(coupled) neighbour cell"
02554 << " has current level:" << neiLevel[i]
02555 << " current count:" << neiCount[i]
02556 << " current refCount:" << neiRefCount[i]
02557 << " level after refinement:" << nbrLevel
02558 << abort(FatalError);
02559 }
02560 }
02561 }
02562
02563
02564
02565 label nRefined = 0;
02566
02567 forAll(allCellInfo, cellI)
02568 {
02569 if (allCellInfo[cellI].isRefined())
02570 {
02571 nRefined++;
02572 }
02573 }
02574
02575
02576 labelList newCellsToRefine(nRefined);
02577 nRefined = 0;
02578
02579 forAll(allCellInfo, cellI)
02580 {
02581 if (allCellInfo[cellI].isRefined())
02582 {
02583 newCellsToRefine[nRefined++] = cellI;
02584 }
02585 }
02586
02587 if (debug)
02588 {
02589 Pout<< "hexRef8::consistentSlowRefinement : From "
02590 << cellsToRefine.size() << " to " << newCellsToRefine.size()
02591 << " cells to refine." << endl;
02592 }
02593
02594 return newCellsToRefine;
02595 }
02596
02597
02598 Foam::labelList Foam::hexRef8::consistentSlowRefinement2
02599 (
02600 const label maxFaceDiff,
02601 const labelList& cellsToRefine,
02602 const labelList& facesToCheck
02603 ) const
02604 {
02605 const labelList& faceOwner = mesh_.faceOwner();
02606 const labelList& faceNeighbour = mesh_.faceNeighbour();
02607
02608 if (maxFaceDiff <= 0)
02609 {
02610 FatalErrorIn
02611 (
02612 "hexRef8::consistentSlowRefinement2"
02613 "(const label, const labelList&, const labelList&)"
02614 ) << "Illegal maxFaceDiff " << maxFaceDiff << nl
02615 << "Value should be >= 1" << exit(FatalError);
02616 }
02617
02618 const scalar level0Size = 2*maxFaceDiff*level0Edge_;
02619
02620
02621
02622
02623
02624
02625
02626
02627 List<refinementDistanceData> allCellInfo(mesh_.nCells());
02628
02629
02630 List<refinementDistanceData> allFaceInfo(mesh_.nFaces());
02631
02632
02633
02634 forAll(cellsToRefine, i)
02635 {
02636 label cellI = cellsToRefine[i];
02637
02638 allCellInfo[cellI] = refinementDistanceData
02639 (
02640 level0Size,
02641 mesh_.cellCentres()[cellI],
02642 cellLevel_[cellI]+1
02643 );
02644 }
02645
02646 forAll(allCellInfo, cellI)
02647 {
02648 if (!allCellInfo[cellI].valid())
02649 {
02650 allCellInfo[cellI] = refinementDistanceData
02651 (
02652 level0Size,
02653 mesh_.cellCentres()[cellI],
02654 cellLevel_[cellI]
02655 );
02656 }
02657 }
02658
02659
02660
02661 DynamicList<label> seedFaces(mesh_.nFaces()/100);
02662
02663 DynamicList<refinementDistanceData> seedFacesInfo(mesh_.nFaces()/100);
02664
02665
02666 const pointField& cc = mesh_.cellCentres();
02667
02668 forAll(facesToCheck, i)
02669 {
02670 label faceI = facesToCheck[i];
02671
02672 if (allFaceInfo[faceI].valid())
02673 {
02674
02675 FatalErrorIn
02676 (
02677 "hexRef8::consistentSlowRefinement2"
02678 "(const label, const labelList&, const labelList&)"
02679 ) << "Argument facesToCheck seems to have duplicate entries!"
02680 << endl
02681 << "face:" << faceI << " occurs at positions "
02682 << findIndices(facesToCheck, faceI)
02683 << abort(FatalError);
02684 }
02685
02686 label own = faceOwner[faceI];
02687
02688 label ownLevel =
02689 (
02690 allCellInfo[own].valid()
02691 ? allCellInfo[own].originLevel()
02692 : cellLevel_[own]
02693 );
02694
02695 if (!mesh_.isInternalFace(faceI))
02696 {
02697
02698
02699 const point& fc = mesh_.faceCentres()[faceI];
02700
02701 refinementDistanceData neiData
02702 (
02703 level0Size,
02704 2*fc - cc[own],
02705 ownLevel+1
02706 );
02707
02708 allFaceInfo[faceI].updateFace
02709 (
02710 mesh_,
02711 faceI,
02712 own,
02713 neiData,
02714 FaceCellWave<refinementDistanceData>::propagationTol()
02715 );
02716 }
02717 else
02718 {
02719 label nei = faceNeighbour[faceI];
02720
02721 label neiLevel =
02722 (
02723 allCellInfo[nei].valid()
02724 ? allCellInfo[nei].originLevel()
02725 : cellLevel_[nei]
02726 );
02727
02728 if (ownLevel == neiLevel)
02729 {
02730
02731 allFaceInfo[faceI].updateFace
02732 (
02733 mesh_,
02734 faceI,
02735 nei,
02736 refinementDistanceData(level0Size, cc[nei], neiLevel+1),
02737 FaceCellWave<refinementDistanceData>::propagationTol()
02738 );
02739 allFaceInfo[faceI].updateFace
02740 (
02741 mesh_,
02742 faceI,
02743 own,
02744 refinementDistanceData(level0Size, cc[own], ownLevel+1),
02745 FaceCellWave<refinementDistanceData>::propagationTol()
02746 );
02747 }
02748 else
02749 {
02750
02751 allFaceInfo[faceI].updateFace
02752 (
02753 mesh_,
02754 faceI,
02755 nei,
02756 refinementDistanceData(level0Size, cc[nei], neiLevel),
02757 FaceCellWave<refinementDistanceData>::propagationTol()
02758 );
02759 allFaceInfo[faceI].updateFace
02760 (
02761 mesh_,
02762 faceI,
02763 own,
02764 refinementDistanceData(level0Size, cc[own], ownLevel),
02765 FaceCellWave<refinementDistanceData>::propagationTol()
02766 );
02767 }
02768 }
02769 seedFaces.append(faceI);
02770 seedFacesInfo.append(allFaceInfo[faceI]);
02771 }
02772
02773
02774
02775
02776
02777 forAll(faceNeighbour, faceI)
02778 {
02779
02780 if (!allFaceInfo[faceI].valid())
02781 {
02782 label own = faceOwner[faceI];
02783
02784 label ownLevel =
02785 (
02786 allCellInfo[own].valid()
02787 ? allCellInfo[own].originLevel()
02788 : cellLevel_[own]
02789 );
02790
02791 label nei = faceNeighbour[faceI];
02792
02793 label neiLevel =
02794 (
02795 allCellInfo[nei].valid()
02796 ? allCellInfo[nei].originLevel()
02797 : cellLevel_[nei]
02798 );
02799
02800 if (ownLevel > neiLevel)
02801 {
02802
02803 seedFaces.append(faceI);
02804 allFaceInfo[faceI].updateFace
02805 (
02806 mesh_,
02807 faceI,
02808 own,
02809 refinementDistanceData(level0Size, cc[own], ownLevel),
02810 FaceCellWave<refinementDistanceData>::propagationTol()
02811 );
02812 seedFacesInfo.append(allFaceInfo[faceI]);
02813 }
02814 else if (neiLevel > ownLevel)
02815 {
02816 seedFaces.append(faceI);
02817 allFaceInfo[faceI].updateFace
02818 (
02819 mesh_,
02820 faceI,
02821 nei,
02822 refinementDistanceData(level0Size, cc[nei], neiLevel),
02823 FaceCellWave<refinementDistanceData>::propagationTol()
02824 );
02825 seedFacesInfo.append(allFaceInfo[faceI]);
02826 }
02827 }
02828 }
02829
02830 seedFaces.shrink();
02831 seedFacesInfo.shrink();
02832
02833
02834 FaceCellWave<refinementDistanceData> levelCalc
02835 (
02836 mesh_,
02837 seedFaces,
02838 seedFacesInfo,
02839 allFaceInfo,
02840 allCellInfo,
02841 mesh_.globalData().nTotalCells()
02842 );
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879 forAll(cellsToRefine, i)
02880 {
02881 label cellI = cellsToRefine[i];
02882
02883 allCellInfo[cellI].originLevel() = sizeof(label)*8-2;
02884 allCellInfo[cellI].origin() = cc[cellI];
02885 }
02886
02887
02888
02889
02890 PackedBoolList refineCell(mesh_.nCells());
02891 forAll(allCellInfo, cellI)
02892 {
02893 label wanted = allCellInfo[cellI].wantedLevel(cc[cellI]);
02894
02895 if (wanted > cellLevel_[cellI]+1)
02896 {
02897 refineCell.set(cellI, 1);
02898 }
02899 }
02900 faceConsistentRefinement(true, refineCell);
02901
02902 while (true)
02903 {
02904 label nChanged = faceConsistentRefinement(true, refineCell);
02905
02906 reduce(nChanged, sumOp<label>());
02907
02908 if (debug)
02909 {
02910 Pout<< "hexRef8::consistentSlowRefinement2 : Changed " << nChanged
02911 << " refinement levels due to 2:1 conflicts."
02912 << endl;
02913 }
02914
02915 if (nChanged == 0)
02916 {
02917 break;
02918 }
02919 }
02920
02921
02922 label nRefined = 0;
02923
02924 forAll(refineCell, cellI)
02925 {
02926 if (refineCell.get(cellI) == 1)
02927 {
02928 nRefined++;
02929 }
02930 }
02931
02932 labelList newCellsToRefine(nRefined);
02933 nRefined = 0;
02934
02935 forAll(refineCell, cellI)
02936 {
02937 if (refineCell.get(cellI) == 1)
02938 {
02939 newCellsToRefine[nRefined++] = cellI;
02940 }
02941 }
02942
02943 if (debug)
02944 {
02945 Pout<< "hexRef8::consistentSlowRefinement2 : From "
02946 << cellsToRefine.size() << " to " << newCellsToRefine.size()
02947 << " cells to refine." << endl;
02948
02949
02950
02951 {
02952 cellSet cellsIn(mesh_, "cellsToRefineIn", cellsToRefine);
02953 Pout<< "hexRef8::consistentSlowRefinement2 : writing "
02954 << cellsIn.size() << " to cellSet "
02955 << cellsIn.objectPath() << endl;
02956 cellsIn.write();
02957 }
02958 {
02959 cellSet cellsOut(mesh_, "cellsToRefineOut", newCellsToRefine);
02960 Pout<< "hexRef8::consistentSlowRefinement2 : writing "
02961 << cellsOut.size() << " to cellSet "
02962 << cellsOut.objectPath() << endl;
02963 cellsOut.write();
02964 }
02965
02966
02967 PackedBoolList refineCell(mesh_.nCells());
02968 forAll(newCellsToRefine, i)
02969 {
02970 refineCell.set(newCellsToRefine[i], 1);
02971 }
02972 const PackedBoolList savedRefineCell(refineCell);
02973
02974 label nChanged = faceConsistentRefinement(true, refineCell);
02975
02976 {
02977 cellSet cellsOut2
02978 (
02979 mesh_, "cellsToRefineOut2", newCellsToRefine.size()
02980 );
02981 forAll(refineCell, cellI)
02982 {
02983 if (refineCell.get(cellI) == 1)
02984 {
02985 cellsOut2.insert(cellI);
02986 }
02987 }
02988 Pout<< "hexRef8::consistentSlowRefinement2 : writing "
02989 << cellsOut2.size() << " to cellSet "
02990 << cellsOut2.objectPath() << endl;
02991 cellsOut2.write();
02992 }
02993
02994 if (nChanged > 0)
02995 {
02996 forAll(refineCell, cellI)
02997 {
02998 if
02999 (
03000 refineCell.get(cellI) == 1
03001 && savedRefineCell.get(cellI) == 0
03002 )
03003 {
03004 dumpCell(cellI);
03005 FatalErrorIn
03006 (
03007 "hexRef8::consistentSlowRefinement2"
03008 "(const label, const labelList&, const labelList&)"
03009 ) << "Cell:" << cellI << " cc:"
03010 << mesh_.cellCentres()[cellI]
03011 << " was not marked for refinement but does not obey"
03012 << " 2:1 constraints."
03013 << abort(FatalError);
03014 }
03015 }
03016 }
03017 }
03018
03019 return newCellsToRefine;
03020 }
03021
03022
03023
03024 Foam::labelListList Foam::hexRef8::setRefinement
03025 (
03026 const labelList& cellLabels,
03027 polyTopoChange& meshMod
03028 )
03029 {
03030 if (debug)
03031 {
03032 Pout<< "hexRef8::setRefinement :"
03033 << " Checking initial mesh just to make sure" << endl;
03034
03035 checkMesh();
03036
03037
03038
03039 }
03040
03041
03042 savedPointLevel_.clear();
03043 savedCellLevel_.clear();
03044
03045
03046
03047 DynamicList<label> newCellLevel(cellLevel_.size());
03048 forAll(cellLevel_, cellI)
03049 {
03050 newCellLevel.append(cellLevel_[cellI]);
03051 }
03052 DynamicList<label> newPointLevel(pointLevel_.size());
03053 forAll(pointLevel_, pointI)
03054 {
03055 newPointLevel.append(pointLevel_[pointI]);
03056 }
03057
03058
03059 if (debug)
03060 {
03061 Pout<< "hexRef8::setRefinement :"
03062 << " Allocating " << cellLabels.size() << " cell midpoints."
03063 << endl;
03064 }
03065
03066
03067
03068
03069
03070 labelList cellMidPoint(mesh_.nCells(), -1);
03071
03072 forAll(cellLabels, i)
03073 {
03074 label cellI = cellLabels[i];
03075
03076 label anchorPointI = mesh_.faces()[mesh_.cells()[cellI][0]][0];
03077
03078 cellMidPoint[cellI] = meshMod.setAction
03079 (
03080 polyAddPoint
03081 (
03082 mesh_.cellCentres()[cellI],
03083 anchorPointI,
03084 -1,
03085 true
03086 )
03087 );
03088
03089 newPointLevel(cellMidPoint[cellI]) = cellLevel_[cellI]+1;
03090 }
03091
03092
03093 if (debug)
03094 {
03095 cellSet splitCells(mesh_, "splitCells", cellLabels.size());
03096
03097 forAll(cellMidPoint, cellI)
03098 {
03099 if (cellMidPoint[cellI] >= 0)
03100 {
03101 splitCells.insert(cellI);
03102 }
03103 }
03104
03105 Pout<< "hexRef8::setRefinement : Dumping " << splitCells.size()
03106 << " cells to split to cellSet " << splitCells.objectPath()
03107 << endl;
03108
03109 splitCells.write();
03110 }
03111
03112
03113
03114
03115
03116
03117 if (debug)
03118 {
03119 Pout<< "hexRef8::setRefinement :"
03120 << " Allocating edge midpoints."
03121 << endl;
03122 }
03123
03124
03125
03126
03127
03128
03129 labelList edgeMidPoint(mesh_.nEdges(), -1);
03130
03131
03132 forAll(cellMidPoint, cellI)
03133 {
03134 if (cellMidPoint[cellI] >= 0)
03135 {
03136 const labelList& cEdges = mesh_.cellEdges(cellI);
03137
03138 forAll(cEdges, i)
03139 {
03140 label edgeI = cEdges[i];
03141
03142 const edge& e = mesh_.edges()[edgeI];
03143
03144 if
03145 (
03146 pointLevel_[e[0]] <= cellLevel_[cellI]
03147 && pointLevel_[e[1]] <= cellLevel_[cellI]
03148 )
03149 {
03150 edgeMidPoint[edgeI] = 12345;
03151 }
03152 }
03153 }
03154 }
03155
03156
03157
03158 syncTools::syncEdgeList
03159 (
03160 mesh_,
03161 edgeMidPoint,
03162 maxEqOp<label>(),
03163 labelMin,
03164 false
03165 );
03166
03167
03168
03169
03170
03171 {
03172
03173
03174
03175
03176 pointField edgeMids(mesh_.nEdges(), point(-GREAT, -GREAT, -GREAT));
03177
03178 forAll(edgeMidPoint, edgeI)
03179 {
03180 if (edgeMidPoint[edgeI] >= 0)
03181 {
03182
03183 edgeMids[edgeI] = mesh_.edges()[edgeI].centre(mesh_.points());
03184 }
03185 }
03186 syncTools::syncEdgeList
03187 (
03188 mesh_,
03189 edgeMids,
03190 maxEqOp<vector>(),
03191 point(-GREAT, -GREAT, -GREAT),
03192 true
03193 );
03194
03195
03196
03197 forAll(edgeMidPoint, edgeI)
03198 {
03199 if (edgeMidPoint[edgeI] >= 0)
03200 {
03201
03202
03203
03204 const edge& e = mesh_.edges()[edgeI];
03205
03206 edgeMidPoint[edgeI] = meshMod.setAction
03207 (
03208 polyAddPoint
03209 (
03210 edgeMids[edgeI],
03211 e[0],
03212 -1,
03213 true
03214 )
03215 );
03216
03217 newPointLevel(edgeMidPoint[edgeI]) =
03218 max
03219 (
03220 pointLevel_[e[0]],
03221 pointLevel_[e[1]]
03222 )
03223 + 1;
03224 }
03225 }
03226 }
03227
03228 if (debug)
03229 {
03230 OFstream str(mesh_.time().path()/"edgeMidPoint.obj");
03231
03232 forAll(edgeMidPoint, edgeI)
03233 {
03234 if (edgeMidPoint[edgeI] >= 0)
03235 {
03236 const edge& e = mesh_.edges()[edgeI];
03237
03238 meshTools::writeOBJ(str, e.centre(mesh_.points()));
03239 }
03240 }
03241
03242 Pout<< "hexRef8::setRefinement :"
03243 << " Dumping edge centres to split to file " << str.name() << endl;
03244 }
03245
03246
03247
03248
03249
03250
03251 if (debug)
03252 {
03253 Pout<< "hexRef8::setRefinement :"
03254 << " Allocating face midpoints."
03255 << endl;
03256 }
03257
03258
03259
03260 labelList faceAnchorLevel(mesh_.nFaces());
03261
03262 for (label faceI = 0; faceI < mesh_.nFaces(); faceI++)
03263 {
03264 faceAnchorLevel[faceI] = getAnchorLevel(faceI);
03265 }
03266
03267
03268
03269 labelList faceMidPoint(mesh_.nFaces(), -1);
03270
03271
03272
03273
03274 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
03275 {
03276 if (faceAnchorLevel[faceI] >= 0)
03277 {
03278 label own = mesh_.faceOwner()[faceI];
03279 label ownLevel = cellLevel_[own];
03280 label newOwnLevel = ownLevel + (cellMidPoint[own] >= 0 ? 1 : 0);
03281
03282 label nei = mesh_.faceNeighbour()[faceI];
03283 label neiLevel = cellLevel_[nei];
03284 label newNeiLevel = neiLevel + (cellMidPoint[nei] >= 0 ? 1 : 0);
03285
03286 if
03287 (
03288 newOwnLevel > faceAnchorLevel[faceI]
03289 || newNeiLevel > faceAnchorLevel[faceI]
03290 )
03291 {
03292 faceMidPoint[faceI] = 12345;
03293 }
03294 }
03295 }
03296
03297
03298
03299
03300
03301
03302
03303
03304 {
03305 labelList newNeiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
03306
03307 forAll(newNeiLevel, i)
03308 {
03309 label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
03310 label ownLevel = cellLevel_[own];
03311 label newOwnLevel = ownLevel + (cellMidPoint[own] >= 0 ? 1 : 0);
03312
03313 newNeiLevel[i] = newOwnLevel;
03314 }
03315
03316
03317 syncTools::swapBoundaryFaceList(mesh_, newNeiLevel, false);
03318
03319
03320
03321 forAll(newNeiLevel, i)
03322 {
03323 label faceI = i+mesh_.nInternalFaces();
03324
03325 if (faceAnchorLevel[faceI] >= 0)
03326 {
03327 label own = mesh_.faceOwner()[faceI];
03328 label ownLevel = cellLevel_[own];
03329 label newOwnLevel = ownLevel + (cellMidPoint[own] >= 0 ? 1 : 0);
03330
03331 if
03332 (
03333 newOwnLevel > faceAnchorLevel[faceI]
03334 || newNeiLevel[i] > faceAnchorLevel[faceI]
03335 )
03336 {
03337 faceMidPoint[faceI] = 12345;
03338 }
03339 }
03340 }
03341 }
03342
03343
03344
03345 syncTools::syncFaceList
03346 (
03347 mesh_,
03348 faceMidPoint,
03349 maxEqOp<label>(),
03350 false
03351 );
03352
03353
03354
03355
03356
03357
03358 {
03359
03360
03361 pointField bFaceMids
03362 (
03363 mesh_.nFaces()-mesh_.nInternalFaces(),
03364 point(-GREAT, -GREAT, -GREAT)
03365 );
03366
03367 forAll(bFaceMids, i)
03368 {
03369 label faceI = i+mesh_.nInternalFaces();
03370
03371 if (faceMidPoint[faceI] >= 0)
03372 {
03373 bFaceMids[i] = mesh_.faceCentres()[faceI];
03374 }
03375 }
03376 syncTools::syncBoundaryFaceList
03377 (
03378 mesh_,
03379 bFaceMids,
03380 maxEqOp<vector>(),
03381 true
03382 );
03383
03384 forAll(faceMidPoint, faceI)
03385 {
03386 if (faceMidPoint[faceI] >= 0)
03387 {
03388
03389
03390
03391 const face& f = mesh_.faces()[faceI];
03392
03393 faceMidPoint[faceI] = meshMod.setAction
03394 (
03395 polyAddPoint
03396 (
03397 (
03398 faceI < mesh_.nInternalFaces()
03399 ? mesh_.faceCentres()[faceI]
03400 : bFaceMids[faceI-mesh_.nInternalFaces()]
03401 ),
03402 f[0],
03403 -1,
03404 true
03405 )
03406 );
03407
03408
03409
03410 newPointLevel(faceMidPoint[faceI]) = faceAnchorLevel[faceI]+1;
03411 }
03412 }
03413 }
03414
03415 if (debug)
03416 {
03417 faceSet splitFaces(mesh_, "splitFaces", cellLabels.size());
03418
03419 forAll(faceMidPoint, faceI)
03420 {
03421 if (faceMidPoint[faceI] >= 0)
03422 {
03423 splitFaces.insert(faceI);
03424 }
03425 }
03426
03427 Pout<< "hexRef8::setRefinement : Dumping " << splitFaces.size()
03428 << " faces to split to faceSet " << splitFaces.objectPath() << endl;
03429
03430 splitFaces.write();
03431 }
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447 if (debug)
03448 {
03449 Pout<< "hexRef8::setRefinement :"
03450 << " Finding cell anchorPoints (8 per cell)"
03451 << endl;
03452 }
03453
03454
03455
03456
03457
03458 labelListList cellAnchorPoints(mesh_.nCells());
03459
03460 {
03461 labelList nAnchorPoints(mesh_.nCells(), 0);
03462
03463 forAll(cellMidPoint, cellI)
03464 {
03465 if (cellMidPoint[cellI] >= 0)
03466 {
03467 cellAnchorPoints[cellI].setSize(8);
03468 }
03469 }
03470
03471 forAll(pointLevel_, pointI)
03472 {
03473 const labelList& pCells = mesh_.pointCells(pointI);
03474
03475 forAll(pCells, pCellI)
03476 {
03477 label cellI = pCells[pCellI];
03478
03479 if
03480 (
03481 cellMidPoint[cellI] >= 0
03482 && pointLevel_[pointI] <= cellLevel_[cellI]
03483 )
03484 {
03485 if (nAnchorPoints[cellI] == 8)
03486 {
03487 dumpCell(cellI);
03488 FatalErrorIn
03489 (
03490 "hexRef8::setRefinement(const labelList&"
03491 ", polyTopoChange&)"
03492 ) << "cell " << cellI
03493 << " of level " << cellLevel_[cellI]
03494 << " uses more than 8 points of equal or"
03495 << " lower level" << nl
03496 << "Points so far:" << cellAnchorPoints[cellI]
03497 << abort(FatalError);
03498 }
03499
03500 cellAnchorPoints[cellI][nAnchorPoints[cellI]++] = pointI;
03501 }
03502 }
03503 }
03504
03505 forAll(cellMidPoint, cellI)
03506 {
03507 if (cellMidPoint[cellI] >= 0)
03508 {
03509 if (nAnchorPoints[cellI] != 8)
03510 {
03511 dumpCell(cellI);
03512
03513 const labelList& cPoints = mesh_.cellPoints(cellI);
03514
03515 FatalErrorIn
03516 (
03517 "hexRef8::setRefinement(const labelList&"
03518 ", polyTopoChange&)"
03519 ) << "cell " << cellI
03520 << " of level " << cellLevel_[cellI]
03521 << " does not seem to have 8 points of equal or"
03522 << " lower level" << endl
03523 << "cellPoints:" << cPoints << endl
03524 << "pointLevels:"
03525 << UIndirectList<label>(pointLevel_, cPoints)() << endl
03526 << abort(FatalError);
03527 }
03528 }
03529 }
03530 }
03531
03532
03533
03534
03535
03536 if (debug)
03537 {
03538 Pout<< "hexRef8::setRefinement :"
03539 << " Adding cells (1 per anchorPoint)"
03540 << endl;
03541 }
03542
03543
03544 labelListList cellAddedCells(mesh_.nCells());
03545
03546 forAll(cellAnchorPoints, cellI)
03547 {
03548 const labelList& cAnchors = cellAnchorPoints[cellI];
03549
03550 if (cAnchors.size() == 8)
03551 {
03552 labelList& cAdded = cellAddedCells[cellI];
03553 cAdded.setSize(8);
03554
03555
03556 cAdded[0] = cellI;
03557
03558
03559 newCellLevel[cellI] = cellLevel_[cellI]+1;
03560
03561
03562 for (label i = 1; i < 8; i++)
03563 {
03564 cAdded[i] = meshMod.setAction
03565 (
03566 polyAddCell
03567 (
03568 -1,
03569 -1,
03570 -1,
03571 cellI,
03572 mesh_.cellZones().whichZone(cellI)
03573 )
03574 );
03575
03576 newCellLevel(cAdded[i]) = cellLevel_[cellI]+1;
03577 }
03578 }
03579 }
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589 if (debug)
03590 {
03591 Pout<< "hexRef8::setRefinement :"
03592 << " Marking faces to be handled"
03593 << endl;
03594 }
03595
03596
03597 PackedBoolList affectedFace(mesh_.nFaces());
03598
03599 {
03600 forAll(cellMidPoint, cellI)
03601 {
03602 if (cellMidPoint[cellI] >= 0)
03603 {
03604 const cell& cFaces = mesh_.cells()[cellI];
03605
03606 forAll(cFaces, i)
03607 {
03608 affectedFace.set(cFaces[i], 1);
03609 }
03610 }
03611 }
03612
03613 forAll(faceMidPoint, faceI)
03614 {
03615 if (faceMidPoint[faceI] >= 0)
03616 {
03617 affectedFace.set(faceI, 1);
03618 }
03619 }
03620
03621 forAll(edgeMidPoint, edgeI)
03622 {
03623 if (edgeMidPoint[edgeI] >= 0)
03624 {
03625 const labelList& eFaces = mesh_.edgeFaces(edgeI);
03626
03627 forAll(eFaces, i)
03628 {
03629 affectedFace.set(eFaces[i], 1);
03630 }
03631 }
03632 }
03633 }
03634
03635
03636
03637
03638
03639 if (debug)
03640 {
03641 Pout<< "hexRef8::setRefinement : Splitting faces" << endl;
03642 }
03643
03644 forAll(faceMidPoint, faceI)
03645 {
03646 if (faceMidPoint[faceI] >= 0 && affectedFace.get(faceI) == 1)
03647 {
03648
03649
03650
03651
03652 const face& f = mesh_.faces()[faceI];
03653
03654
03655
03656 bool modifiedFace = false;
03657
03658 label anchorLevel = faceAnchorLevel[faceI];
03659
03660 face newFace(4);
03661
03662 forAll(f, fp)
03663 {
03664 label pointI = f[fp];
03665
03666 if (pointLevel_[pointI] <= anchorLevel)
03667 {
03668
03669
03670 DynamicList<label> faceVerts(4);
03671
03672 faceVerts.append(pointI);
03673
03674
03675
03676
03677
03678
03679 walkFaceToMid
03680 (
03681 edgeMidPoint,
03682 anchorLevel,
03683 faceI,
03684 fp,
03685 faceVerts
03686 );
03687
03688 faceVerts.append(faceMidPoint[faceI]);
03689
03690 walkFaceFromMid
03691 (
03692 edgeMidPoint,
03693 anchorLevel,
03694 faceI,
03695 fp,
03696 faceVerts
03697 );
03698
03699
03700 newFace.transfer(faceVerts);
03701
03702
03703
03704
03705
03706 label own, nei;
03707 getFaceNeighbours
03708 (
03709 cellAnchorPoints,
03710 cellAddedCells,
03711 faceI,
03712 pointI,
03713
03714 own,
03715 nei
03716 );
03717
03718
03719 if (debug)
03720 {
03721 if (mesh_.isInternalFace(faceI))
03722 {
03723 label oldOwn = mesh_.faceOwner()[faceI];
03724 label oldNei = mesh_.faceNeighbour()[faceI];
03725
03726 checkInternalOrientation
03727 (
03728 meshMod,
03729 oldOwn,
03730 faceI,
03731 mesh_.cellCentres()[oldOwn],
03732 mesh_.cellCentres()[oldNei],
03733 newFace
03734 );
03735 }
03736 else
03737 {
03738 label oldOwn = mesh_.faceOwner()[faceI];
03739
03740 checkBoundaryOrientation
03741 (
03742 meshMod,
03743 oldOwn,
03744 faceI,
03745 mesh_.cellCentres()[oldOwn],
03746 mesh_.faceCentres()[faceI],
03747 newFace
03748 );
03749 }
03750 }
03751
03752
03753 if (!modifiedFace)
03754 {
03755 modifiedFace = true;
03756
03757 modFace(meshMod, faceI, newFace, own, nei);
03758 }
03759 else
03760 {
03761 addFace(meshMod, faceI, newFace, own, nei);
03762 }
03763 }
03764 }
03765
03766
03767 affectedFace.set(faceI, 0);
03768 }
03769 }
03770
03771
03772
03773
03774
03775 if (debug)
03776 {
03777 Pout<< "hexRef8::setRefinement :"
03778 << " Adding edge splits to unsplit faces"
03779 << endl;
03780 }
03781
03782 DynamicList<label> eFacesStorage;
03783 DynamicList<label> fEdgesStorage;
03784
03785 forAll(edgeMidPoint, edgeI)
03786 {
03787 if (edgeMidPoint[edgeI] >= 0)
03788 {
03789
03790
03791 const labelList& eFaces = mesh_.edgeFaces(edgeI, eFacesStorage);
03792
03793 forAll(eFaces, i)
03794 {
03795 label faceI = eFaces[i];
03796
03797 if (faceMidPoint[faceI] < 0 && affectedFace.get(faceI) == 1)
03798 {
03799
03800
03801 const face& f = mesh_.faces()[faceI];
03802 const labelList& fEdges = mesh_.faceEdges
03803 (
03804 faceI,
03805 fEdgesStorage
03806 );
03807
03808 DynamicList<label> newFaceVerts(f.size());
03809
03810 forAll(f, fp)
03811 {
03812 newFaceVerts.append(f[fp]);
03813
03814 label edgeI = fEdges[fp];
03815
03816 if (edgeMidPoint[edgeI] >= 0)
03817 {
03818 newFaceVerts.append(edgeMidPoint[edgeI]);
03819 }
03820 }
03821
03822 face newFace;
03823 newFace.transfer(newFaceVerts);
03824
03825
03826
03827 label anchorFp = findMinLevel(f);
03828
03829 label own, nei;
03830 getFaceNeighbours
03831 (
03832 cellAnchorPoints,
03833 cellAddedCells,
03834 faceI,
03835 f[anchorFp],
03836
03837 own,
03838 nei
03839 );
03840
03841
03842 if (debug)
03843 {
03844 if (mesh_.isInternalFace(faceI))
03845 {
03846 label oldOwn = mesh_.faceOwner()[faceI];
03847 label oldNei = mesh_.faceNeighbour()[faceI];
03848
03849 checkInternalOrientation
03850 (
03851 meshMod,
03852 oldOwn,
03853 faceI,
03854 mesh_.cellCentres()[oldOwn],
03855 mesh_.cellCentres()[oldNei],
03856 newFace
03857 );
03858 }
03859 else
03860 {
03861 label oldOwn = mesh_.faceOwner()[faceI];
03862
03863 checkBoundaryOrientation
03864 (
03865 meshMod,
03866 oldOwn,
03867 faceI,
03868 mesh_.cellCentres()[oldOwn],
03869 mesh_.faceCentres()[faceI],
03870 newFace
03871 );
03872 }
03873 }
03874
03875 modFace(meshMod, faceI, newFace, own, nei);
03876
03877
03878 affectedFace.set(faceI, 0);
03879 }
03880 }
03881 }
03882 }
03883
03884
03885
03886
03887
03888 if (debug)
03889 {
03890 Pout<< "hexRef8::setRefinement :"
03891 << " Changing owner/neighbour for otherwise unaffected faces"
03892 << endl;
03893 }
03894
03895 forAll(affectedFace, faceI)
03896 {
03897 if (affectedFace.get(faceI) == 1)
03898 {
03899 const face& f = mesh_.faces()[faceI];
03900
03901
03902
03903 label anchorFp = findMinLevel(f);
03904
03905 label own, nei;
03906 getFaceNeighbours
03907 (
03908 cellAnchorPoints,
03909 cellAddedCells,
03910 faceI,
03911 f[anchorFp],
03912
03913 own,
03914 nei
03915 );
03916
03917 modFace(meshMod, faceI, f, own, nei);
03918
03919
03920 affectedFace.set(faceI, 0);
03921 }
03922 }
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933 if (debug)
03934 {
03935 Pout<< "hexRef8::setRefinement :"
03936 << " Create new internal faces for split cells"
03937 << endl;
03938 }
03939
03940 forAll(cellMidPoint, cellI)
03941 {
03942 if (cellMidPoint[cellI] >= 0)
03943 {
03944 createInternalFaces
03945 (
03946 cellAnchorPoints,
03947 cellAddedCells,
03948 cellMidPoint,
03949 faceMidPoint,
03950 faceAnchorLevel,
03951 edgeMidPoint,
03952 cellI,
03953 meshMod
03954 );
03955 }
03956 }
03957
03958
03959
03960
03961
03962 if (debug)
03963 {
03964 label minPointI = labelMax;
03965 label maxPointI = labelMin;
03966
03967 forAll(cellMidPoint, cellI)
03968 {
03969 if (cellMidPoint[cellI] >= 0)
03970 {
03971 minPointI = min(minPointI, cellMidPoint[cellI]);
03972 maxPointI = max(maxPointI, cellMidPoint[cellI]);
03973 }
03974 }
03975 forAll(faceMidPoint, faceI)
03976 {
03977 if (faceMidPoint[faceI] >= 0)
03978 {
03979 minPointI = min(minPointI, faceMidPoint[faceI]);
03980 maxPointI = max(maxPointI, faceMidPoint[faceI]);
03981 }
03982 }
03983 forAll(edgeMidPoint, edgeI)
03984 {
03985 if (edgeMidPoint[edgeI] >= 0)
03986 {
03987 minPointI = min(minPointI, edgeMidPoint[edgeI]);
03988 maxPointI = max(maxPointI, edgeMidPoint[edgeI]);
03989 }
03990 }
03991
03992 if (minPointI != labelMax && minPointI != mesh_.nPoints())
03993 {
03994 FatalErrorIn("hexRef8::setRefinement(..)")
03995 << "Added point labels not consecutive to existing mesh points."
03996 << nl
03997 << "mesh_.nPoints():" << mesh_.nPoints()
03998 << " minPointI:" << minPointI
03999 << " maxPointI:" << maxPointI
04000 << abort(FatalError);
04001 }
04002 }
04003
04004 pointLevel_.transfer(newPointLevel);
04005 cellLevel_.transfer(newCellLevel);
04006
04007
04008 setInstance(mesh_.facesInstance());
04009
04010
04011
04012
04013
04014
04015 if (history_.active())
04016 {
04017 if (debug)
04018 {
04019 Pout<< "hexRef8::setRefinement :"
04020 << " Updating refinement history to " << cellLevel_.size()
04021 << " cells" << endl;
04022 }
04023
04024
04025 history_.resize(cellLevel_.size());
04026
04027 forAll(cellAddedCells, cellI)
04028 {
04029 const labelList& addedCells = cellAddedCells[cellI];
04030
04031 if (addedCells.size())
04032 {
04033
04034 history_.storeSplit(cellI, addedCells);
04035 }
04036 }
04037 }
04038
04039
04040
04041 labelListList refinedCells(cellLabels.size());
04042
04043 forAll(cellLabels, i)
04044 {
04045 label cellI = cellLabels[i];
04046
04047 refinedCells[i].transfer(cellAddedCells[cellI]);
04048 }
04049
04050 return refinedCells;
04051 }
04052
04053
04054 void Foam::hexRef8::storeData
04055 (
04056 const labelList& pointsToStore,
04057 const labelList& facesToStore,
04058 const labelList& cellsToStore
04059 )
04060 {
04061 savedPointLevel_.resize(2*pointsToStore.size());
04062 forAll(pointsToStore, i)
04063 {
04064 label pointI = pointsToStore[i];
04065 savedPointLevel_.insert(pointI, pointLevel_[pointI]);
04066 }
04067
04068 savedCellLevel_.resize(2*cellsToStore.size());
04069 forAll(cellsToStore, i)
04070 {
04071 label cellI = cellsToStore[i];
04072 savedCellLevel_.insert(cellI, cellLevel_[cellI]);
04073 }
04074 }
04075
04076
04077
04078
04079
04080 void Foam::hexRef8::updateMesh(const mapPolyMesh& map)
04081 {
04082 Map<label> dummyMap(0);
04083
04084 updateMesh(map, dummyMap, dummyMap, dummyMap);
04085 }
04086
04087
04088
04089
04090
04091 void Foam::hexRef8::updateMesh
04092 (
04093 const mapPolyMesh& map,
04094 const Map<label>& pointsToRestore,
04095 const Map<label>& facesToRestore,
04096 const Map<label>& cellsToRestore
04097 )
04098 {
04099
04100 if (debug)
04101 {
04102 Pout<< "hexRef8::updateMesh :"
04103 << " Updating various lists"
04104 << endl;
04105 }
04106
04107 {
04108 const labelList& reverseCellMap = map.reverseCellMap();
04109
04110 if (debug)
04111 {
04112 Pout<< "hexRef8::updateMesh :"
04113 << " reverseCellMap:" << map.reverseCellMap().size()
04114 << " cellMap:" << map.cellMap().size()
04115 << " nCells:" << mesh_.nCells()
04116 << " nOldCells:" << map.nOldCells()
04117 << " cellLevel_:" << cellLevel_.size()
04118 << " reversePointMap:" << map.reversePointMap().size()
04119 << " pointMap:" << map.pointMap().size()
04120 << " nPoints:" << mesh_.nPoints()
04121 << " nOldPoints:" << map.nOldPoints()
04122 << " pointLevel_:" << pointLevel_.size()
04123 << endl;
04124 }
04125
04126 if (reverseCellMap.size() == cellLevel_.size())
04127 {
04128
04129
04130
04131
04132 reorder(reverseCellMap, mesh_.nCells(), -1, cellLevel_);
04133 }
04134 else
04135 {
04136
04137 const labelList& cellMap = map.cellMap();
04138
04139 labelList newCellLevel(cellMap.size());
04140 forAll(cellMap, newCellI)
04141 {
04142 label oldCellI = cellMap[newCellI];
04143
04144 if (oldCellI == -1)
04145 {
04146 newCellLevel[newCellI] = -1;
04147 }
04148 else
04149 {
04150 newCellLevel[newCellI] = cellLevel_[oldCellI];
04151 }
04152 }
04153 cellLevel_.transfer(newCellLevel);
04154 }
04155
04156
04157
04158 forAllConstIter(Map<label>, cellsToRestore, iter)
04159 {
04160 label newCellI = iter.key();
04161 label storedCellI = iter();
04162
04163 Map<label>::iterator fnd = savedCellLevel_.find(storedCellI);
04164
04165 if (fnd == savedCellLevel_.end())
04166 {
04167 FatalErrorIn("hexRef8::updateMesh(const mapPolyMesh&)")
04168 << "Problem : trying to restore old value for new cell "
04169 << newCellI << " but cannot find old cell " << storedCellI
04170 << " in map of stored values " << savedCellLevel_
04171 << abort(FatalError);
04172 }
04173 cellLevel_[newCellI] = fnd();
04174 }
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187 }
04188
04189
04190
04191 {
04192 const labelList& reversePointMap = map.reversePointMap();
04193
04194 if (reversePointMap.size() == pointLevel_.size())
04195 {
04196
04197 reorder(reversePointMap, mesh_.nPoints(), -1, pointLevel_);
04198 }
04199 else
04200 {
04201
04202 const labelList& pointMap = map.pointMap();
04203
04204 labelList newPointLevel(pointMap.size());
04205
04206 forAll(pointMap, newPointI)
04207 {
04208 label oldPointI = pointMap[newPointI];
04209
04210 if (oldPointI == -1)
04211 {
04212
04213
04214
04215
04216
04217
04218
04219 newPointLevel[newPointI] = -1;
04220 }
04221 else
04222 {
04223 newPointLevel[newPointI] = pointLevel_[oldPointI];
04224 }
04225 }
04226 pointLevel_.transfer(newPointLevel);
04227 }
04228
04229
04230
04231 forAllConstIter(Map<label>, pointsToRestore, iter)
04232 {
04233 label newPointI = iter.key();
04234 label storedPointI = iter();
04235
04236 Map<label>::iterator fnd = savedPointLevel_.find(storedPointI);
04237
04238 if (fnd == savedPointLevel_.end())
04239 {
04240 FatalErrorIn("hexRef8::updateMesh(const mapPolyMesh&)")
04241 << "Problem : trying to restore old value for new point "
04242 << newPointI << " but cannot find old point "
04243 << storedPointI
04244 << " in map of stored values " << savedPointLevel_
04245 << abort(FatalError);
04246 }
04247 pointLevel_[newPointI] = fnd();
04248 }
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261 }
04262
04263
04264 if (history_.active())
04265 {
04266 history_.updateMesh(map);
04267 }
04268
04269
04270 setInstance(mesh_.facesInstance());
04271
04272
04273 faceRemover_.updateMesh(map);
04274 }
04275
04276
04277
04278 void Foam::hexRef8::subset
04279 (
04280 const labelList& pointMap,
04281 const labelList& faceMap,
04282 const labelList& cellMap
04283 )
04284 {
04285
04286 if (debug)
04287 {
04288 Pout<< "hexRef8::subset :"
04289 << " Updating various lists"
04290 << endl;
04291 }
04292
04293 if (history_.active())
04294 {
04295 WarningIn
04296 (
04297 "hexRef8::subset(const labelList&, const labelList&"
04298 ", const labelList&)"
04299 ) << "Subsetting will not work in combination with unrefinement."
04300 << nl
04301 << "Proceed at your own risk." << endl;
04302 }
04303
04304
04305
04306 {
04307 labelList newCellLevel(cellMap.size());
04308
04309 forAll(cellMap, newCellI)
04310 {
04311 newCellLevel[newCellI] = cellLevel_[cellMap[newCellI]];
04312 }
04313
04314 cellLevel_.transfer(newCellLevel);
04315
04316 if (findIndex(cellLevel_, -1) != -1)
04317 {
04318 FatalErrorIn("hexRef8::subset(..)")
04319 << "Problem : "
04320 << "cellLevel_ contains illegal value -1 after mapping:"
04321 << cellLevel_
04322 << abort(FatalError);
04323 }
04324 }
04325
04326
04327 {
04328 labelList newPointLevel(pointMap.size());
04329
04330 forAll(pointMap, newPointI)
04331 {
04332 newPointLevel[newPointI] = pointLevel_[pointMap[newPointI]];
04333 }
04334
04335 pointLevel_.transfer(newPointLevel);
04336
04337 if (findIndex(pointLevel_, -1) != -1)
04338 {
04339 FatalErrorIn("hexRef8::subset(..)")
04340 << "Problem : "
04341 << "pointLevel_ contains illegal value -1 after mapping:"
04342 << pointLevel_
04343 << abort(FatalError);
04344 }
04345 }
04346
04347
04348 if (history_.active())
04349 {
04350 history_.subset(pointMap, faceMap, cellMap);
04351 }
04352
04353
04354 setInstance(mesh_.facesInstance());
04355
04356
04357
04358 }
04359
04360
04361
04362 void Foam::hexRef8::distribute(const mapDistributePolyMesh& map)
04363 {
04364 if (debug)
04365 {
04366 Pout<< "hexRef8::distribute :"
04367 << " Updating various lists"
04368 << endl;
04369 }
04370
04371
04372 map.distributeCellData(cellLevel_);
04373
04374 map.distributePointData(pointLevel_);
04375
04376
04377 if (history_.active())
04378 {
04379 history_.distribute(map);
04380 }
04381
04382
04383 faceRemover_.distribute(map);
04384 }
04385
04386
04387 void Foam::hexRef8::checkMesh() const
04388 {
04389 const scalar smallDim = 1E-6 * mesh_.globalData().bb().mag();
04390
04391 if (debug)
04392 {
04393 Pout<< "hexRef8::checkMesh : Using matching tolerance smallDim:"
04394 << smallDim << endl;
04395 }
04396
04397
04398
04399
04400
04401
04402
04403 {
04404 labelList nei(mesh_.nFaces()-mesh_.nInternalFaces());
04405 forAll(nei, i)
04406 {
04407 nei[i] = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
04408 }
04409
04410
04411 syncTools::swapBoundaryFaceList(mesh_, nei, false);
04412
04413 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
04414
04415 forAll(patches, patchI)
04416 {
04417 const polyPatch& pp = patches[patchI];
04418
04419 if (pp.coupled())
04420 {
04421
04422
04423 HashTable<label, labelPair, labelPair::Hash<> >
04424 cellToFace(2*pp.size());
04425
04426 label faceI = pp.start();
04427
04428 forAll(pp, i)
04429 {
04430 label own = mesh_.faceOwner()[faceI];
04431 label bFaceI = faceI-mesh_.nInternalFaces();
04432
04433 if (!cellToFace.insert(labelPair(own, nei[bFaceI]), faceI))
04434 {
04435 dumpCell(own);
04436 FatalErrorIn("hexRef8::checkMesh()")
04437 << "Faces do not seem to be correct across coupled"
04438 << " boundaries" << endl
04439 << "Coupled face " << faceI
04440 << " between owner " << own
04441 << " on patch " << pp.name()
04442 << " and coupled neighbour " << nei[bFaceI]
04443 << " has two faces connected to it:"
04444 << faceI << " and "
04445 << cellToFace[labelPair(own, nei[bFaceI])]
04446 << abort(FatalError);
04447 }
04448
04449 faceI++;
04450 }
04451 }
04452 }
04453 }
04454
04455
04456
04457
04458 {
04459 scalarField neiFaceAreas(mesh_.nFaces()-mesh_.nInternalFaces());
04460 forAll(neiFaceAreas, i)
04461 {
04462 neiFaceAreas[i] = mag(mesh_.faceAreas()[i+mesh_.nInternalFaces()]);
04463 }
04464
04465
04466 syncTools::swapBoundaryFaceList(mesh_, neiFaceAreas, false);
04467
04468 forAll(neiFaceAreas, i)
04469 {
04470 label faceI = i+mesh_.nInternalFaces();
04471
04472 const scalar magArea = mag(mesh_.faceAreas()[faceI]);
04473
04474 if (mag(magArea - neiFaceAreas[i]) > smallDim)
04475 {
04476 const face& f = mesh_.faces()[faceI];
04477 label patchI = mesh_.boundaryMesh().whichPatch(faceI);
04478
04479 dumpCell(mesh_.faceOwner()[faceI]);
04480
04481 FatalErrorIn("hexRef8::checkMesh()")
04482 << "Faces do not seem to be correct across coupled"
04483 << " boundaries" << endl
04484 << "Coupled face " << faceI
04485 << " on patch " << patchI
04486 << " " << mesh_.boundaryMesh()[patchI].name()
04487 << " coords:" << UIndirectList<point>(mesh_.points(), f)()
04488 << " has face area:" << magArea
04489 << " (coupled) neighbour face area differs:"
04490 << neiFaceAreas[i]
04491 << " to within tolerance " << smallDim
04492 << abort(FatalError);
04493 }
04494 }
04495 }
04496
04497
04498
04499
04500 {
04501 labelList nVerts(mesh_.nFaces()-mesh_.nInternalFaces());
04502
04503 forAll(nVerts, i)
04504 {
04505 nVerts[i] = mesh_.faces()[i+mesh_.nInternalFaces()].size();
04506 }
04507
04508
04509 syncTools::swapBoundaryFaceList(mesh_, nVerts, false);
04510
04511 forAll(nVerts, i)
04512 {
04513 label faceI = i+mesh_.nInternalFaces();
04514
04515 const face& f = mesh_.faces()[faceI];
04516
04517 if (f.size() != nVerts[i])
04518 {
04519 dumpCell(mesh_.faceOwner()[faceI]);
04520
04521 label patchI = mesh_.boundaryMesh().whichPatch(faceI);
04522
04523 FatalErrorIn("hexRef8::checkMesh()")
04524 << "Faces do not seem to be correct across coupled"
04525 << " boundaries" << endl
04526 << "Coupled face " << faceI
04527 << " on patch " << patchI
04528 << " " << mesh_.boundaryMesh()[patchI].name()
04529 << " coords:" << UIndirectList<point>(mesh_.points(), f)()
04530 << " has size:" << f.size()
04531 << " (coupled) neighbour face has size:"
04532 << nVerts[i]
04533 << abort(FatalError);
04534 }
04535 }
04536 }
04537
04538
04539
04540
04541 {
04542
04543 pointField anchorPoints(mesh_.nFaces()-mesh_.nInternalFaces());
04544
04545 forAll(anchorPoints, i)
04546 {
04547 label faceI = i+mesh_.nInternalFaces();
04548 const point& fc = mesh_.faceCentres()[faceI];
04549 const face& f = mesh_.faces()[faceI];
04550 const vector anchorVec(mesh_.points()[f[0]] - fc);
04551
04552 anchorPoints[i] = anchorVec;
04553 }
04554
04555
04556
04557
04558 syncTools::swapBoundaryFaceList(mesh_, anchorPoints, false);
04559
04560 forAll(anchorPoints, i)
04561 {
04562 label faceI = i+mesh_.nInternalFaces();
04563 const point& fc = mesh_.faceCentres()[faceI];
04564 const face& f = mesh_.faces()[faceI];
04565 const vector anchorVec(mesh_.points()[f[0]] - fc);
04566
04567 if (mag(anchorVec - anchorPoints[i]) > smallDim)
04568 {
04569 dumpCell(mesh_.faceOwner()[faceI]);
04570
04571 label patchI = mesh_.boundaryMesh().whichPatch(faceI);
04572
04573 FatalErrorIn("hexRef8::checkMesh()")
04574 << "Faces do not seem to be correct across coupled"
04575 << " boundaries" << endl
04576 << "Coupled face " << faceI
04577 << " on patch " << patchI
04578 << " " << mesh_.boundaryMesh()[patchI].name()
04579 << " coords:" << UIndirectList<point>(mesh_.points(), f)()
04580 << " has anchor vector:" << anchorVec
04581 << " (coupled) neighbour face anchor vector differs:"
04582 << anchorPoints[i]
04583 << " to within tolerance " << smallDim
04584 << abort(FatalError);
04585 }
04586 }
04587 }
04588
04589 if (debug)
04590 {
04591 Pout<< "hexRef8::checkMesh : Returning" << endl;
04592 }
04593 }
04594
04595
04596 void Foam::hexRef8::checkRefinementLevels
04597 (
04598 const label maxPointDiff,
04599 const labelList& pointsToCheck
04600 ) const
04601 {
04602 if (debug)
04603 {
04604 Pout<< "hexRef8::checkRefinementLevels :"
04605 << " Checking 2:1 refinement level" << endl;
04606 }
04607
04608 if
04609 (
04610 cellLevel_.size() != mesh_.nCells()
04611 || pointLevel_.size() != mesh_.nPoints()
04612 )
04613 {
04614 FatalErrorIn("hexRef8::checkRefinementLevels(const label)")
04615 << "cellLevel size should be number of cells"
04616 << " and pointLevel size should be number of points."<< nl
04617 << "cellLevel:" << cellLevel_.size()
04618 << " mesh.nCells():" << mesh_.nCells() << nl
04619 << "pointLevel:" << pointLevel_.size()
04620 << " mesh.nPoints():" << mesh_.nPoints()
04621 << abort(FatalError);
04622 }
04623
04624
04625
04626
04627
04628 {
04629
04630 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
04631 {
04632 label own = mesh_.faceOwner()[faceI];
04633 label nei = mesh_.faceNeighbour()[faceI];
04634
04635 if (mag(cellLevel_[own] - cellLevel_[nei]) > 1)
04636 {
04637 dumpCell(own);
04638 dumpCell(nei);
04639
04640 FatalErrorIn
04641 (
04642 "hexRef8::checkRefinementLevels(const label)"
04643 ) << "Celllevel does not satisfy 2:1 constraint." << nl
04644 << "On face " << faceI << " owner cell " << own
04645 << " has refinement " << cellLevel_[own]
04646 << " neighbour cell " << nei << " has refinement "
04647 << cellLevel_[nei]
04648 << abort(FatalError);
04649 }
04650 }
04651
04652
04653 labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
04654
04655 forAll(neiLevel, i)
04656 {
04657 label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
04658
04659 neiLevel[i] = cellLevel_[own];
04660 }
04661
04662
04663 syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
04664
04665 forAll(neiLevel, i)
04666 {
04667 label faceI = i+mesh_.nInternalFaces();
04668
04669 label own = mesh_.faceOwner()[faceI];
04670
04671 if (mag(cellLevel_[own] - neiLevel[i]) > 1)
04672 {
04673 dumpCell(own);
04674
04675 label patchI = mesh_.boundaryMesh().whichPatch(faceI);
04676
04677 FatalErrorIn
04678 (
04679 "hexRef8::checkRefinementLevels(const label)"
04680 ) << "Celllevel does not satisfy 2:1 constraint."
04681 << " On coupled face " << faceI
04682 << " on patch " << patchI << " "
04683 << mesh_.boundaryMesh()[patchI].name()
04684 << " owner cell " << own << " has refinement "
04685 << cellLevel_[own]
04686 << " (coupled) neighbour cell has refinement "
04687 << neiLevel[i]
04688 << abort(FatalError);
04689 }
04690 }
04691 }
04692
04693
04694
04695
04696 {
04697 labelList syncPointLevel(pointLevel_);
04698
04699
04700 syncTools::syncPointList
04701 (
04702 mesh_,
04703 syncPointLevel,
04704 minEqOp<label>(),
04705 labelMax,
04706 false
04707 );
04708
04709
04710 forAll(syncPointLevel, pointI)
04711 {
04712 if (pointLevel_[pointI] != syncPointLevel[pointI])
04713 {
04714 FatalErrorIn
04715 (
04716 "hexRef8::checkRefinementLevels(const label)"
04717 ) << "PointLevel is not consistent across coupled patches."
04718 << endl
04719 << "point:" << pointI << " coord:" << mesh_.points()[pointI]
04720 << " has level " << pointLevel_[pointI]
04721 << " whereas the coupled point has level "
04722 << syncPointLevel[pointI]
04723 << abort(FatalError);
04724 }
04725 }
04726 }
04727
04728
04729
04730 if (maxPointDiff != -1)
04731 {
04732
04733 labelList maxPointLevel(mesh_.nPoints(), 0);
04734
04735 forAll(maxPointLevel, pointI)
04736 {
04737 const labelList& pCells = mesh_.pointCells(pointI);
04738
04739 label& pLevel = maxPointLevel[pointI];
04740
04741 forAll(pCells, i)
04742 {
04743 pLevel = max(pLevel, cellLevel_[pCells[i]]);
04744 }
04745 }
04746
04747
04748 syncTools::syncPointList
04749 (
04750 mesh_,
04751 maxPointLevel,
04752 maxEqOp<label>(),
04753 labelMin,
04754 false
04755 );
04756
04757
04758 forAll(pointsToCheck, i)
04759 {
04760 label pointI = pointsToCheck[i];
04761
04762 const labelList& pCells = mesh_.pointCells(pointI);
04763
04764 forAll(pCells, i)
04765 {
04766 label cellI = pCells[i];
04767
04768 if
04769 (
04770 mag(cellLevel_[cellI]-maxPointLevel[pointI])
04771 > maxPointDiff
04772 )
04773 {
04774 dumpCell(cellI);
04775
04776 FatalErrorIn
04777 (
04778 "hexRef8::checkRefinementLevels(const label)"
04779 ) << "Too big a difference between"
04780 << " point-connected cells." << nl
04781 << "cell:" << cellI
04782 << " cellLevel:" << cellLevel_[cellI]
04783 << " uses point:" << pointI
04784 << " coord:" << mesh_.points()[pointI]
04785 << " which is also used by a cell with level:"
04786 << maxPointLevel[pointI]
04787 << abort(FatalError);
04788 }
04789 }
04790 }
04791 }
04792
04793
04794
04796
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814
04815
04816
04817
04818
04819
04820
04821
04822
04823
04824
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844
04845
04846
04847
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858 }
04859
04860
04861
04862
04863
04864
04865
04866
04867
04868 Foam::labelList Foam::hexRef8::getSplitPoints() const
04869 {
04870 if (debug)
04871 {
04872 checkRefinementLevels(-1, labelList(0));
04873 }
04874
04875 if (debug)
04876 {
04877 Pout<< "hexRef8::getSplitPoints :"
04878 << " Calculating unrefineable points" << endl;
04879 }
04880
04881
04882 if (!history_.active())
04883 {
04884 FatalErrorIn("hexRef8::getSplitPoints()")
04885 << "Only call if constructed with history capability"
04886 << abort(FatalError);
04887 }
04888
04889
04890
04891
04892
04893 labelList splitMaster(mesh_.nPoints(), -1);
04894 labelList splitMasterLevel(mesh_.nPoints(), 0);
04895
04896
04897
04898
04899 for (label pointI = 0; pointI < mesh_.nPoints(); pointI++)
04900 {
04901 const labelList& pCells = mesh_.pointCells(pointI);
04902
04903 if (pCells.size() != 8)
04904 {
04905 splitMaster[pointI] = -2;
04906 }
04907 }
04908
04909
04910 const labelList& visibleCells = history_.visibleCells();
04911
04912 forAll(visibleCells, cellI)
04913 {
04914 const labelList& cPoints = mesh_.cellPoints(cellI);
04915
04916 if (visibleCells[cellI] != -1 && history_.parentIndex(cellI) >= 0)
04917 {
04918 label parentIndex = history_.parentIndex(cellI);
04919
04920
04921 forAll(cPoints, i)
04922 {
04923 label pointI = cPoints[i];
04924
04925 label masterCellI = splitMaster[pointI];
04926
04927 if (masterCellI == -1)
04928 {
04929
04930
04931
04932
04933
04934 splitMaster[pointI] = parentIndex;
04935 splitMasterLevel[pointI] = cellLevel_[cellI] - 1;
04936 }
04937 else if (masterCellI == -2)
04938 {
04939
04940 }
04941 else if
04942 (
04943 (masterCellI != parentIndex)
04944 || (splitMasterLevel[pointI] != cellLevel_[cellI] - 1)
04945 )
04946 {
04947
04948
04949 splitMaster[pointI] = -2;
04950 }
04951 }
04952 }
04953 else
04954 {
04955
04956 forAll(cPoints, i)
04957 {
04958 label pointI = cPoints[i];
04959
04960 splitMaster[pointI] = -2;
04961 }
04962 }
04963 }
04964
04965
04966 for
04967 (
04968 label faceI = mesh_.nInternalFaces();
04969 faceI < mesh_.nFaces();
04970 faceI++
04971 )
04972 {
04973 const face& f = mesh_.faces()[faceI];
04974
04975 forAll(f, fp)
04976 {
04977 splitMaster[f[fp]] = -2;
04978 }
04979 }
04980
04981
04982
04983
04984 label nSplitPoints = 0;
04985
04986 forAll(splitMaster, pointI)
04987 {
04988 if (splitMaster[pointI] >= 0)
04989 {
04990 nSplitPoints++;
04991 }
04992 }
04993
04994 labelList splitPoints(nSplitPoints);
04995 nSplitPoints = 0;
04996
04997 forAll(splitMaster, pointI)
04998 {
04999 if (splitMaster[pointI] >= 0)
05000 {
05001 splitPoints[nSplitPoints++] = pointI;
05002 }
05003 }
05004
05005 return splitPoints;
05006 }
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036
05041
05042
05043
05044
05045
05046
05047
05048
05049
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061
05062
05063
05064
05065
05066
05067
05068
05069
05070
05071 Foam::labelList Foam::hexRef8::consistentUnrefinement
05072 (
05073 const labelList& pointsToUnrefine,
05074 const bool maxSet
05075 ) const
05076 {
05077 if (debug)
05078 {
05079 Pout<< "hexRef8::consistentUnrefinement :"
05080 << " Determining 2:1 consistent unrefinement" << endl;
05081 }
05082
05083 if (maxSet)
05084 {
05085 FatalErrorIn
05086 (
05087 "hexRef8::consistentUnrefinement(const labelList&, const bool"
05088 ) << "maxSet not implemented yet."
05089 << abort(FatalError);
05090 }
05091
05092
05093
05094
05095
05096
05097
05098 PackedBoolList unrefinePoint(mesh_.nPoints());
05099
05100 forAll(pointsToUnrefine, i)
05101 {
05102 label pointI = pointsToUnrefine[i];
05103
05104 unrefinePoint.set(pointI, 1);
05105 }
05106
05107
05108 while (true)
05109 {
05110
05111
05112
05113 PackedBoolList unrefineCell(mesh_.nCells());
05114
05115 forAll(unrefinePoint, pointI)
05116 {
05117 if (unrefinePoint.get(pointI) == 1)
05118 {
05119 const labelList& pCells = mesh_.pointCells(pointI);
05120
05121 forAll(pCells, j)
05122 {
05123 unrefineCell.set(pCells[j], 1);
05124 }
05125 }
05126 }
05127
05128
05129 label nChanged = 0;
05130
05131
05132
05133
05134
05135
05136 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
05137 {
05138 label own = mesh_.faceOwner()[faceI];
05139 label ownLevel = cellLevel_[own] - unrefineCell.get(own);
05140
05141 label nei = mesh_.faceNeighbour()[faceI];
05142 label neiLevel = cellLevel_[nei] - unrefineCell.get(nei);
05143
05144 if (ownLevel < (neiLevel-1))
05145 {
05146
05147
05148
05149 if (maxSet)
05150 {
05151 unrefineCell.set(nei, 1);
05152 }
05153 else
05154 {
05155 if (unrefineCell.get(own) == 0)
05156 {
05157 FatalErrorIn("hexRef8::consistentUnrefinement(..)")
05158 << "problem" << abort(FatalError);
05159 }
05160
05161 unrefineCell.set(own, 0);
05162 }
05163 nChanged++;
05164 }
05165 else if (neiLevel < (ownLevel-1))
05166 {
05167 if (maxSet)
05168 {
05169 unrefineCell.set(own, 1);
05170 }
05171 else
05172 {
05173 if (unrefineCell.get(nei) == 0)
05174 {
05175 FatalErrorIn("hexRef8::consistentUnrefinement(..)")
05176 << "problem" << abort(FatalError);
05177 }
05178
05179 unrefineCell.set(nei, 0);
05180 }
05181 nChanged++;
05182 }
05183 }
05184
05185
05186
05187 labelList neiLevel(mesh_.nFaces()-mesh_.nInternalFaces());
05188
05189 forAll(neiLevel, i)
05190 {
05191 label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
05192
05193 neiLevel[i] = cellLevel_[own] - unrefineCell.get(own);
05194 }
05195
05196
05197 syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
05198
05199 forAll(neiLevel, i)
05200 {
05201 label faceI = i+mesh_.nInternalFaces();
05202 label own = mesh_.faceOwner()[faceI];
05203 label ownLevel = cellLevel_[own] - unrefineCell.get(own);
05204
05205 if (ownLevel < (neiLevel[i]-1))
05206 {
05207 if (!maxSet)
05208 {
05209 if (unrefineCell.get(own) == 0)
05210 {
05211 FatalErrorIn("hexRef8::consistentUnrefinement(..)")
05212 << "problem" << abort(FatalError);
05213 }
05214
05215 unrefineCell.set(own, 0);
05216 nChanged++;
05217 }
05218 }
05219 else if (neiLevel[i] < (ownLevel-1))
05220 {
05221 if (maxSet)
05222 {
05223 if (unrefineCell.get(own) == 1)
05224 {
05225 FatalErrorIn("hexRef8::consistentUnrefinement(..)")
05226 << "problem" << abort(FatalError);
05227 }
05228
05229 unrefineCell.set(own, 1);
05230 nChanged++;
05231 }
05232 }
05233 }
05234
05235 reduce(nChanged, sumOp<label>());
05236
05237 if (debug)
05238 {
05239 Pout<< "hexRef8::consistentUnrefinement :"
05240 << " Changed " << nChanged
05241 << " refinement levels due to 2:1 conflicts."
05242 << endl;
05243 }
05244
05245 if (nChanged == 0)
05246 {
05247 break;
05248 }
05249
05250
05251
05252
05253
05254
05255 forAll(unrefinePoint, pointI)
05256 {
05257 if (unrefinePoint.get(pointI) == 1)
05258 {
05259 const labelList& pCells = mesh_.pointCells(pointI);
05260
05261 forAll(pCells, j)
05262 {
05263 if (unrefineCell.get(pCells[j]) == 0)
05264 {
05265 unrefinePoint.set(pointI, 0);
05266 break;
05267 }
05268 }
05269 }
05270 }
05271 }
05272
05273
05274
05275 label nSet = 0;
05276
05277 forAll(unrefinePoint, pointI)
05278 {
05279 if (unrefinePoint.get(pointI) == 1)
05280 {
05281 nSet++;
05282 }
05283 }
05284
05285 labelList newPointsToUnrefine(nSet);
05286 nSet = 0;
05287
05288 forAll(unrefinePoint, pointI)
05289 {
05290 if (unrefinePoint.get(pointI) == 1)
05291 {
05292 newPointsToUnrefine[nSet++] = pointI;
05293 }
05294 }
05295
05296 return newPointsToUnrefine;
05297 }
05298
05299
05300 void Foam::hexRef8::setUnrefinement
05301 (
05302 const labelList& splitPointLabels,
05303 polyTopoChange& meshMod
05304 )
05305 {
05306 if (!history_.active())
05307 {
05308 FatalErrorIn
05309 (
05310 "hexRef8::setUnrefinement(const labelList&, polyTopoChange&)"
05311 ) << "Only call if constructed with history capability"
05312 << abort(FatalError);
05313 }
05314
05315 if (debug)
05316 {
05317 Pout<< "hexRef8::setUnrefinement :"
05318 << " Checking initial mesh just to make sure" << endl;
05319
05320 checkMesh();
05321
05322 forAll(cellLevel_, cellI)
05323 {
05324 if (cellLevel_[cellI] < 0)
05325 {
05326 FatalErrorIn
05327 (
05328 "hexRef8::setUnrefinement(const labelList&, polyTopoChange&)"
05329 ) << "Illegal cell level " << cellLevel_[cellI]
05330 << " for cell " << cellI
05331 << abort(FatalError);
05332 }
05333 }
05334
05335
05336
05337 pointSet pSet(mesh_, "splitPoints", splitPointLabels);
05338 pSet.write();
05339
05340 cellSet cSet(mesh_, "splitPointCells", splitPointLabels.size());
05341
05342 forAll(splitPointLabels, i)
05343 {
05344 const labelList& pCells = mesh_.pointCells(splitPointLabels[i]);
05345
05346 forAll(pCells, j)
05347 {
05348 cSet.insert(pCells[j]);
05349 }
05350 }
05351 cSet.write();
05352
05353 Pout<< "hexRef8::setRefinement : Dumping " << pSet.size()
05354 << " points and "
05355 << cSet.size() << " cells for unrefinement to" << nl
05356 << " pointSet " << pSet.objectPath() << nl
05357 << " cellSet " << cSet.objectPath()
05358 << endl;
05359 }
05360
05361
05362 labelList cellRegion;
05363 labelList cellRegionMaster;
05364 labelList facesToRemove;
05365
05366 {
05367 labelHashSet splitFaces(12*splitPointLabels.size());
05368
05369 forAll(splitPointLabels, i)
05370 {
05371 const labelList& pFaces = mesh_.pointFaces()[splitPointLabels[i]];
05372
05373 forAll(pFaces, j)
05374 {
05375 splitFaces.insert(pFaces[j]);
05376 }
05377 }
05378
05379
05380
05381 faceRemover_.compatibleRemoves
05382 (
05383 splitFaces.toc(),
05384 cellRegion,
05385 cellRegionMaster,
05386 facesToRemove
05387 );
05388
05389 if (facesToRemove.size() != splitFaces.size())
05390 {
05391 FatalErrorIn
05392 (
05393 "hexRef8::setUnrefinement(const labelList&, polyTopoChange&)"
05394 ) << "Ininitial set of split points to unrefine does not"
05395 << " seem to be consistent or not mid points of refined cells"
05396 << abort(FatalError);
05397 }
05398 }
05399
05400
05401
05402
05403
05404 forAll(splitPointLabels, i)
05405 {
05406 label pointI = splitPointLabels[i];
05407
05408
05409
05410 const labelList& pCells = mesh_.pointCells(pointI);
05411
05412
05413 if (pCells.size() != 8)
05414 {
05415 FatalErrorIn
05416 (
05417 "hexRef8::setUnrefinement(const labelList&, polyTopoChange&)"
05418 ) << "splitPoint " << pointI
05419 << " should have 8 cells using it. It has " << pCells
05420 << abort(FatalError);
05421 }
05422
05423
05424
05425
05426
05427 {
05428 label masterCellI = min(pCells);
05429
05430 forAll(pCells, j)
05431 {
05432 label cellI = pCells[j];
05433
05434 label region = cellRegion[cellI];
05435
05436 if (region == -1)
05437 {
05438 FatalErrorIn("hexRef8::setUnrefinement(..)")
05439 << "Ininitial set of split points to unrefine does not"
05440 << " seem to be consistent or not mid points"
05441 << " of refined cells" << nl
05442 << "cell:" << cellI << " on splitPoint " << pointI
05443 << " has no region to be merged into"
05444 << abort(FatalError);
05445 }
05446
05447 if (masterCellI != cellRegionMaster[region])
05448 {
05449 FatalErrorIn("hexRef8::setUnrefinement(..)")
05450 << "cell:" << cellI << " on splitPoint:" << pointI
05451 << " in region " << region
05452 << " has master:" << cellRegionMaster[region]
05453 << " which is not the lowest numbered cell"
05454 << " among the pointCells:" << pCells
05455 << abort(FatalError);
05456 }
05457 }
05458 }
05459 }
05460
05461
05462
05463 faceRemover_.setRefinement
05464 (
05465 facesToRemove,
05466 cellRegion,
05467 cellRegionMaster,
05468 meshMod
05469 );
05470
05471
05472
05473
05474 forAll(splitPointLabels, i)
05475 {
05476 label pointI = splitPointLabels[i];
05477
05478 const labelList& pCells = mesh_.pointCells(pointI);
05479
05480 label masterCellI = min(pCells);
05481
05482 forAll(pCells, j)
05483 {
05484 cellLevel_[pCells[j]]--;
05485 }
05486
05487 history_.combineCells(masterCellI, pCells);
05488 }
05489
05490
05491 setInstance(mesh_.facesInstance());
05492
05493
05494 }
05495
05496
05497
05498 bool Foam::hexRef8::write() const
05499 {
05500 bool writeOk = cellLevel_.write() && pointLevel_.write();
05501
05502 if (history_.active())
05503 {
05504 writeOk = writeOk && history_.write();
05505 }
05506
05507 return writeOk;
05508 }
05509
05510
05511