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

decomposeMesh.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 InClass
00025     domainDecomposition
00026 
00027 Description
00028     Private member of domainDecomposition.
00029     Decomposes the mesh into bits
00030 
00031 \*---------------------------------------------------------------------------*/
00032 
00033 #include "domainDecomposition.H"
00034 #include <OpenFOAM/IOstreams.H>
00035 #include <OpenFOAM/SLPtrList.H>
00036 #include <OpenFOAM/boolList.H>
00037 #include <OpenFOAM/primitiveMesh.H>
00038 #include <OpenFOAM/cyclicPolyPatch.H>
00039 
00040 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00041 
00042 void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
00043 {
00044     // Decide which cell goes to which processor
00045     distributeCells();
00046 
00047     // Distribute the cells according to the given processor label
00048 
00049     // calculate the addressing information for the original mesh
00050     Info<< "\nCalculating original mesh data" << endl;
00051 
00052     // set references to the original mesh
00053     const polyBoundaryMesh& patches = boundaryMesh();
00054     const faceList& fcs = faces();
00055     const labelList& owner = faceOwner();
00056     const labelList& neighbour = faceNeighbour();
00057 
00058     // loop through the list of processor labels for the cell and add the
00059     // cell shape to the list of cells for the appropriate processor
00060 
00061     Info<< "\nDistributing cells to processors" << endl;
00062 
00063     // Memory management
00064     {
00065         List<SLList<label> > procCellList(nProcs_);
00066 
00067         forAll (cellToProc_, celli)
00068         {
00069             if (cellToProc_[celli] >= nProcs_)
00070             {
00071                 FatalErrorIn("domainDecomposition::decomposeMesh()")
00072                     << "Impossible processor label " << cellToProc_[celli]
00073                     << "for cell " << celli
00074                     << abort(FatalError);
00075             }
00076             else
00077             {
00078                 procCellList[cellToProc_[celli]].append(celli);
00079             }
00080         }
00081 
00082         // Convert linked lists into normal lists
00083         forAll (procCellList, procI)
00084         {
00085             procCellAddressing_[procI] = procCellList[procI];
00086         }
00087     }
00088 
00089     Info << "\nDistributing faces to processors" << endl;
00090 
00091     // Loop through all internal faces and decide which processor they belong to
00092     // First visit all internal faces. If cells at both sides belong to the
00093     // same processor, the face is an internal face. If they are different,
00094     // it belongs to both processors.
00095 
00096     // Memory management
00097     {
00098         List<SLList<label> > procFaceList(nProcs_);
00099 
00100         forAll (neighbour, facei)
00101         {
00102             if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
00103             {
00104                 // Face internal to processor
00105                 procFaceList[cellToProc_[owner[facei]]].append(facei);
00106             }
00107         }
00108 
00109         // Detect inter-processor boundaries
00110 
00111         // Neighbour processor for each subdomain
00112         List<SLList<label> > interProcBoundaries(nProcs_);
00113 
00114         // Face labels belonging to each inter-processor boundary
00115         List<SLList<SLList<label> > > interProcBFaces(nProcs_);
00116 
00117         List<SLList<label> > procPatchIndex(nProcs_);
00118 
00119         forAll (neighbour, facei)
00120         {
00121             if (cellToProc_[owner[facei]] != cellToProc_[neighbour[facei]])
00122             {
00123                 // inter - processor patch face found. Go through the list of
00124                 // inside boundaries for the owner processor and try to find
00125                 // this inter-processor patch.
00126 
00127                 label ownerProc = cellToProc_[owner[facei]];
00128                 label neighbourProc = cellToProc_[neighbour[facei]];
00129 
00130                 SLList<label>::iterator curInterProcBdrsOwnIter =
00131                     interProcBoundaries[ownerProc].begin();
00132 
00133                 SLList<SLList<label> >::iterator curInterProcBFacesOwnIter =
00134                     interProcBFaces[ownerProc].begin();
00135 
00136                 bool interProcBouFound = false;
00137 
00138                 // WARNING: Synchronous SLList iterators
00139 
00140                 for
00141                 (
00142                     ;
00143                     curInterProcBdrsOwnIter
00144                  != interProcBoundaries[ownerProc].end()
00145                  && curInterProcBFacesOwnIter
00146                  != interProcBFaces[ownerProc].end();
00147                     ++curInterProcBdrsOwnIter, ++curInterProcBFacesOwnIter
00148                 )
00149                 {
00150                     if (curInterProcBdrsOwnIter() == neighbourProc)
00151                     {
00152                         // the inter - processor boundary exists. Add the face
00153                         interProcBouFound = true;
00154 
00155                         curInterProcBFacesOwnIter().append(facei);
00156 
00157                         SLList<label>::iterator curInterProcBdrsNeiIter =
00158                             interProcBoundaries[neighbourProc].begin();
00159 
00160                         SLList<SLList<label> >::iterator 
00161                             curInterProcBFacesNeiIter =
00162                             interProcBFaces[neighbourProc].begin();
00163 
00164                         bool neighbourFound = false;
00165 
00166                         // WARNING: Synchronous SLList iterators
00167 
00168                         for
00169                         (
00170                             ;
00171                             curInterProcBdrsNeiIter !=
00172                             interProcBoundaries[neighbourProc].end()
00173                          && curInterProcBFacesNeiIter !=
00174                             interProcBFaces[neighbourProc].end();
00175                             ++curInterProcBdrsNeiIter,
00176                             ++curInterProcBFacesNeiIter
00177                         )
00178                         {
00179                             if (curInterProcBdrsNeiIter() == ownerProc)
00180                             {
00181                                 // boundary found. Add the face
00182                                 neighbourFound = true;
00183 
00184                                 curInterProcBFacesNeiIter().append(facei);
00185                             }
00186 
00187                             if (neighbourFound) break;
00188                         }
00189 
00190                         if (interProcBouFound && !neighbourFound)
00191                         {
00192                             FatalErrorIn("domainDecomposition::decomposeMesh()")
00193                                 << "Inconsistency in inter - "
00194                                 << "processor boundary lists for processors "
00195                                 << ownerProc << " and " << neighbourProc
00196                                 << abort(FatalError);
00197                         }
00198                     }
00199 
00200                     if (interProcBouFound) break;
00201                 }
00202 
00203                 if (!interProcBouFound)
00204                 {
00205                     // inter - processor boundaries do not exist and need to
00206                     // be created
00207 
00208                     // set the new addressing information
00209 
00210                     // owner
00211                     interProcBoundaries[ownerProc].append(neighbourProc);
00212                     interProcBFaces[ownerProc].append(SLList<label>(facei));
00213 
00214                     // neighbour
00215                     interProcBoundaries[neighbourProc].append(ownerProc);
00216                     interProcBFaces[neighbourProc].append(SLList<label>(facei));
00217                 }
00218             }
00219         }
00220 
00221         // Loop through patches. For cyclic boundaries detect inter-processor
00222         // faces; for all other, add faces to the face list and remember start
00223         // and size of all patches.
00224 
00225         // for all processors, set the size of start index and patch size
00226         // lists to the number of patches in the mesh
00227         forAll (procPatchSize_, procI)
00228         {
00229             procPatchSize_[procI].setSize(patches.size());
00230             procPatchStartIndex_[procI].setSize(patches.size());
00231         }
00232 
00233         forAll (patches, patchi)
00234         {
00235             // Reset size and start index for all processors
00236             forAll (procPatchSize_, procI)
00237             {
00238                 procPatchSize_[procI][patchi] = 0;
00239                 procPatchStartIndex_[procI][patchi] =
00240                     procFaceList[procI].size();
00241             }
00242 
00243             const label patchStart = patches[patchi].start();
00244 
00245             if (!isA<cyclicPolyPatch>(patches[patchi]))
00246             {
00247                 // Normal patch. Add faces to processor where the cell
00248                 // next to the face lives
00249 
00250                 const unallocLabelList& patchFaceCells =
00251                     patches[patchi].faceCells();
00252 
00253                 forAll (patchFaceCells, facei)
00254                 {
00255                     const label curProc = cellToProc_[patchFaceCells[facei]];
00256 
00257                     // add the face
00258                     procFaceList[curProc].append(patchStart + facei);
00259 
00260                     // increment the number of faces for this patch
00261                     procPatchSize_[curProc][patchi]++;
00262                 }
00263             }
00264             else
00265             {
00266                 // Cyclic patch special treatment
00267 
00268                 const polyPatch& cPatch = patches[patchi];
00269 
00270                 const label cycOffset = cPatch.size()/2;
00271 
00272                 // Set reference to faceCells for both patches
00273                 const labelList::subList firstFaceCells
00274                 (
00275                     cPatch.faceCells(),
00276                     cycOffset
00277                 );
00278 
00279                 const labelList::subList secondFaceCells
00280                 (
00281                     cPatch.faceCells(),
00282                     cycOffset,
00283                     cycOffset
00284                 );
00285 
00286                 forAll (firstFaceCells, facei)
00287                 {
00288                     if
00289                     (
00290                         cellToProc_[firstFaceCells[facei]]
00291                      != cellToProc_[secondFaceCells[facei]]
00292                     )
00293                     {
00294                         // This face becomes an inter-processor boundary face
00295                         // inter - processor patch face found. Go through
00296                         // the list of inside boundaries for the owner
00297                         // processor and try to find this inter-processor
00298                         // patch.
00299 
00300                         cyclicParallel_ = true;
00301 
00302                         label ownerProc = cellToProc_[firstFaceCells[facei]];
00303                         label neighbourProc =
00304                             cellToProc_[secondFaceCells[facei]];
00305 
00306                         SLList<label>::iterator curInterProcBdrsOwnIter =
00307                             interProcBoundaries[ownerProc].begin();
00308 
00309                         SLList<SLList<label> >::iterator 
00310                             curInterProcBFacesOwnIter =
00311                             interProcBFaces[ownerProc].begin();
00312 
00313                         bool interProcBouFound = false;
00314 
00315                         // WARNING: Synchronous SLList iterators
00316 
00317                         for
00318                         (
00319                             ;
00320                             curInterProcBdrsOwnIter !=
00321                             interProcBoundaries[ownerProc].end()
00322                          && curInterProcBFacesOwnIter !=
00323                             interProcBFaces[ownerProc].end();
00324                             ++curInterProcBdrsOwnIter,
00325                             ++curInterProcBFacesOwnIter
00326                         )
00327                         {
00328                             if (curInterProcBdrsOwnIter() == neighbourProc)
00329                             {
00330                                 // the inter - processor boundary exists.
00331                                 // Add the face
00332                                 interProcBouFound = true;
00333 
00334                                 curInterProcBFacesOwnIter().append
00335                                     (patchStart + facei);
00336 
00337                                 SLList<label>::iterator curInterProcBdrsNeiIter
00338                                    = interProcBoundaries[neighbourProc].begin();
00339 
00340                                 SLList<SLList<label> >::iterator
00341                                     curInterProcBFacesNeiIter =
00342                                     interProcBFaces[neighbourProc].begin();
00343 
00344                                 bool neighbourFound = false;
00345 
00346                                 // WARNING: Synchronous SLList iterators
00347 
00348                                 for
00349                                 (
00350                                     ;
00351                                     curInterProcBdrsNeiIter
00352                                    != interProcBoundaries[neighbourProc].end()
00353                                  && curInterProcBFacesNeiIter
00354                                    != interProcBFaces[neighbourProc].end();
00355                                     ++curInterProcBdrsNeiIter,
00356                                     ++curInterProcBFacesNeiIter
00357                                 )
00358                                 {
00359                                     if (curInterProcBdrsNeiIter() == ownerProc)
00360                                     {
00361                                         // boundary found. Add the face
00362                                         neighbourFound = true;
00363 
00364                                         curInterProcBFacesNeiIter()
00365                                             .append
00366                                             (
00367                                                 patchStart
00368                                               + cycOffset
00369                                               + facei
00370                                             );
00371                                     }
00372 
00373                                     if (neighbourFound) break;
00374                                 }
00375 
00376                                 if (interProcBouFound && !neighbourFound)
00377                                 {
00378                                     FatalErrorIn
00379                                     (
00380                                         "domainDecomposition::decomposeMesh()"
00381                                     )   << "Inconsistency in inter-processor "
00382                                         << "boundary lists for processors "
00383                                         << ownerProc << " and " << neighbourProc
00384                                         << " in cyclic boundary matching"
00385                                         << abort(FatalError);
00386                                 }
00387                             }
00388 
00389                             if (interProcBouFound) break;
00390                         }
00391 
00392                         if (!interProcBouFound)
00393                         {
00394                             // inter - processor boundaries do not exist
00395                             // and need to be created
00396 
00397                             // set the new addressing information
00398 
00399                             // owner
00400                             interProcBoundaries[ownerProc]
00401                                 .append(neighbourProc);
00402                             interProcBFaces[ownerProc]
00403                                 .append(SLList<label>(patchStart + facei));
00404 
00405                             // neighbour
00406                             interProcBoundaries[neighbourProc]
00407                                 .append(ownerProc);
00408                             interProcBFaces[neighbourProc]
00409                                 .append
00410                                 (
00411                                     SLList<label>
00412                                     (
00413                                         patchStart
00414                                       + cycOffset
00415                                       + facei
00416                                     )
00417                                 );
00418                         }
00419                     }
00420                     else
00421                     {
00422                         // This cyclic face remains on the processor
00423                         label ownerProc = cellToProc_[firstFaceCells[facei]];
00424 
00425                         // add the face
00426                         procFaceList[ownerProc].append(patchStart + facei);
00427 
00428                         // increment the number of faces for this patch
00429                         procPatchSize_[ownerProc][patchi]++;
00430 
00431                         // Note: I cannot add the other side of the cyclic
00432                         // boundary here because this would violate the order.
00433                         // They will be added in a separate loop below
00434                         // 
00435                     }
00436                 }
00437 
00438                 // Ordering in cyclic boundaries is important.
00439                 // Add the other half of cyclic faces for cyclic boundaries
00440                 // that remain on the processor
00441                 forAll (secondFaceCells, facei)
00442                 {
00443                     if
00444                     (
00445                         cellToProc_[firstFaceCells[facei]]
00446                      == cellToProc_[secondFaceCells[facei]]
00447                     )
00448                     {
00449                         // This cyclic face remains on the processor
00450                         label ownerProc = cellToProc_[firstFaceCells[facei]];
00451 
00452                         // add the second face
00453                         procFaceList[ownerProc].append
00454                             (patchStart + cycOffset + facei);
00455 
00456                         // increment the number of faces for this patch
00457                         procPatchSize_[ownerProc][patchi]++;
00458                     }
00459                 }
00460             }
00461         }
00462 
00463         // Convert linked lists into normal lists
00464         // Add inter-processor boundaries and remember start indices
00465         forAll (procFaceList, procI)
00466         {
00467             // Get internal and regular boundary processor faces
00468             SLList<label>& curProcFaces = procFaceList[procI];
00469 
00470             // Get reference to processor face addressing
00471             labelList& curProcFaceAddressing = procFaceAddressing_[procI];
00472 
00473             labelList& curProcNeighbourProcessors =
00474                 procNeighbourProcessors_[procI];
00475 
00476             labelList& curProcProcessorPatchSize =
00477                 procProcessorPatchSize_[procI];
00478 
00479             labelList& curProcProcessorPatchStartIndex =
00480                 procProcessorPatchStartIndex_[procI];
00481 
00482             // calculate the size
00483             label nFacesOnProcessor = curProcFaces.size();
00484 
00485             for 
00486             (
00487                 SLList<SLList<label> >::iterator curInterProcBFacesIter =
00488                     interProcBFaces[procI].begin();
00489                 curInterProcBFacesIter != interProcBFaces[procI].end();
00490                 ++curInterProcBFacesIter
00491             )
00492             {
00493                 nFacesOnProcessor += curInterProcBFacesIter().size();
00494             }
00495 
00496             curProcFaceAddressing.setSize(nFacesOnProcessor);
00497 
00498             // Fill in the list. Calculate turning index.
00499             // Turning index will be -1 only for some faces on processor
00500             // boundaries, i.e. the ones where the current processor ID
00501             // is in the cell which is a face neighbour.
00502             // Turning index is stored as the sign of the face addressing list
00503 
00504             label nFaces = 0;
00505 
00506             // Add internal and boundary faces
00507             // Remember to increment the index by one such that the
00508             // turning index works properly.  
00509             for
00510             (
00511                 SLList<label>::iterator curProcFacesIter = curProcFaces.begin();
00512                 curProcFacesIter != curProcFaces.end();
00513                 ++curProcFacesIter
00514             )
00515             {
00516                 curProcFaceAddressing[nFaces] = curProcFacesIter() + 1;
00517                 nFaces++;
00518             }
00519 
00520             // Add inter-processor boundary faces. At the beginning of each
00521             // patch, grab the patch start index and size
00522 
00523             curProcNeighbourProcessors.setSize
00524             (
00525                 interProcBoundaries[procI].size()
00526             );
00527 
00528             curProcProcessorPatchSize.setSize
00529             (
00530                 interProcBoundaries[procI].size()
00531             );
00532 
00533             curProcProcessorPatchStartIndex.setSize
00534             (
00535                 interProcBoundaries[procI].size()
00536             );
00537 
00538             label nProcPatches = 0;
00539 
00540             SLList<label>::iterator curInterProcBdrsIter =
00541                 interProcBoundaries[procI].begin();
00542 
00543             SLList<SLList<label> >::iterator curInterProcBFacesIter =
00544                 interProcBFaces[procI].begin();
00545 
00546             for
00547             (
00548                 ;
00549                 curInterProcBdrsIter != interProcBoundaries[procI].end()
00550              && curInterProcBFacesIter != interProcBFaces[procI].end();
00551                 ++curInterProcBdrsIter, ++curInterProcBFacesIter
00552             )
00553             {
00554                 curProcNeighbourProcessors[nProcPatches] =
00555                     curInterProcBdrsIter();
00556 
00557                 // Get start index for processor patch
00558                 curProcProcessorPatchStartIndex[nProcPatches] = nFaces;
00559 
00560                 label& curSize =
00561                     curProcProcessorPatchSize[nProcPatches];
00562 
00563                 curSize = 0;
00564 
00565                 // add faces for this processor boundary
00566 
00567                 for
00568                 (
00569                     SLList<label>::iterator curFacesIter =
00570                         curInterProcBFacesIter().begin();
00571                     curFacesIter != curInterProcBFacesIter().end();
00572                     ++curFacesIter
00573                 )
00574                 {
00575                     // add the face
00576 
00577                     // Remember to increment the index by one such that the
00578                     // turning index works properly.  
00579                     if (cellToProc_[owner[curFacesIter()]] == procI)
00580                     {
00581                         curProcFaceAddressing[nFaces] = curFacesIter() + 1;
00582                     }
00583                     else
00584                     {
00585                         // turning face
00586                         curProcFaceAddressing[nFaces] = -(curFacesIter() + 1);
00587                     }
00588 
00589                     // increment the size
00590                     curSize++;
00591 
00592                     nFaces++;
00593                 }
00594 
00595                 nProcPatches++;
00596             }
00597         }
00598     }
00599 
00600     Info << "\nCalculating processor boundary addressing" << endl;
00601     // For every patch of processor boundary, find the index of the original
00602     // patch. Mis-alignment is caused by the fact that patches with zero size
00603     // are omitted. For processor patches, set index to -1.
00604     // At the same time, filter the procPatchSize_ and procPatchStartIndex_
00605     // lists to exclude zero-size patches
00606     forAll (procPatchSize_, procI)
00607     {
00608         // Make a local copy of old lists
00609         const labelList oldPatchSizes = procPatchSize_[procI];
00610 
00611         const labelList oldPatchStarts = procPatchStartIndex_[procI];
00612 
00613         labelList& curPatchSizes = procPatchSize_[procI];
00614 
00615         labelList& curPatchStarts = procPatchStartIndex_[procI];
00616 
00617         const labelList& curProcessorPatchSizes =
00618             procProcessorPatchSize_[procI];
00619 
00620         labelList& curBoundaryAddressing = procBoundaryAddressing_[procI];
00621 
00622         curBoundaryAddressing.setSize
00623         (
00624             oldPatchSizes.size()
00625           + curProcessorPatchSizes.size()
00626         );
00627 
00628         label nPatches = 0;
00629 
00630         forAll (oldPatchSizes, patchi)
00631         {
00632             if (!filterEmptyPatches || oldPatchSizes[patchi] > 0)
00633             {
00634                 curBoundaryAddressing[nPatches] = patchi;
00635 
00636                 curPatchSizes[nPatches] = oldPatchSizes[patchi];
00637 
00638                 curPatchStarts[nPatches] = oldPatchStarts[patchi];
00639 
00640                 nPatches++;
00641             }
00642         }
00643 
00644         // reset to the size of live patches
00645         curPatchSizes.setSize(nPatches);
00646         curPatchStarts.setSize(nPatches);
00647 
00648         forAll (curProcessorPatchSizes, procPatchI)
00649         {
00650             curBoundaryAddressing[nPatches] = -1;
00651 
00652             nPatches++;
00653         }
00654 
00655         curBoundaryAddressing.setSize(nPatches);
00656     }
00657 
00658     Info << "\nDistributing points to processors" << endl;
00659     // For every processor, loop through the list of faces for the processor.
00660     // For every face, loop through the list of points and mark the point as
00661     // used for the processor. Collect the list of used points for the
00662     // processor.
00663 
00664     forAll (procPointAddressing_, procI)
00665     {
00666         boolList pointLabels(nPoints(), false);
00667 
00668         // Get reference to list of used faces
00669         const labelList& procFaceLabels = procFaceAddressing_[procI];
00670 
00671         forAll (procFaceLabels, facei)
00672         {
00673             // Because of the turning index, some labels may be negative
00674             const labelList& facePoints = fcs[mag(procFaceLabels[facei]) - 1];
00675 
00676             forAll (facePoints, pointi)
00677             {
00678                 // Mark the point as used
00679                 pointLabels[facePoints[pointi]] = true;
00680             }
00681         }
00682 
00683         // Collect the used points
00684         labelList& procPointLabels = procPointAddressing_[procI];
00685 
00686         procPointLabels.setSize(pointLabels.size());
00687 
00688         label nUsedPoints = 0;
00689 
00690         forAll (pointLabels, pointi)
00691         {
00692             if (pointLabels[pointi])
00693             {
00694                 procPointLabels[nUsedPoints] = pointi;
00695 
00696                 nUsedPoints++;
00697             }
00698         }
00699 
00700         // Reset the size of used points
00701         procPointLabels.setSize(nUsedPoints);
00702     }
00703 
00704     // Gather data about globally shared points
00705 
00706     // Memory management
00707     {
00708         labelList pointsUsage(nPoints(), 0);
00709 
00710         // Globally shared points are the ones used by more than 2 processors
00711         // Size the list approximately and gather the points
00712         labelHashSet gSharedPoints
00713         (
00714             min(100, nPoints()/1000)
00715         );
00716 
00717         // Loop through all the processors and mark up points used by
00718         // processor boundaries.  When a point is used twice, it is a
00719         // globally shared point
00720 
00721         for (label procI = 0; procI < nProcs_; procI++)
00722         {
00723             // Get list of face labels
00724             const labelList& curFaceLabels = procFaceAddressing_[procI];
00725 
00726             // Get start of processor faces
00727             const labelList& curProcessorPatchStarts =
00728                 procProcessorPatchStartIndex_[procI];
00729 
00730             const labelList& curProcessorPatchSizes =
00731                 procProcessorPatchSize_[procI];
00732 
00733             // Reset the lookup list
00734             pointsUsage = 0;
00735 
00736             forAll (curProcessorPatchStarts, patchi)
00737             {
00738                 const label curStart = curProcessorPatchStarts[patchi];
00739                 const label curEnd = curStart + curProcessorPatchSizes[patchi];
00740 
00741                 for
00742                 (
00743                     label facei = curStart;
00744                     facei < curEnd;
00745                     facei++
00746                 )
00747                 {
00748                     // Mark the original face as used
00749                     // Remember to decrement the index by one (turning index)
00750                     // 
00751                     const label curF = mag(curFaceLabels[facei]) - 1;
00752 
00753                     const face& f = fcs[curF];
00754 
00755                     forAll (f, pointi)
00756                     {
00757                         if (pointsUsage[f[pointi]] == 0)
00758                         {
00759                             // Point not previously used
00760                             pointsUsage[f[pointi]] = patchi + 1;
00761                         }
00762                         else if (pointsUsage[f[pointi]] != patchi + 1)
00763                         {
00764                             // Point used by some other patch = global point!
00765                             gSharedPoints.insert(f[pointi]);
00766                         }
00767                     }
00768                 }
00769             }
00770         }
00771 
00772         // Grab the result from the hash list
00773         globallySharedPoints_ = gSharedPoints.toc();
00774         sort(globallySharedPoints_);
00775     }
00776 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines