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

referredCellList.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) 2008-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 "referredCellList.H"
00027 #include <molecule/interactionLists.H>
00028 #include <OpenFOAM/polyBoundaryMeshEntries.H>
00029 #include <OpenFOAM/PstreamCombineReduceOps.H>
00030 #include <OpenFOAM/Time.H>
00031 #include <OpenFOAM/globalMeshData.H>
00032 #include <OpenFOAM/processorPolyPatch.H>
00033 #include <OpenFOAM/cyclicPolyPatch.H>
00034 
00035 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00036 
00037 void Foam::referredCellList::buildReferredCellList
00038 (
00039     bool pointPointListBuild
00040 )
00041 {
00042     Info << nl << "Building list of referred interaction neighbours" << endl;
00043 
00044     const polyMesh& mesh(il_.mesh());
00045 
00046     DynamicList<referredCell> referredInteractionList;
00047 
00048     // realCellsWithinRCutMaxOfAnyReferringPatch
00049     DynamicList<label> rCellsWRRP;
00050 
00051     // realFacesWithinRCutMaxOfAnyReferringPatch
00052     DynamicList<label> rFacesWRRP;
00053 
00054     // realEdgesWithinRCutMaxOfAnyReferringPatch
00055     DynamicList<label> rEdgesWRRP;
00056 
00057     // realPointsWithinRCutMaxOfAnyReferringPatch
00058     DynamicList<label> rPointsWRRP;
00059 
00060     labelListList processorPatchSegmentMapping
00061     (
00062         mesh.globalData().processorPatches().size()
00063     );
00064 
00065     List<vectorList> allNeighbourFaceCentres
00066     (
00067         mesh.globalData().processorPatches().size()
00068     );
00069 
00070     List<vectorList> allNeighbourFaceAreas
00071     (
00072         mesh.globalData().processorPatches().size()
00073     );
00074 
00075     label nUndecomposedPatches = 0;
00076 
00077     if (Pstream::parRun())
00078     {
00079         dictionary patchDictionary;
00080 
00081         DynamicList<word> patchNames;
00082 
00083         Time undecomposedTime
00084         (
00085             Time::controlDictName,
00086             mesh.time().rootPath(),
00087             mesh.time().caseName().path()
00088         );
00089 
00090         IOobject undecomposedBoundaryHeader
00091         (
00092             "boundary",
00093             undecomposedTime.constant(),
00094             polyMesh::meshSubDir,
00095             undecomposedTime,
00096             IOobject::MUST_READ,
00097             IOobject::NO_WRITE,
00098             false
00099         );
00100 
00101         if (undecomposedBoundaryHeader.headerOk())
00102         {
00103             polyBoundaryMeshEntries undecomposedPatchEntries
00104             (
00105                 undecomposedBoundaryHeader
00106             );
00107 
00108             forAll(undecomposedPatchEntries, patchi)
00109             {
00110                 patchNames.append
00111                 (
00112                     undecomposedPatchEntries[patchi].keyword()
00113                 );
00114 
00115                 patchDictionary.add
00116                 (
00117                     undecomposedPatchEntries[patchi]
00118                 );
00119             }
00120         }
00121         else
00122         {
00123             FatalErrorIn ("referredCellList.C")
00124                 << nl << "unable to read undecomposed boundary file from "
00125                 << "constant/polyMesh" << nl
00126                 << abort(FatalError);
00127         }
00128 
00129         labelIOList faceProcAddressing
00130         (
00131             IOobject
00132             (
00133                 "faceProcAddressing",
00134                 mesh.time().constant(),
00135                 polyMesh::meshSubDir,
00136                 mesh,
00137                 IOobject::MUST_READ,
00138                 IOobject::NO_WRITE,
00139                 false
00140             )
00141         );
00142 
00143         labelList procPatches(mesh.globalData().processorPatches());
00144 
00145         nUndecomposedPatches = patchNames.size();
00146 
00147         // processorPatchSegmentMapping works by mapping the original patch and
00148         // half that a face on a processor patch was on before decomposition.
00149         // This creates a patch segment for each half of each original (cyclic)
00150         // patch which can be assessed separately.  There are n =
00151         // patchNames.size() original patches, k = 0 to n-1.  The mapping is:
00152         // value = 0: originally an internal face value = k, was originally on
00153         // the on the patch k-1, 1st half value = -k, was originally on the on
00154         // the patch k-1, 2nd half
00155 
00156         forAll(procPatches,pP)
00157         {
00158             const processorPolyPatch& patch = refCast<const processorPolyPatch>
00159             (
00160                 mesh.boundaryMesh()[procPatches[pP]]
00161             );
00162 
00163             labelList& procPatchSegMap = processorPatchSegmentMapping[pP];
00164 
00165             procPatchSegMap.setSize(patch.size());
00166 
00167             forAll (patch, pI)
00168             {
00169                 label decomposedMeshFace = patch.start() + pI;
00170 
00171                 label faceProcAdd = faceProcAddressing[decomposedMeshFace];
00172 
00173                 label globalFace = abs(faceProcAdd)-1;
00174 
00175                 label minStart = -1;
00176 
00177                 forAll(patchNames, pN)
00178                 {
00179                     if (patchDictionary.found(patchNames[pN]))
00180                     {
00181                         const dictionary& patchDict =
00182                         patchDictionary.subDict(patchNames[pN]);
00183 
00184                         label startFace
00185                         (
00186                             readLabel
00187                             (
00188                                 patchDict.lookup("startFace")
00189                             )
00190                         );
00191 
00192                         label nFaces(readLabel(patchDict.lookup("nFaces")));
00193 
00194                         if (minStart < 0 || startFace < minStart)
00195                         {
00196                             minStart = startFace;
00197                         }
00198 
00199                         if
00200                         (
00201                             globalFace >= startFace
00202                          && globalFace < startFace + nFaces/2
00203                         )
00204                         {
00205                             procPatchSegMap[pI] = pN + 1;
00206                         }
00207                         else if
00208                         (
00209                             globalFace >= startFace + nFaces/2
00210                          && globalFace < startFace + nFaces
00211                         )
00212                         {
00213                             procPatchSegMap[pI] = -(pN + 1);
00214                         }
00215                     }
00216                 }
00217 
00218                 if (globalFace < minStart)
00219                 {
00220                     procPatchSegMap[pI] = 0;
00221                 }
00222             }
00223         }
00224 
00225         forAll(procPatches,pP)
00226         {
00227             const processorPolyPatch& patch = refCast<const processorPolyPatch>
00228             (
00229                 mesh.boundaryMesh()[procPatches[pP]]
00230             );
00231 
00232             {
00233                 OPstream toNeighbProc
00234                 (
00235                     Pstream::blocking,
00236                     patch.neighbProcNo()
00237                 );
00238 
00239                 toNeighbProc << patch.faceCentres() << patch.faceAreas();
00240             }
00241         }
00242 
00243         forAll(procPatches,pP)
00244         {
00245             const processorPolyPatch& patch = refCast<const processorPolyPatch>
00246             (
00247                 mesh.boundaryMesh()[procPatches[pP]]
00248             );
00249 
00250             vectorList& neighbFaceCentres = allNeighbourFaceCentres[pP];
00251 
00252             neighbFaceCentres.setSize(patch.size());
00253 
00254             vectorList& neighbFaceAreas = allNeighbourFaceAreas[pP];
00255 
00256             neighbFaceAreas.setSize(patch.size());
00257 
00258             {
00259                 IPstream fromNeighbProc
00260                 (
00261                     Pstream::blocking,
00262                     patch.neighbProcNo()
00263                 );
00264 
00265                 fromNeighbProc >> neighbFaceCentres >> neighbFaceAreas;
00266             }
00267         }
00268 
00269         // *************************************************************
00270         // Tests that all processor patch segments from different
00271         // original patches prior to decomposition produce the same
00272         // transform. Check before 1st iteration.
00273         // *************************************************************
00274 
00275         forAll(procPatches,pP)
00276         {
00277             const processorPolyPatch& patch = refCast<const processorPolyPatch>
00278             (
00279                 mesh.boundaryMesh()[procPatches[pP]]
00280             );
00281 
00282             const vectorList& neighbFaceCentres = allNeighbourFaceCentres[pP];
00283 
00284             const vectorList& neighbFaceAreas = allNeighbourFaceAreas[pP];
00285 
00286             label nUP;
00287 
00288             for
00289             (
00290                 nUP = -nUndecomposedPatches;
00291                 nUP <= nUndecomposedPatches;
00292                 nUP++
00293             )
00294             {
00295                 DynamicList<vector> refOff;
00296 
00297                 DynamicList<tensor> refTrans;
00298 
00299                 forAll (patch, faceI)
00300                 {
00301                     if (processorPatchSegmentMapping[pP][faceI] == nUP)
00302                     {
00303                         referredCell testRefCell
00304                         (
00305                             mesh,
00306                             -1,
00307                             -1,
00308                             patch.faceCentres()[faceI],
00309                             neighbFaceCentres[faceI],
00310                             patch.faceNormals()[faceI],
00311                             neighbFaceAreas[faceI]
00312                             /(mag(neighbFaceAreas[faceI]) + VSMALL)
00313                         );
00314 
00315                         refOff.append(testRefCell.offset());
00316 
00317                         refTrans.append(testRefCell.rotation());
00318                     }
00319                 }
00320 
00321                 refOff.shrink();
00322 
00323                 refTrans.shrink();
00324 
00325                 if (refOff.size())
00326                 {
00327                     if
00328                     (
00329                         sum(mag(refOff-refOff[0]))/refOff.size()
00330                             > interactionLists::transTol
00331                      || sum(mag(refTrans-refTrans[0]))/refTrans.size()
00332                             > interactionLists::transTol
00333                     )
00334                     {
00335                         FatalErrorIn ("referredCellList.C")
00336                             << nl << "Face pairs on patch "
00337                             << patch.name()
00338                             << ", segment " << patchNames[nUP]
00339                             << " do not give the same referring "
00340                             << " transformations to within tolerance of "
00341                             << interactionLists::transTol << nl
00342                             << " Referring offsets:" << refOff << nl
00343                             << " Average sum of mag difference: "
00344                             << sum(mag(refOff-refOff[0]))/refOff.size() << nl
00345                             << " Referring transforms:" << refTrans << nl
00346                             << " Average sum of mag difference: "
00347                             << sum(mag(refTrans-refTrans[0]))/refTrans.size()
00348                             << nl << abort(FatalError);
00349                     }
00350                 }
00351             }
00352         }
00353     }
00354 
00355     label cellsReferredThisIteration = 1;
00356 
00357     label iterationNo = 0;
00358 
00359     while (cellsReferredThisIteration)
00360     {
00361         label refIntListStartSize = referredInteractionList.size();
00362 
00363         forAll (mesh.boundaryMesh(), patchI)
00364         {
00365             // Treat local cyclics on each processor before processor
00366             // boundaries.  Separate treatment allows the serial version to run
00367             // transparently.
00368 
00369             if (isA<cyclicPolyPatch>(mesh.boundaryMesh()[patchI]))
00370             {
00371                 const cyclicPolyPatch& patch = refCast<const cyclicPolyPatch>
00372                 (
00373                     mesh.boundaryMesh()[patchI]
00374                 );
00375 
00376                 if (patch.size())
00377                 {
00378                     if (iterationNo == 0)
00379                     {
00380                         // Tests that all combinations of face pairs produce the
00381                         // same transform.  Only check on 1st iteration.
00382 
00383                         label faceL;
00384                         // A face in the 1st half of the patch
00385 
00386                         label faceM;
00387                         // Face corresponding to faceL in the 2nd half of the
00388                         // patch. Assumes correct face ordering.
00389 
00390                         vectorList refOff(patch.size()/2);
00391 
00392                         List<tensor> refTrans(patch.size()/2);
00393 
00394                         for
00395                         (
00396                             faceL = 0, faceM = patch.size()/2;
00397                             faceL < patch.size()/2;
00398                             faceL++, faceM++
00399                         )
00400                         {
00401                             referredCell testRefCell
00402                             (
00403                                 mesh,
00404                                 -1,
00405                                 -1,
00406                                 patch.faceCentres()[faceL],
00407                                 patch.faceCentres()[faceM],
00408                                 patch.faceNormals()[faceL],
00409                                 patch.faceNormals()[faceM]
00410                             );
00411 
00412                             refOff[faceL] = testRefCell.offset();
00413 
00414                             refTrans[faceL] = testRefCell.rotation();
00415                         }
00416 
00417                         if
00418                         (
00419                             sum(mag(refOff - refOff[0]))/(patch.size()/2)
00420                                 > interactionLists::transTol
00421                          || sum(mag(refTrans - refTrans[0]))/(patch.size()/2)
00422                                 > interactionLists::transTol
00423                         )
00424                         {
00425                             FatalErrorIn ("referredCellList.C")
00426                                 << nl << "Face pairs on patch "
00427                                 << patch.name()
00428                                 << " do not give the same referring "
00429                                 << " transformations to within tolerance of "
00430                                 << interactionLists::transTol << nl
00431                                 << " Referring offsets:" << refOff << nl
00432                                 << " Average sum of mag difference: "
00433                                 << sum(mag(refOff-refOff[0]))/refOff.size()
00434                                 << nl
00435                                 << " Referring transforms:" << refTrans << nl
00436                                 << " Average sum of mag difference: "
00437                                 << sum(mag(refTrans-refTrans[0]))
00438                                    /refTrans.size()
00439                                 << nl << abort(FatalError);
00440                         }
00441                     }
00442 
00443                     // *********************************************************
00444                     // 1st half of face list - 1st side of boundary
00445                     // *********************************************************
00446 
00447                     label faceI;
00448 
00449                     DynamicList<label> meshFacesOnThisSegment;
00450 
00451                     for (faceI = 0; faceI < patch.size()/2; faceI++)
00452                     {
00453                         // unable to use the normal accessors for the polyPatch
00454                         // because points on separate halves need used
00455                         // separately
00456 
00457                         meshFacesOnThisSegment.append(faceI + patch.start());
00458                     }
00459 
00460                     meshFacesOnThisSegment.shrink();
00461 
00462                     DynamicList<label> meshEdgesOnThisSegment;
00463 
00464                     DynamicList<label> meshPointsOnThisSegment;
00465 
00466                     forAll(meshFacesOnThisSegment, mFOTS)
00467                     {
00468                         const label segFace = meshFacesOnThisSegment[mFOTS];
00469 
00470                         const labelList& faceEdges = mesh.faceEdges()[segFace];
00471 
00472                         forAll (faceEdges, fE)
00473                         {
00474                             const label faceEdge(faceEdges[fE]);
00475 
00476                             if
00477                             (
00478                                 findIndex
00479                                 (
00480                                     meshEdgesOnThisSegment,
00481                                     faceEdge
00482                                 ) == -1
00483                             )
00484                             {
00485                                 meshEdgesOnThisSegment.append(faceEdge);
00486                             }
00487                         }
00488 
00489                         const face& facePoints(mesh.faces()[segFace]);
00490 
00491                         forAll (facePoints, fP)
00492                         {
00493                             const label facePoint(facePoints[fP]);
00494 
00495                             if
00496                             (
00497                                 findIndex
00498                                 (
00499                                     meshPointsOnThisSegment,
00500                                     facePoint
00501                                 )
00502                              ==
00503                                 -1
00504                             )
00505                             {
00506                                 meshPointsOnThisSegment.append(facePoint);
00507                             }
00508                         }
00509                     }
00510 
00511                     meshEdgesOnThisSegment.shrink();
00512 
00513                     meshPointsOnThisSegment.shrink();
00514 
00515                     if (iterationNo == 0)
00516                     {
00517                         // Assessing real cells in range is only required on
00518                         // the 1st iteration because they do not change from
00519                         // iteration to iteration.
00520 
00521                         labelList realCellsFoundInRange
00522                         (
00523                             il_.realCellsInRangeOfSegment
00524                             (
00525                                 meshFacesOnThisSegment,
00526                                 meshEdgesOnThisSegment,
00527                                 meshPointsOnThisSegment
00528                             )
00529                         );
00530 
00531                         forAll(realCellsFoundInRange,cFIR)
00532                         {
00533                             const label realCell = realCellsFoundInRange[cFIR];
00534 
00535                             referredCell cellToRefer
00536                             (
00537                                 mesh,
00538                                 Pstream::myProcNo(),
00539                                 realCell,
00540                                 patch.faceCentres()[0],
00541                                 patch.faceCentres()[patch.size()/2],
00542                                 patch.faceNormals()[0],
00543                                 patch.faceNormals()[patch.size()/2]
00544                             );
00545 
00546                             // Test all existing referred and real cells to
00547                             // check duplicates are not being made or cells
00548                             // aren't being referred back onto themselves
00549 
00550                             bool addCellToRefer = true;
00551 
00552                             // Check if cellToRefer is an existing referred cell
00553 
00554                             forAll(referredInteractionList, rIL)
00555                             {
00556                                 if
00557                                 (
00558                                     cellToRefer.duplicate
00559                                     (
00560                                         referredInteractionList[rIL]
00561                                     )
00562                                 )
00563                                 {
00564                                     addCellToRefer = false;
00565 
00566                                     break;
00567                                 }
00568                             }
00569 
00570                             // Check for cellToRefer being referred back
00571                             // ontop of a real cell
00572 
00573                             if
00574                             (
00575                                 cellToRefer.duplicate
00576                                 (
00577                                     Pstream::myProcNo(),
00578                                     mesh.nCells()
00579                                 )
00580                             )
00581                             {
00582                                 addCellToRefer = false;
00583                             }
00584 
00585                             if (addCellToRefer)
00586                             {
00587                                 referredInteractionList.append(cellToRefer);
00588                             }
00589 
00590                             // add real cells found in range of cyclic patch
00591                             // to whole mesh list
00592 
00593                             if (findIndex (rCellsWRRP, realCell) == -1)
00594                             {
00595                                 rCellsWRRP.append(realCell);
00596                             }
00597                         }
00598                     }
00599 
00600                     referredInteractionList.shrink();
00601 
00602                     labelList referredCellsFoundInRange
00603                     (
00604                         il_.referredCellsInRangeOfSegment
00605                         (
00606                             referredInteractionList,
00607                             meshFacesOnThisSegment,
00608                             meshEdgesOnThisSegment,
00609                             meshPointsOnThisSegment
00610                         )
00611                     );
00612 
00613                     forAll(referredCellsFoundInRange,cFIR)
00614                     {
00615                         referredCell& existingRefCell =
00616                             referredInteractionList
00617                             [
00618                                 referredCellsFoundInRange[cFIR]
00619                             ];
00620 
00621                         referredCell cellToReRefer =
00622                             existingRefCell.reRefer
00623                             (
00624                                 patch.faceCentres()[0],
00625                                 patch.faceCentres()[patch.size()/2],
00626                                 patch.faceNormals()[0],
00627                                 patch.faceNormals()[patch.size()/2]
00628                             );
00629 
00630                         // Test all existing referred and real cells to check
00631                         // duplicates are not being made or cells aren't being
00632                         // referred back onto themselves
00633 
00634                         bool addCellToReRefer = true;
00635 
00636                         // Check if cellToRefer is an existing referred cell
00637 
00638                         forAll(referredInteractionList, rIL)
00639                         {
00640                             if
00641                             (
00642                                 cellToReRefer.duplicate
00643                                 (
00644                                     referredInteractionList[rIL]
00645                                 )
00646                             )
00647                             {
00648                                 addCellToReRefer = false;
00649 
00650                                 break;
00651                             }
00652                         }
00653 
00654                         // Check for cellToRefer being referred back
00655                         // ontop of a real cell
00656 
00657                         if
00658                         (
00659                             cellToReRefer.duplicate
00660                             (
00661                                 Pstream::myProcNo(),
00662                                 mesh.nCells()
00663                             )
00664                         )
00665                         {
00666                             addCellToReRefer = false;
00667                         }
00668 
00669                         if (addCellToReRefer)
00670                         {
00671                             referredInteractionList.append(cellToReRefer);
00672                         }
00673                     }
00674 
00675                     // *********************************************************
00676                     // 2nd half of face list - 2nd side of boundary
00677                     // *********************************************************
00678 
00679                     meshFacesOnThisSegment.clear();
00680 
00681                     for (faceI = patch.size()/2; faceI < patch.size(); faceI++)
00682                     {
00683                         // unable to use the normal accessors for the polyPatch
00684                         // because points on separate halves need used
00685                         // separately
00686 
00687                         meshFacesOnThisSegment.append(faceI + patch.start());
00688                     }
00689 
00690                     meshFacesOnThisSegment.shrink();
00691 
00692                     meshEdgesOnThisSegment.clear();
00693 
00694                     meshPointsOnThisSegment.clear();
00695 
00696                     forAll(meshFacesOnThisSegment, mFOTS)
00697                     {
00698                         const label segFace = meshFacesOnThisSegment[mFOTS];
00699 
00700                         const labelList& faceEdges = mesh.faceEdges()[segFace];
00701 
00702                         forAll (faceEdges, fE)
00703                         {
00704                             const label faceEdge(faceEdges[fE]);
00705 
00706                             if
00707                             (
00708                                 findIndex
00709                                 (
00710                                     meshEdgesOnThisSegment,
00711                                     faceEdge
00712                                 )
00713                              ==
00714                                 -1
00715                             )
00716                             {
00717                                 meshEdgesOnThisSegment.append(faceEdge);
00718                             }
00719                         }
00720 
00721                         const face& facePoints(mesh.faces()[segFace]);
00722 
00723                         forAll (facePoints, fP)
00724                         {
00725                             const label facePoint(facePoints[fP]);
00726 
00727                             if
00728                             (
00729                                 findIndex
00730                                 (
00731                                     meshPointsOnThisSegment,
00732                                     facePoint
00733                                 )
00734                              ==
00735                                 -1
00736                             )
00737                             {
00738                                 meshPointsOnThisSegment.append(facePoint);
00739                             }
00740                         }
00741                     }
00742 
00743                     meshEdgesOnThisSegment.shrink();
00744 
00745                     meshPointsOnThisSegment.shrink();
00746 
00747                     if (iterationNo == 0)
00748                     {
00749                         // Assessing real cells in range is only required on
00750                         // the 1st iteration because they do not change from
00751                         // iteration to iteration.
00752 
00753                         labelList realCellsFoundInRange
00754                         (
00755                             il_.realCellsInRangeOfSegment
00756                             (
00757                                 meshFacesOnThisSegment,
00758                                 meshEdgesOnThisSegment,
00759                                 meshPointsOnThisSegment
00760                             )
00761                         );
00762 
00763                         forAll(realCellsFoundInRange,cFIR)
00764                         {
00765                             const label realCell = realCellsFoundInRange[cFIR];
00766 
00767                             referredCell cellToRefer
00768                             (
00769                                 mesh,
00770                                 Pstream::myProcNo(),
00771                                 realCell,
00772                                 patch.faceCentres()[patch.size()/2],
00773                                 patch.faceCentres()[0],
00774                                 patch.faceNormals()[patch.size()/2],
00775                                 patch.faceNormals()[0]
00776                             );
00777 
00778                             // Test all existing referred and real cells to
00779                             // check duplicates are not being made or cells
00780                             // aren't being referred back onto themselves
00781 
00782                             bool addCellToRefer = true;
00783 
00784                             // Check if cellToRefer is an existing referred cell
00785 
00786                             forAll(referredInteractionList, rIL)
00787                             {
00788                                 if
00789                                 (
00790                                     cellToRefer.duplicate
00791                                     (
00792                                         referredInteractionList[rIL]
00793                                     )
00794                                 )
00795                                 {
00796                                     addCellToRefer = false;
00797 
00798                                     break;
00799                                 }
00800                             }
00801 
00802                             // Check for cellToRefer being referred back
00803                             // ontop of a real cell
00804 
00805                             if
00806                             (
00807                                 cellToRefer.duplicate
00808                                 (
00809                                     Pstream::myProcNo(),
00810                                     mesh.nCells()
00811                                 )
00812                             )
00813                             {
00814                                 addCellToRefer = false;
00815                             }
00816 
00817                             if (addCellToRefer)
00818                             {
00819                                 referredInteractionList.append(cellToRefer);
00820                             }
00821 
00822                             // add real cells found in range of cyclic patch
00823                             // to whole mesh list
00824 
00825                             if (findIndex (rCellsWRRP, realCell) == -1)
00826                             {
00827                                 rCellsWRRP.append(realCell);
00828                             }
00829                         }
00830                     }
00831 
00832                     referredInteractionList.shrink();
00833 
00834                     referredCellsFoundInRange =
00835                         il_.referredCellsInRangeOfSegment
00836                         (
00837                             referredInteractionList,
00838                             meshFacesOnThisSegment,
00839                             meshEdgesOnThisSegment,
00840                             meshPointsOnThisSegment
00841                         );
00842 
00843                     forAll(referredCellsFoundInRange,cFIR)
00844                     {
00845                         referredCell& existingRefCell =
00846                             referredInteractionList
00847                             [
00848                                 referredCellsFoundInRange[cFIR]
00849                             ];
00850 
00851                         referredCell cellToReRefer =
00852                             existingRefCell.reRefer
00853                             (
00854                                 patch.faceCentres()[patch.size()/2],
00855                                 patch.faceCentres()[0],
00856                                 patch.faceNormals()[patch.size()/2],
00857                                 patch.faceNormals()[0]
00858                             );
00859 
00860                         // Test all existing referred and real cells to check
00861                         // duplicates are not being made or cells aren't being
00862                         // referred back onto themselves
00863 
00864                         bool addCellToReRefer = true;
00865 
00866                         // Check if cellToRefer is an existing referred cell
00867 
00868                         forAll(referredInteractionList, rIL)
00869                         {
00870                             if
00871                             (
00872                                 cellToReRefer.duplicate
00873                                 (
00874                                     referredInteractionList[rIL]
00875                                 )
00876                             )
00877                             {
00878                                 addCellToReRefer = false;
00879 
00880                                 break;
00881                             }
00882                         }
00883 
00884                         // Check for cellToRefer being referred back
00885                         // ontop of a real cell
00886 
00887                         if
00888                         (
00889                             cellToReRefer.duplicate
00890                             (
00891                                 Pstream::myProcNo(),
00892                                 mesh.nCells()
00893                             )
00894                         )
00895                         {
00896                             addCellToReRefer = false;
00897                         }
00898 
00899                         if (addCellToReRefer)
00900                         {
00901                             referredInteractionList.append(cellToReRefer);
00902                         }
00903                     }
00904                 }
00905             }
00906         }
00907 
00908         if (Pstream::parRun())
00909         {
00910             labelList procPatches(mesh.globalData().processorPatches());
00911 
00912             forAll(procPatches,pP)
00913             {
00914                 const processorPolyPatch& patch =
00915                     refCast<const processorPolyPatch>
00916                     (
00917                         mesh.boundaryMesh()[procPatches[pP]]
00918                     );
00919 
00920                 DynamicList<referredCell> referredCellsToTransfer;
00921 
00922                 const vectorList& neighbFaceCentres =
00923                     allNeighbourFaceCentres[pP];
00924 
00925                 const vectorList& neighbFaceAreas = allNeighbourFaceAreas[pP];
00926 
00927                 label nUP;
00928 
00929                 for
00930                 (
00931                     nUP = -nUndecomposedPatches;
00932                     nUP <= nUndecomposedPatches;
00933                     nUP++
00934                 )
00935                 {
00936                     // faceT is used to specify one face on this patch segment
00937                     // that will be used to calculate the transformation values.
00938                     // All faces are guaranteed to produce the same transform
00939                     // because of the checks carried out at the start of the
00940                     // function.  Setting to -1 until the 1st face on this
00941                     // segment is found.
00942 
00943                     label faceT = -1;
00944 
00945                     DynamicList<label> meshFacesOnThisSegment;
00946 
00947                     forAll (patch, faceI)
00948                     {
00949                         if (processorPatchSegmentMapping[pP][faceI] == nUP)
00950                         {
00951                             if (faceT == -1)
00952                             {
00953                                 faceT = faceI;
00954                             }
00955 
00956                             meshFacesOnThisSegment.append
00957                             (
00958                                 faceI + patch.start()
00959                             );
00960                         }
00961                     }
00962 
00963                     meshFacesOnThisSegment.shrink();
00964 
00965                     DynamicList<label> meshEdgesOnThisSegment;
00966 
00967                     DynamicList<label> meshPointsOnThisSegment;
00968 
00969                     forAll(meshFacesOnThisSegment, mFOTS)
00970                     {
00971                         const label segFace = meshFacesOnThisSegment[mFOTS];
00972 
00973                         const labelList& faceEdges = mesh.faceEdges()[segFace];
00974 
00975                         forAll (faceEdges, fE)
00976                         {
00977                             const label faceEdge(faceEdges[fE]);
00978 
00979                             if
00980                             (
00981                                 findIndex
00982                                 (
00983                                     meshEdgesOnThisSegment,
00984                                     faceEdge
00985                                 )
00986                              ==
00987                                 -1
00988                             )
00989                             {
00990                                 meshEdgesOnThisSegment.append(faceEdge);
00991                             }
00992                         }
00993 
00994                         const face& facePoints(mesh.faces()[segFace]);
00995 
00996                         forAll (facePoints, fP)
00997                         {
00998                             const label facePoint(facePoints[fP]);
00999 
01000                             if
01001                             (
01002                                 findIndex
01003                                 (
01004                                     meshPointsOnThisSegment,
01005                                     facePoint
01006                                 )
01007                              ==
01008                                 -1
01009                             )
01010                             {
01011                                 meshPointsOnThisSegment.append(facePoint);
01012                             }
01013                         }
01014                     }
01015 
01016                     meshEdgesOnThisSegment.shrink();
01017 
01018                     meshPointsOnThisSegment.shrink();
01019 
01020                     if (meshFacesOnThisSegment.size())
01021                     {
01022                         if (faceT == -1)
01023                         {
01024                             FatalErrorIn ("referredCellList.C")
01025                                 << nl << "faceT == -1 encountered but "
01026                                 << meshFacesOnThisSegment.size()
01027                                 << " faces found on patch segment."
01028                                 << abort(FatalError);
01029                         }
01030 
01031                         if (iterationNo == 0)
01032                         {
01033                             // Assessing real cells in range is only required on
01034                             // the 1st iteration because they do not change from
01035                             // iteration to iteration.
01036 
01037                             labelList realCellsFoundInRange
01038                             (
01039                                 il_.realCellsInRangeOfSegment
01040                                 (
01041                                     meshFacesOnThisSegment,
01042                                     meshEdgesOnThisSegment,
01043                                     meshPointsOnThisSegment
01044                                 )
01045                             );
01046 
01047                             forAll(realCellsFoundInRange,cFIR)
01048                             {
01049                                 const label realCell =
01050                                     realCellsFoundInRange[cFIR];
01051 
01052                                 referredCell cellToRefer
01053                                 (
01054                                     mesh,
01055                                     Pstream::myProcNo(),
01056                                     realCell,
01057                                     patch.faceCentres()[faceT],
01058                                     neighbFaceCentres[faceT],
01059                                     patch.faceNormals()[faceT],
01060                                     neighbFaceAreas[faceT]
01061                                     /(mag(neighbFaceAreas[faceT]) + VSMALL)
01062                                 );
01063 
01064                                 referredCellsToTransfer.append(cellToRefer);
01065 
01066                                 // add real cells found in range of processor
01067                                 // patch to whole mesh list
01068 
01069                                 if (findIndex (rCellsWRRP, realCell) == -1)
01070                                 {
01071                                     rCellsWRRP.append(realCell);
01072                                 }
01073                             }
01074                         }
01075 
01076                         referredInteractionList.shrink();
01077 
01078                         labelList referredCellsFoundInRange
01079                         (
01080                             il_.referredCellsInRangeOfSegment
01081                             (
01082                                 referredInteractionList,
01083                                 meshFacesOnThisSegment,
01084                                 meshEdgesOnThisSegment,
01085                                 meshPointsOnThisSegment
01086                             )
01087                         );
01088 
01089                         forAll(referredCellsFoundInRange,cFIR)
01090                         {
01091                             referredCell& existingRefCell =
01092                                 referredInteractionList
01093                                 [
01094                                     referredCellsFoundInRange[cFIR]
01095                                 ];
01096 
01097                             referredCell cellToReRefer =
01098                                 existingRefCell.reRefer
01099                                 (
01100                                     patch.faceCentres()[faceT],
01101                                     neighbFaceCentres[faceT],
01102                                     patch.faceNormals()[faceT],
01103                                     neighbFaceAreas[faceT]
01104                                     /(mag(neighbFaceAreas[faceT]) + VSMALL)
01105                                 );
01106 
01107                             referredCellsToTransfer.append(cellToReRefer);
01108                         }
01109                     }
01110                 }
01111 
01112                 referredCellsToTransfer.shrink();
01113 
01114                 // Send these cells to the neighbouring processor.
01115 
01116                 {
01117                     OPstream toNeighbProc
01118                     (
01119                         Pstream::blocking,
01120                         patch.neighbProcNo()
01121                     );
01122 
01123                     toNeighbProc << referredCellsToTransfer;
01124                 }
01125             }
01126 
01127             forAll(procPatches,pP)
01128             {
01129                 const processorPolyPatch& patch =
01130                 refCast<const processorPolyPatch>
01131                 (
01132                     mesh.boundaryMesh()[procPatches[pP]]
01133                 );
01134 
01135                 // Receive the cells from neighbour
01136 
01137                 List<referredCell> referredCellsFromNeighbour(patch.size());
01138 
01139                 {
01140                     IPstream fromNeighbProc
01141                     (
01142                         Pstream::blocking,
01143                         patch.neighbProcNo()
01144                     );
01145 
01146                     fromNeighbProc >> referredCellsFromNeighbour;
01147                 }
01148 
01149                 // Check to see if they are duplicates, if not append
01150                 // them to the referredInteractionList
01151 
01152                 forAll(referredCellsFromNeighbour,rCFN)
01153                 {
01154                     referredCell& cellToRefer =
01155                     referredCellsFromNeighbour[rCFN];
01156 
01157                     // Test all existing referred and real cells to check
01158                     // duplicates are not being made or cells aren't being
01159                     // referred back onto themselves
01160 
01161                     bool addCellToRefer = true;
01162 
01163                     // Check if cellToRefer is an existing referred cell
01164 
01165                     forAll(referredInteractionList, rIL)
01166                     {
01167                         if (cellToRefer.duplicate(referredInteractionList[rIL]))
01168                         {
01169                             addCellToRefer = false;
01170 
01171                             break;
01172                         }
01173                     }
01174 
01175                     // Check for cellToRefer being referred back ontop of a real
01176                     // cell
01177 
01178                     if
01179                     (
01180                         cellToRefer.duplicate
01181                         (
01182                             Pstream::myProcNo(),
01183                             mesh.nCells()
01184                         )
01185                     )
01186                     {
01187                         addCellToRefer = false;
01188                     }
01189 
01190                     if (addCellToRefer)
01191                     {
01192                         referredInteractionList.append(cellToRefer);
01193                     }
01194                 }
01195             }
01196         }
01197 
01198         if (iterationNo == 0)
01199         {
01200             // record all real cells in range of any referring patch (cyclic or
01201             // processor) on the first iteration when the real cells are
01202             // evaluated.
01203 
01204             rCellsWRRP.shrink();
01205 
01206             // construct {faces, edges, points}WithinRCutMaxOfAnyReferringPatch
01207 
01208             forAll(rCellsWRRP, rCWR)
01209             {
01210                 const label realCell(rCellsWRRP[rCWR]);
01211 
01212                 const labelList& rCFaces
01213                 (
01214                     mesh.cells()[realCell]
01215                 );
01216 
01217                 forAll(rCFaces, rCF)
01218                 {
01219                     const label f(rCFaces[rCF]);
01220 
01221                     if (findIndex(rFacesWRRP,f) == -1)
01222                     {
01223                         rFacesWRRP.append(f);
01224                     }
01225                 }
01226 
01227                 const labelList& rCEdges
01228                 (
01229                     mesh.cellEdges()[realCell]
01230                 );
01231 
01232                 forAll(rCEdges, rCE)
01233                 {
01234                     const label e(rCEdges[rCE]);
01235 
01236                     if (findIndex(rEdgesWRRP,e) == -1)
01237                     {
01238                         rEdgesWRRP.append(e);
01239                     }
01240                 }
01241 
01242                 const labelList& rCPoints
01243                 (
01244                     mesh.cellPoints()[realCell]
01245                 );
01246 
01247                 forAll(rCPoints, rCP)
01248                 {
01249                     const label p(rCPoints[rCP]);
01250 
01251                     if (findIndex(rPointsWRRP,p) == -1)
01252                     {
01253                         rPointsWRRP.append(p);
01254                     }
01255                 }
01256             }
01257 
01258             rFacesWRRP.shrink();
01259 
01260             rEdgesWRRP.shrink();
01261 
01262             rPointsWRRP.shrink();
01263         }
01264 
01265         iterationNo++;
01266 
01267         cellsReferredThisIteration =
01268             referredInteractionList.size() - refIntListStartSize;
01269 
01270         reduce(cellsReferredThisIteration, sumOp<label>());
01271 
01272         Info<< tab << "Cells added this iteration: "
01273             << cellsReferredThisIteration << endl;
01274     }
01275 
01276     referredInteractionList.shrink();
01277 
01278     //     Info<< "referredInteractionList.size() = "
01279     //         << referredInteractionList.size() << endl;
01280 
01281     //     forAll(referredInteractionList,rIL)
01282     //     {
01283     //         Info<< referredInteractionList[rIL];
01284     //     }
01285 
01286     (*this).setSize
01287     (
01288         referredInteractionList.size()
01289     );
01290 
01291     forAll(referredInteractionList, rIL)
01292     {
01293         (*this)[rIL] = referredInteractionList[rIL];
01294     }
01295 
01296     Info<< nl << "Finding real cells in range of referred cells" << endl;
01297 
01298     forAll(*this, rC)
01299     {
01300         const polyMesh& mesh(il_.mesh());
01301 
01302         referredCell& refCell = (*this)[rC];
01303 
01304         DynamicList<label> realCellsFoundInRange;
01305 
01306         const vectorList& refCellPoints = refCell.vertexPositions();
01307 
01308         forAll(rFacesWRRP, rCF)
01309         {
01310             const label f(rFacesWRRP[rCF]);
01311 
01312             if (il_.testPointFaceDistance(refCellPoints,f))
01313             {
01314                 const label cellO(mesh.faceOwner()[f]);
01315 
01316                 if (findIndex(realCellsFoundInRange, cellO) == -1)
01317                 {
01318                     realCellsFoundInRange.append(cellO);
01319                 }
01320 
01321                 if (mesh.isInternalFace(f))
01322                 {
01323                     // boundary faces will not have neighbour information
01324 
01325                     const label cellN(mesh.faceNeighbour()[f]);
01326 
01327                     if (findIndex(realCellsFoundInRange, cellN) == -1)
01328                     {
01329                         realCellsFoundInRange.append(cellN);
01330                     }
01331                 }
01332             }
01333         }
01334 
01335         forAll(rPointsWRRP, rCP)
01336         {
01337             const label p(rPointsWRRP[rCP]);
01338 
01339             if (il_.testPointFaceDistance(p,refCell))
01340             {
01341                 const labelList& pCells(mesh.pointCells()[p]);
01342 
01343                 forAll(pCells, pC)
01344                 {
01345                     const label cellI(pCells[pC]);
01346 
01347                     if (findIndex(realCellsFoundInRange, cellI) == -1)
01348                     {
01349                         realCellsFoundInRange.append(cellI);
01350                     }
01351                 }
01352             }
01353         }
01354 
01355 
01356         const edgeList& refCellEdges = refCell.edges();
01357 
01358         forAll(rEdgesWRRP, rCE)
01359         {
01360             const label edgeIIndex(rEdgesWRRP[rCE]);
01361 
01362             const edge& eI(mesh.edges()[edgeIIndex]);
01363 
01364             forAll(refCellEdges, rCE)
01365             {
01366                 const edge& eJ(refCellEdges[rCE]);
01367 
01368                 if
01369                 (
01370                     il_.testEdgeEdgeDistance
01371                     (
01372                         eI,
01373                         refCellPoints[eJ.start()],
01374                         refCellPoints[eJ.end()]
01375                     )
01376                 )
01377                 {
01378                     const labelList& eICells(mesh.edgeCells()[edgeIIndex]);
01379 
01380                     forAll(eICells, eIC)
01381                     {
01382                         const label cellI(eICells[eIC]);
01383 
01384                         if (findIndex(realCellsFoundInRange, cellI) == -1)
01385                         {
01386                             realCellsFoundInRange.append(cellI);
01387                         }
01388                     }
01389                 }
01390             }
01391         }
01392 
01393 //         scalar rCutMaxSqr = molCloud_.rCutMax()*molCloud_.rCutMax();
01394 //
01395 //         forAll (molCloud_.mesh().points(), pointIIndex)
01396 //         {
01397 //             const point& ptI
01398 //             (
01399 //                 molCloud_.mesh().points()[pointIIndex]
01400 //             );
01401 //
01402 //             forAll(refCellPoints, rCP)
01403 //             {
01404 //                 if (magSqr(ptI - refCellPoints[rCP]) <= rCutMaxSqr)
01405 //                 {
01406 //                     const labelList& ptICells
01407 //                     (
01408 //                         molCloud_.mesh().pointCells()[pointIIndex]
01409 //                     );
01410 //
01411 //                     forAll(ptICells, pIC)
01412 //                     {
01413 //                         const label cellI(ptICells[pIC]);
01414 //
01415 //                         if (findIndex(realCellsFoundInRange, cellI) == -1)
01416 //                         {
01417 //                             realCellsFoundInRange.append(cellI);
01418 //                         }
01419 //                     }
01420 //                 }
01421 //             }
01422 //         }
01423 
01424         refCell.realCells() = realCellsFoundInRange.shrink();
01425     }
01426 }
01427 
01428 
01429 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
01430 
01431 Foam::referredCellList::referredCellList
01432 (
01433     interactionLists& il,
01434     bool pointPointListBuild
01435 )
01436 :
01437     List<referredCell>(),
01438     il_(il)
01439 {
01440     buildReferredCellList(pointPointListBuild);
01441 }
01442 
01443 
01444 Foam::referredCellList::referredCellList(interactionLists& il)
01445 :
01446     List<referredCell>(),
01447     il_(il)
01448 {
01449     Info<< "Read referredCellList from disk not implemented" << endl;
01450 }
01451 
01452 
01453 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
01454 
01455 Foam::referredCellList::~referredCellList()
01456 {}
01457 
01458 
01459 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
01460 
01461 void Foam::referredCellList::referMolecules
01462 (
01463     const List<DynamicList<molecule*> >& cellOccupancy
01464 )
01465 {
01466     // Create referred molecules for sending using cell occupancy and
01467     // cellSendingReferralLists
01468 
01469     forAll(il_.cellSendingReferralLists(), cSRL)
01470     {
01471         const sendingReferralList& sRL
01472         (
01473             il_.cellSendingReferralLists()[cSRL]
01474         );
01475 
01476         List<DynamicList<referredMolecule> > molsToReferOut(sRL.size());
01477 
01478         forAll(sRL, sRLI)
01479         {
01480             List<molecule*> realMols = cellOccupancy[sRL[sRLI]];
01481 
01482             forAll (realMols, rM)
01483             {
01484                 molecule* mol = realMols[rM];
01485 
01486                 molsToReferOut[sRLI].append
01487                 (
01488                     referredMolecule
01489                     (
01490                         mol->id(),
01491                         mol->position(),
01492                         mol->sitePositions()
01493                     )
01494                 );
01495             }
01496 
01497             molsToReferOut[sRLI].shrink();
01498         }
01499 
01500         // Send lists of referred molecules to other processors
01501 
01502         if (sRL.destinationProc() != Pstream::myProcNo())
01503         {
01504             if (Pstream::parRun())
01505             {
01506                 OPstream toInteractingProc
01507                 (
01508                     Pstream::blocking,
01509                     sRL.destinationProc()
01510                 );
01511 
01512                 toInteractingProc << molsToReferOut;
01513             }
01514         }
01515         else
01516         {
01517             // Refer molecules directly for referred cells on the same
01518             // processor.
01519 
01520             const receivingReferralList& rRL
01521             (
01522                 il_.cellReceivingReferralLists()[cSRL]
01523             );
01524 
01525             forAll(rRL, rRLI)
01526             {
01527                 forAll(rRL[rRLI], rC)
01528                 {
01529                     referredCell& refCellToRefMolsTo = (*this)[rRL[rRLI][rC]];
01530 
01531                     refCellToRefMolsTo.referInMols(molsToReferOut[rRLI]);
01532                 }
01533             }
01534         }
01535     }
01536 
01537     // Receive referred molecule lists to and distribute to referredCells
01538     // according tocellReceivingReferralLists, referredCells deal with the
01539     // transformations themselves
01540 
01541     forAll(il_.cellReceivingReferralLists(), cRRL)
01542     {
01543         const receivingReferralList& rRL
01544         (
01545             il_.cellReceivingReferralLists()[cRRL]
01546         );
01547 
01548         List<List<referredMolecule> > molsToReferIn(rRL.size());
01549 
01550         if (rRL.sourceProc() != Pstream::myProcNo())
01551         {
01552             if (Pstream::parRun())
01553             {
01554                 IPstream fromInteractingProc
01555                 (
01556                     Pstream::blocking,
01557                     rRL.sourceProc()
01558                 );
01559 
01560                 fromInteractingProc >> molsToReferIn;
01561             }
01562 
01563             forAll(rRL, rRLI)
01564             {
01565                 forAll(rRL[rRLI], rC)
01566                 {
01567                     referredCell& refCellToRefMolsTo = (*this)[rRL[rRLI][rC]];
01568 
01569                     refCellToRefMolsTo.referInMols(molsToReferIn[rRLI]);
01570                 }
01571             }
01572         }
01573     }
01574 }
01575 
01576 
01577 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines