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