FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

createMergeList.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "blockMesh.H"
00027 
00028 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00029 
00030 Foam::labelList Foam::blockMesh::createMergeList()
00031 {
00032     Info<< nl << "Creating merge list " << flush;
00033 
00034     labelList MergeList(nPoints_, -1);
00035 
00036     blockMesh& blocks = *this;
00037 
00038     const pointField& blockPoints = topology().points();
00039     const cellList& blockCells = topology().cells();
00040     const faceList& blockFaces = topology().faces();
00041     const labelList& faceOwnerBlocks = topology().faceOwner();
00042 
00043     // For efficiency, create merge pairs in the first pass
00044     labelListListList glueMergePairs(blockFaces.size());
00045 
00046     const labelList& faceNeighbourBlocks = topology().faceNeighbour();
00047 
00048     forAll(blockFaces, blockFaceLabel)
00049     {
00050         label blockPlabel = faceOwnerBlocks[blockFaceLabel];
00051         const pointField& blockPpoints = blocks[blockPlabel].points();
00052         const labelList& blockPfaces = blockCells[blockPlabel];
00053 
00054         bool foundFace = false;
00055         label blockPfaceLabel;
00056         for
00057         (
00058             blockPfaceLabel = 0;
00059             blockPfaceLabel < blockPfaces.size();
00060             blockPfaceLabel++
00061         )
00062         {
00063             if
00064             (
00065                 blockFaces[blockPfaces[blockPfaceLabel]]
00066              == blockFaces[blockFaceLabel]
00067             )
00068             {
00069                 foundFace = true;
00070                 break;
00071             }
00072         }
00073 
00074         if (!foundFace)
00075         {
00076             FatalErrorIn("blockMesh::createMergeList()")
00077                 << "Cannot find merge face for block " << blockPlabel
00078                 << exit(FatalError);
00079         };
00080 
00081         const labelListList& blockPfaceFaces =
00082             blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
00083 
00084         labelListList& curPairs = glueMergePairs[blockFaceLabel];
00085         curPairs.setSize(blockPfaceFaces.size());
00086 
00087         // Calculate sqr of the merge tolerance as 1/10th of the min sqr
00088         // point to point distance on the block face.
00089         // At the same time merge collated points on the block's faces
00090         // (removes boundary poles etc.)
00091         // Co-located points detected by initally taking a constant factor of
00092         // the size of the block face:
00093         boundBox bb(blockFaces[blockFaceLabel].points(blockPoints));
00094         const scalar mergeSqrDist =
00095             SMALL*magSqr(bb.span())/blockPfaceFaces.size();
00096         scalar sqrMergeTol = GREAT;
00097 
00098         // This is an N^2 algorithm
00099         forAll(blockPfaceFaces, blockPfaceFaceLabel)
00100         {
00101             const labelList& blockPfaceFacePoints
00102                 = blockPfaceFaces[blockPfaceFaceLabel];
00103 
00104             forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
00105             {
00106                 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel2)
00107                 {
00108                     if (blockPfaceFacePointLabel != blockPfaceFacePointLabel2)
00109                     {
00110                         scalar magSqrDist = magSqr
00111                         (
00112                             blockPpoints[blockPfaceFacePoints
00113                             [blockPfaceFacePointLabel]]
00114                             - blockPpoints[blockPfaceFacePoints
00115                             [blockPfaceFacePointLabel2]]
00116                         );
00117 
00118                         if (magSqrDist < mergeSqrDist)
00119                         {
00120                             label PpointLabel =
00121                                 blockPfaceFacePoints[blockPfaceFacePointLabel]
00122                               + blockOffsets_[blockPlabel];
00123 
00124                             label PpointLabel2 =
00125                                 blockPfaceFacePoints[blockPfaceFacePointLabel2]
00126                               + blockOffsets_[blockPlabel];
00127 
00128                             label minPP2 = min(PpointLabel, PpointLabel2);
00129 
00130                             if (MergeList[PpointLabel] != -1)
00131                             {
00132                                 minPP2 = min(minPP2, MergeList[PpointLabel]);
00133                             }
00134 
00135                             if (MergeList[PpointLabel2] != -1)
00136                             {
00137                                 minPP2 = min(minPP2, MergeList[PpointLabel2]);
00138                             }
00139 
00140                             MergeList[PpointLabel] = MergeList[PpointLabel2]
00141                                 = minPP2;
00142                         }
00143                         else
00144                         {
00145                             sqrMergeTol = min(sqrMergeTol, magSqrDist);
00146                         }
00147                     }
00148                 }
00149             }
00150         }
00151 
00152         sqrMergeTol /= 10.0;
00153 
00154 
00155         if (topology().isInternalFace(blockFaceLabel))
00156         {
00157             label blockNlabel = faceNeighbourBlocks[blockFaceLabel];
00158             const pointField& blockNpoints = blocks[blockNlabel].points();
00159             const labelList& blockNfaces = blockCells[blockNlabel];
00160 
00161             foundFace = false;
00162             label blockNfaceLabel;
00163             for
00164             (
00165                 blockNfaceLabel = 0;
00166                 blockNfaceLabel < blockNfaces.size();
00167                 blockNfaceLabel++
00168             )
00169             {
00170                 if
00171                 (
00172                     blockFaces[blockNfaces[blockNfaceLabel]]
00173                  == blockFaces[blockFaceLabel]
00174                 )
00175                 {
00176                     foundFace = true;
00177                     break;
00178                 }
00179             }
00180 
00181             if (!foundFace)
00182             {
00183                 FatalErrorIn("blockMesh::createMergeList()")
00184                 << "Cannot find merge face for block " << blockNlabel
00185                     << exit(FatalError);
00186             };
00187 
00188             const labelListList& blockNfaceFaces =
00189             blocks[blockNlabel].boundaryPatches()[blockNfaceLabel];
00190 
00191             if (blockPfaceFaces.size() != blockNfaceFaces.size())
00192             {
00193                 FatalErrorIn("blockMesh::createMergeList()")
00194                 << "Inconsistent number of faces between block pair "
00195                     << blockPlabel << " and " << blockNlabel
00196                     << exit(FatalError);
00197             }
00198 
00199 
00200             bool found = false;
00201 
00202             // N-squared point search over all points of all faces of
00203             // master block over all point of all faces of slave block
00204             forAll(blockPfaceFaces, blockPfaceFaceLabel)
00205             {
00206                 const labelList& blockPfaceFacePoints =
00207                     blockPfaceFaces[blockPfaceFaceLabel];
00208 
00209                 labelList& cp = curPairs[blockPfaceFaceLabel];
00210                 cp.setSize(blockPfaceFacePoints.size());
00211                 cp = -1;
00212 
00213                 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
00214                 {
00215                     found = false;
00216 
00217                     forAll(blockNfaceFaces, blockNfaceFaceLabel)
00218                     {
00219                         const labelList& blockNfaceFacePoints
00220                         = blockNfaceFaces[blockNfaceFaceLabel];
00221 
00222                         forAll(blockNfaceFacePoints, blockNfaceFacePointLabel)
00223                         {
00224                             if
00225                             (
00226                                 magSqr
00227                                 (
00228                                     blockPpoints
00229                                     [
00230                                         blockPfaceFacePoints
00231                                         [blockPfaceFacePointLabel]
00232                                     ]
00233                                     - blockNpoints
00234                                     [
00235                                         blockNfaceFacePoints
00236                                         [blockNfaceFacePointLabel]
00237                                     ]
00238                                 ) < sqrMergeTol
00239                             )
00240                             {
00241                                 // Found a new pair
00242                                 found = true;
00243 
00244                                 cp[blockPfaceFacePointLabel] =
00245                                 blockNfaceFacePoints[blockNfaceFacePointLabel];
00246 
00247                                 label PpointLabel =
00248                                     blockPfaceFacePoints
00249                                     [
00250                                         blockPfaceFacePointLabel
00251                                     ]
00252                                   + blockOffsets_[blockPlabel];
00253 
00254                                 label NpointLabel =
00255                                     blockNfaceFacePoints
00256                                     [
00257                                         blockNfaceFacePointLabel
00258                                     ]
00259                                   + blockOffsets_[blockNlabel];
00260 
00261                                 label minPN = min(PpointLabel, NpointLabel);
00262 
00263                                 if (MergeList[PpointLabel] != -1)
00264                                 {
00265                                     minPN = min(minPN, MergeList[PpointLabel]);
00266                                 }
00267 
00268                                 if (MergeList[NpointLabel] != -1)
00269                                 {
00270                                     minPN = min(minPN, MergeList[NpointLabel]);
00271                                 }
00272 
00273                                 MergeList[PpointLabel] =
00274                                 MergeList[NpointLabel] =
00275                                 minPN;
00276                             }
00277                         }
00278                     }
00279                 }
00280                 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
00281                 {
00282                     if (cp[blockPfaceFacePointLabel] == -1)
00283                     {
00284                         FatalErrorIn("blockMesh::createMergeList()")
00285                             << "Inconsistent point locations between blocks "
00286                             << blockPlabel << " and " << blockNlabel << nl
00287                             << "    probably due to inconsistent grading."
00288                             << exit(FatalError);
00289                     }
00290                 }
00291             }
00292         }
00293     }
00294 
00295 
00296     const faceList::subList blockInternalFaces
00297     (
00298         blockFaces,
00299         topology().nInternalFaces()
00300     );
00301 
00302     bool changedPointMerge = false;
00303     label nPasses = 0;
00304 
00305     do
00306     {
00307         changedPointMerge = false;
00308         nPasses++;
00309 
00310         forAll(blockInternalFaces, blockFaceLabel)
00311         {
00312             label blockPlabel = faceOwnerBlocks[blockFaceLabel];
00313             label blockNlabel = faceNeighbourBlocks[blockFaceLabel];
00314 
00315             const labelList& blockPfaces = blockCells[blockPlabel];
00316             const labelList& blockNfaces = blockCells[blockNlabel];
00317 
00318             const labelListList& curPairs = glueMergePairs[blockFaceLabel];
00319 
00320             bool foundFace = false;
00321             label blockPfaceLabel;
00322             for
00323             (
00324                 blockPfaceLabel = 0;
00325                 blockPfaceLabel < blockPfaces.size();
00326                 blockPfaceLabel++
00327             )
00328             {
00329                 if
00330                 (
00331                     blockFaces[blockPfaces[blockPfaceLabel]]
00332                  == blockInternalFaces[blockFaceLabel]
00333                 )
00334                 {
00335                     foundFace = true;
00336                     break;
00337                 }
00338             }
00339 
00340             foundFace = false;
00341             label blockNfaceLabel;
00342             for
00343             (
00344                 blockNfaceLabel = 0;
00345                 blockNfaceLabel < blockNfaces.size();
00346                 blockNfaceLabel++
00347             )
00348             {
00349                 if
00350                 (
00351                     blockFaces[blockNfaces[blockNfaceLabel]]
00352                  == blockInternalFaces[blockFaceLabel]
00353                 )
00354                 {
00355                     foundFace = true;
00356                     break;
00357                 }
00358             }
00359 
00360             const labelListList& blockPfaceFaces =
00361                 blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
00362 
00363             forAll(blockPfaceFaces, blockPfaceFaceLabel)
00364             {
00365                 const labelList& blockPfaceFacePoints
00366                     = blockPfaceFaces[blockPfaceFaceLabel];
00367 
00368                 const labelList& cp = curPairs[blockPfaceFaceLabel];
00369 
00370                 forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
00371                 {
00372                     label PpointLabel =
00373                         blockPfaceFacePoints[blockPfaceFacePointLabel]
00374                       + blockOffsets_[blockPlabel];
00375 
00376                     label NpointLabel =
00377                         cp[blockPfaceFacePointLabel]
00378                       + blockOffsets_[blockNlabel];
00379 
00380                     if
00381                     (
00382                         MergeList[PpointLabel]
00383                      != MergeList[NpointLabel]
00384                     )
00385                     {
00386                         changedPointMerge = true;
00387 
00388                         MergeList[PpointLabel]
00389                       = MergeList[NpointLabel]
00390                       = min
00391                         (
00392                             MergeList[PpointLabel],
00393                             MergeList[NpointLabel]
00394                         );
00395                     }
00396                 }
00397             }
00398         }
00399         Info << "." << flush;
00400 
00401         if (nPasses > 100)
00402         {
00403             FatalErrorIn("blockMesh::createMergeList()")
00404                 << "Point merging failed after max number of passes."
00405                 << abort(FatalError);
00406         }
00407     }
00408     while (changedPointMerge);
00409     Info << endl;
00410 
00411     forAll(blockInternalFaces, blockFaceLabel)
00412     {
00413         label blockPlabel = faceOwnerBlocks[blockFaceLabel];
00414         label blockNlabel = faceNeighbourBlocks[blockFaceLabel];
00415 
00416         const labelList& blockPfaces = blockCells[blockPlabel];
00417         const labelList& blockNfaces = blockCells[blockNlabel];
00418 
00419         const pointField& blockPpoints = blocks[blockPlabel].points();
00420         const pointField& blockNpoints = blocks[blockNlabel].points();
00421 
00422         bool foundFace = false;
00423         label blockPfaceLabel;
00424         for
00425         (
00426             blockPfaceLabel = 0;
00427             blockPfaceLabel < blockPfaces.size();
00428             blockPfaceLabel++
00429         )
00430         {
00431             if
00432             (
00433                 blockFaces[blockPfaces[blockPfaceLabel]]
00434              == blockInternalFaces[blockFaceLabel]
00435             )
00436             {
00437                 foundFace = true;
00438                 break;
00439             }
00440         }
00441 
00442         if (!foundFace)
00443         {
00444             FatalErrorIn("blockMesh::createMergeList()")
00445                 << "Cannot find merge face for block " << blockPlabel
00446                 << exit(FatalError);
00447         };
00448 
00449         foundFace = false;
00450         label blockNfaceLabel;
00451         for
00452         (
00453             blockNfaceLabel = 0;
00454             blockNfaceLabel < blockNfaces.size();
00455             blockNfaceLabel++
00456         )
00457         {
00458             if
00459             (
00460                 blockFaces[blockNfaces[blockNfaceLabel]]
00461              == blockInternalFaces[blockFaceLabel]
00462             )
00463             {
00464                 foundFace = true;
00465                 break;
00466             }
00467         }
00468 
00469         if (!foundFace)
00470         {
00471             FatalErrorIn("blockMesh::createMergeList()")
00472                 << "Cannot find merge face for block " << blockNlabel
00473                 << exit(FatalError);
00474         };
00475 
00476         const labelListList& blockPfaceFaces =
00477             blocks[blockPlabel].boundaryPatches()[blockPfaceLabel];
00478 
00479         const labelListList& blockNfaceFaces =
00480             blocks[blockNlabel].boundaryPatches()[blockNfaceLabel];
00481 
00482         forAll(blockPfaceFaces, blockPfaceFaceLabel)
00483         {
00484             const labelList& blockPfaceFacePoints
00485                 = blockPfaceFaces[blockPfaceFaceLabel];
00486 
00487             forAll(blockPfaceFacePoints, blockPfaceFacePointLabel)
00488             {
00489                 label PpointLabel =
00490                     blockPfaceFacePoints[blockPfaceFacePointLabel]
00491                   + blockOffsets_[blockPlabel];
00492 
00493                 if (MergeList[PpointLabel] == -1)
00494                 {
00495                     FatalErrorIn("blockMesh::createMergeList()")
00496                         << "Unable to merge point "
00497                         << blockPfaceFacePointLabel
00498                         << ' ' << blockPpoints[blockPfaceFacePointLabel]
00499                         << " of face "
00500                         << blockPfaceLabel
00501                         << " of block "
00502                         << blockPlabel
00503                         << exit(FatalError);
00504                 }
00505             }
00506         }
00507 
00508         forAll(blockNfaceFaces, blockNfaceFaceLabel)
00509         {
00510             const labelList& blockNfaceFacePoints
00511                 = blockNfaceFaces[blockNfaceFaceLabel];
00512 
00513             forAll(blockNfaceFacePoints, blockNfaceFacePointLabel)
00514             {
00515                 label NpointLabel =
00516                     blockNfaceFacePoints[blockNfaceFacePointLabel]
00517                   + blockOffsets_[blockNlabel];
00518 
00519                 if (MergeList[NpointLabel] == -1)
00520                 {
00521                     FatalErrorIn("blockMesh::createMergeList()")
00522                         << "unable to merge point "
00523                         << blockNfaceFacePointLabel
00524                         << ' ' << blockNpoints[blockNfaceFacePointLabel]
00525                         << " of face "
00526                         << blockNfaceLabel
00527                         << " of block "
00528                         << blockNlabel
00529                         << exit(FatalError);
00530                 }
00531             }
00532         }
00533     }
00534 
00535 
00536     // sort merge list to return new point label (in new shorter list)
00537     // given old point label
00538     label newPointLabel = 0;
00539 
00540     forAll(MergeList, pointLabel)
00541     {
00542         if (MergeList[pointLabel] > pointLabel)
00543         {
00544             FatalErrorIn("blockMesh::createMergeList()")
00545                 << "ouch" << exit(FatalError);
00546         }
00547 
00548         if
00549         (
00550             (MergeList[pointLabel] == -1)
00551          || MergeList[pointLabel] == pointLabel
00552         )
00553         {
00554             MergeList[pointLabel] = newPointLabel;
00555             newPointLabel++;
00556         }
00557         else
00558         {
00559             MergeList[pointLabel] = MergeList[MergeList[pointLabel]];
00560         }
00561     }
00562 
00563     nPoints_ = newPointLabel;
00564 
00565 
00566     return MergeList;
00567 }
00568 
00569 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines