1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*----------------------------------------------------------------------------*/
27 #include "referredCellList.H"
28 #include "interactionLists.H"
29 #include "polyBoundaryMeshEntries.H"
30 #include "PstreamCombineReduceOps.H"
32 #include "globalMeshData.H"
33 #include "processorPolyPatch.H"
34 #include "cyclicPolyPatch.H"
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 void Foam::referredCellList::buildReferredCellList
40 bool pointPointListBuild
43 Info << nl << "Building list of referred interaction neighbours" << endl;
45 const polyMesh& mesh(il_.mesh());
47 DynamicList<referredCell> referredInteractionList;
49 // realCellsWithinRCutMaxOfAnyReferringPatch
50 DynamicList<label> rCellsWRRP;
52 // realFacesWithinRCutMaxOfAnyReferringPatch
53 DynamicList<label> rFacesWRRP;
55 // realEdgesWithinRCutMaxOfAnyReferringPatch
56 DynamicList<label> rEdgesWRRP;
58 // realPointsWithinRCutMaxOfAnyReferringPatch
59 DynamicList<label> rPointsWRRP;
61 labelListList processorPatchSegmentMapping
63 mesh.globalData().processorPatches().size()
66 List<vectorList> allNeighbourFaceCentres
68 mesh.globalData().processorPatches().size()
71 List<vectorList> allNeighbourFaceAreas
73 mesh.globalData().processorPatches().size()
76 label nUndecomposedPatches = 0;
78 if (Pstream::parRun())
80 dictionary patchDictionary;
82 DynamicList<word> patchNames;
86 Time::controlDictName,
87 mesh.time().rootPath(),
88 mesh.time().caseName().path()
91 IOobject undecomposedBoundaryHeader
94 undecomposedTime.constant(),
102 if (undecomposedBoundaryHeader.headerOk())
104 polyBoundaryMeshEntries undecomposedPatchEntries
106 undecomposedBoundaryHeader
109 forAll(undecomposedPatchEntries, patchi)
113 undecomposedPatchEntries[patchi].keyword()
118 undecomposedPatchEntries[patchi]
124 FatalErrorIn ("referredCellList.C")
125 << nl << "unable to read undecomposed boundary file from "
126 << "constant/polyMesh" << nl
127 << abort(FatalError);
130 labelIOList faceProcAddressing
134 "faceProcAddressing",
135 mesh.time().constant(),
136 polyMesh::meshSubDir,
144 labelList procPatches(mesh.globalData().processorPatches());
146 nUndecomposedPatches = patchNames.size();
148 // processorPatchSegmentMapping works by mapping the original patch and
149 // half that a face on a processor patch was on before decomposition.
150 // This creates a patch segment for each half of each original (cyclic)
151 // patch which can be assessed separately. There are n =
152 // patchNames.size() original patches, k = 0 to n-1. The mapping is:
153 // value = 0: originally an internal face value = k, was originally on
154 // the on the patch k-1, 1st half value = -k, was originally on the on
155 // the patch k-1, 2nd half
157 forAll(procPatches,pP)
159 const processorPolyPatch& patch = refCast<const processorPolyPatch>
161 mesh.boundaryMesh()[procPatches[pP]]
164 labelList& procPatchSegMap = processorPatchSegmentMapping[pP];
166 procPatchSegMap.setSize(patch.size());
170 label decomposedMeshFace = patch.start() + pI;
172 label faceProcAdd = faceProcAddressing[decomposedMeshFace];
174 label globalFace = abs(faceProcAdd)-1;
178 forAll(patchNames, pN)
180 if (patchDictionary.found(patchNames[pN]))
182 const dictionary& patchDict =
183 patchDictionary.subDict(patchNames[pN]);
189 patchDict.lookup("startFace")
193 label nFaces(readLabel(patchDict.lookup("nFaces")));
195 if (minStart < 0 || startFace < minStart)
197 minStart = startFace;
202 globalFace >= startFace
203 && globalFace < startFace + nFaces/2
206 procPatchSegMap[pI] = pN + 1;
210 globalFace >= startFace + nFaces/2
211 && globalFace < startFace + nFaces
214 procPatchSegMap[pI] = -(pN + 1);
219 if (globalFace < minStart)
221 procPatchSegMap[pI] = 0;
226 forAll(procPatches,pP)
228 const processorPolyPatch& patch = refCast<const processorPolyPatch>
230 mesh.boundaryMesh()[procPatches[pP]]
234 OPstream toNeighbProc
240 toNeighbProc << patch.faceCentres() << patch.faceAreas();
244 forAll(procPatches,pP)
246 const processorPolyPatch& patch = refCast<const processorPolyPatch>
248 mesh.boundaryMesh()[procPatches[pP]]
251 vectorList& neighbFaceCentres = allNeighbourFaceCentres[pP];
253 neighbFaceCentres.setSize(patch.size());
255 vectorList& neighbFaceAreas = allNeighbourFaceAreas[pP];
257 neighbFaceAreas.setSize(patch.size());
260 IPstream fromNeighbProc
266 fromNeighbProc >> neighbFaceCentres >> neighbFaceAreas;
270 // *************************************************************
271 // Tests that all processor patch segments from different
272 // original patches prior to decomposition produce the same
273 // transform. Check before 1st iteration.
274 // *************************************************************
276 forAll(procPatches,pP)
278 const processorPolyPatch& patch = refCast<const processorPolyPatch>
280 mesh.boundaryMesh()[procPatches[pP]]
283 const vectorList& neighbFaceCentres = allNeighbourFaceCentres[pP];
285 const vectorList& neighbFaceAreas = allNeighbourFaceAreas[pP];
291 nUP = -nUndecomposedPatches;
292 nUP <= nUndecomposedPatches;
296 DynamicList<vector> refOff;
298 DynamicList<tensor> refTrans;
300 forAll (patch, faceI)
302 if (processorPatchSegmentMapping[pP][faceI] == nUP)
304 referredCell testRefCell
309 patch.faceCentres()[faceI],
310 neighbFaceCentres[faceI],
311 patch.faceNormals()[faceI],
312 neighbFaceAreas[faceI]
313 /(mag(neighbFaceAreas[faceI]) + VSMALL)
316 refOff.append(testRefCell.offset());
318 refTrans.append(testRefCell.rotation());
330 sum(mag(refOff-refOff[0]))/refOff.size()
331 > interactionLists::transTol
332 || sum(mag(refTrans-refTrans[0]))/refTrans.size()
333 > interactionLists::transTol
336 FatalErrorIn ("referredCellList.C")
337 << nl << "Face pairs on patch "
339 << ", segment " << patchNames[nUP]
340 << " do not give the same referring "
341 << " transformations to within tolerance of "
342 << interactionLists::transTol << nl
343 << " Referring offsets:" << refOff << nl
344 << " Average sum of mag difference: "
345 << sum(mag(refOff-refOff[0]))/refOff.size() << nl
346 << " Referring transforms:" << refTrans << nl
347 << " Average sum of mag difference: "
348 << sum(mag(refTrans-refTrans[0]))/refTrans.size()
349 << nl << abort(FatalError);
356 label cellsReferredThisIteration = 1;
358 label iterationNo = 0;
360 while (cellsReferredThisIteration)
362 label refIntListStartSize = referredInteractionList.size();
364 forAll (mesh.boundaryMesh(), patchI)
366 // Treat local cyclics on each processor before processor
367 // boundaries. Separate treatment allows the serial version to run
370 if (isA<cyclicPolyPatch>(mesh.boundaryMesh()[patchI]))
372 const cyclicPolyPatch& patch = refCast<const cyclicPolyPatch>
374 mesh.boundaryMesh()[patchI]
379 if (iterationNo == 0)
381 // Tests that all combinations of face pairs produce the
382 // same transform. Only check on 1st iteration.
385 // A face in the 1st half of the patch
388 // Face corresponding to faceL in the 2nd half of the
389 // patch. Assumes correct face ordering.
391 vectorList refOff(patch.size()/2);
393 List<tensor> refTrans(patch.size()/2);
397 faceL = 0, faceM = patch.size()/2;
398 faceL < patch.size()/2;
402 referredCell testRefCell
407 patch.faceCentres()[faceL],
408 patch.faceCentres()[faceM],
409 patch.faceNormals()[faceL],
410 patch.faceNormals()[faceM]
413 refOff[faceL] = testRefCell.offset();
415 refTrans[faceL] = testRefCell.rotation();
420 sum(mag(refOff - refOff[0]))/(patch.size()/2)
421 > interactionLists::transTol
422 || sum(mag(refTrans - refTrans[0]))/(patch.size()/2)
423 > interactionLists::transTol
426 FatalErrorIn ("referredCellList.C")
427 << nl << "Face pairs on patch "
429 << " do not give the same referring "
430 << " transformations to within tolerance of "
431 << interactionLists::transTol << nl
432 << " Referring offsets:" << refOff << nl
433 << " Average sum of mag difference: "
434 << sum(mag(refOff-refOff[0]))/refOff.size()
436 << " Referring transforms:" << refTrans << nl
437 << " Average sum of mag difference: "
438 << sum(mag(refTrans-refTrans[0]))
440 << nl << abort(FatalError);
444 // *********************************************************
445 // 1st half of face list - 1st side of boundary
446 // *********************************************************
450 DynamicList<label> meshFacesOnThisSegment;
452 for (faceI = 0; faceI < patch.size()/2; faceI++)
454 // unable to use the normal accessors for the polyPatch
455 // because points on separate halves need used
458 meshFacesOnThisSegment.append(faceI + patch.start());
461 meshFacesOnThisSegment.shrink();
463 DynamicList<label> meshEdgesOnThisSegment;
465 DynamicList<label> meshPointsOnThisSegment;
467 forAll(meshFacesOnThisSegment, mFOTS)
469 const label segFace = meshFacesOnThisSegment[mFOTS];
471 const labelList& faceEdges = mesh.faceEdges()[segFace];
473 forAll (faceEdges, fE)
475 const label faceEdge(faceEdges[fE]);
481 meshEdgesOnThisSegment,
486 meshEdgesOnThisSegment.append(faceEdge);
490 const face& facePoints(mesh.faces()[segFace]);
492 forAll (facePoints, fP)
494 const label facePoint(facePoints[fP]);
500 meshPointsOnThisSegment,
507 meshPointsOnThisSegment.append(facePoint);
512 meshEdgesOnThisSegment.shrink();
514 meshPointsOnThisSegment.shrink();
516 if (iterationNo == 0)
518 // Assessing real cells in range is only required on
519 // the 1st iteration because they do not change from
520 // iteration to iteration.
522 labelList realCellsFoundInRange
524 il_.realCellsInRangeOfSegment
526 meshFacesOnThisSegment,
527 meshEdgesOnThisSegment,
528 meshPointsOnThisSegment
532 forAll(realCellsFoundInRange,cFIR)
534 const label realCell = realCellsFoundInRange[cFIR];
536 referredCell cellToRefer
541 patch.faceCentres()[0],
542 patch.faceCentres()[patch.size()/2],
543 patch.faceNormals()[0],
544 patch.faceNormals()[patch.size()/2]
547 // Test all existing referred and real cells to
548 // check duplicates are not being made or cells
549 // aren't being referred back onto themselves
551 bool addCellToRefer = true;
553 // Check if cellToRefer is an existing referred cell
555 forAll(referredInteractionList, rIL)
559 cellToRefer.duplicate
561 referredInteractionList[rIL]
565 addCellToRefer = false;
571 // Check for cellToRefer being referred back
572 // ontop of a real cell
576 cellToRefer.duplicate
583 addCellToRefer = false;
588 referredInteractionList.append(cellToRefer);
591 // add real cells found in range of cyclic patch
592 // to whole mesh list
594 if (findIndex (rCellsWRRP, realCell) == -1)
596 rCellsWRRP.append(realCell);
601 referredInteractionList.shrink();
603 labelList referredCellsFoundInRange
605 il_.referredCellsInRangeOfSegment
607 referredInteractionList,
608 meshFacesOnThisSegment,
609 meshEdgesOnThisSegment,
610 meshPointsOnThisSegment
614 forAll(referredCellsFoundInRange,cFIR)
616 referredCell& existingRefCell =
617 referredInteractionList
619 referredCellsFoundInRange[cFIR]
622 referredCell cellToReRefer =
623 existingRefCell.reRefer
625 patch.faceCentres()[0],
626 patch.faceCentres()[patch.size()/2],
627 patch.faceNormals()[0],
628 patch.faceNormals()[patch.size()/2]
631 // Test all existing referred and real cells to check
632 // duplicates are not being made or cells aren't being
633 // referred back onto themselves
635 bool addCellToReRefer = true;
637 // Check if cellToRefer is an existing referred cell
639 forAll(referredInteractionList, rIL)
643 cellToReRefer.duplicate
645 referredInteractionList[rIL]
649 addCellToReRefer = false;
655 // Check for cellToRefer being referred back
656 // ontop of a real cell
660 cellToReRefer.duplicate
667 addCellToReRefer = false;
670 if (addCellToReRefer)
672 referredInteractionList.append(cellToReRefer);
676 // *********************************************************
677 // 2nd half of face list - 2nd side of boundary
678 // *********************************************************
680 meshFacesOnThisSegment.clear();
682 for (faceI = patch.size()/2; faceI < patch.size(); faceI++)
684 // unable to use the normal accessors for the polyPatch
685 // because points on separate halves need used
688 meshFacesOnThisSegment.append(faceI + patch.start());
691 meshFacesOnThisSegment.shrink();
693 meshEdgesOnThisSegment.clear();
695 meshPointsOnThisSegment.clear();
697 forAll(meshFacesOnThisSegment, mFOTS)
699 const label segFace = meshFacesOnThisSegment[mFOTS];
701 const labelList& faceEdges = mesh.faceEdges()[segFace];
703 forAll (faceEdges, fE)
705 const label faceEdge(faceEdges[fE]);
711 meshEdgesOnThisSegment,
718 meshEdgesOnThisSegment.append(faceEdge);
722 const face& facePoints(mesh.faces()[segFace]);
724 forAll (facePoints, fP)
726 const label facePoint(facePoints[fP]);
732 meshPointsOnThisSegment,
739 meshPointsOnThisSegment.append(facePoint);
744 meshEdgesOnThisSegment.shrink();
746 meshPointsOnThisSegment.shrink();
748 if (iterationNo == 0)
750 // Assessing real cells in range is only required on
751 // the 1st iteration because they do not change from
752 // iteration to iteration.
754 labelList realCellsFoundInRange
756 il_.realCellsInRangeOfSegment
758 meshFacesOnThisSegment,
759 meshEdgesOnThisSegment,
760 meshPointsOnThisSegment
764 forAll(realCellsFoundInRange,cFIR)
766 const label realCell = realCellsFoundInRange[cFIR];
768 referredCell cellToRefer
773 patch.faceCentres()[patch.size()/2],
774 patch.faceCentres()[0],
775 patch.faceNormals()[patch.size()/2],
776 patch.faceNormals()[0]
779 // Test all existing referred and real cells to
780 // check duplicates are not being made or cells
781 // aren't being referred back onto themselves
783 bool addCellToRefer = true;
785 // Check if cellToRefer is an existing referred cell
787 forAll(referredInteractionList, rIL)
791 cellToRefer.duplicate
793 referredInteractionList[rIL]
797 addCellToRefer = false;
803 // Check for cellToRefer being referred back
804 // ontop of a real cell
808 cellToRefer.duplicate
815 addCellToRefer = false;
820 referredInteractionList.append(cellToRefer);
823 // add real cells found in range of cyclic patch
824 // to whole mesh list
826 if (findIndex (rCellsWRRP, realCell) == -1)
828 rCellsWRRP.append(realCell);
833 referredInteractionList.shrink();
835 referredCellsFoundInRange =
836 il_.referredCellsInRangeOfSegment
838 referredInteractionList,
839 meshFacesOnThisSegment,
840 meshEdgesOnThisSegment,
841 meshPointsOnThisSegment
844 forAll(referredCellsFoundInRange,cFIR)
846 referredCell& existingRefCell =
847 referredInteractionList
849 referredCellsFoundInRange[cFIR]
852 referredCell cellToReRefer =
853 existingRefCell.reRefer
855 patch.faceCentres()[patch.size()/2],
856 patch.faceCentres()[0],
857 patch.faceNormals()[patch.size()/2],
858 patch.faceNormals()[0]
861 // Test all existing referred and real cells to check
862 // duplicates are not being made or cells aren't being
863 // referred back onto themselves
865 bool addCellToReRefer = true;
867 // Check if cellToRefer is an existing referred cell
869 forAll(referredInteractionList, rIL)
873 cellToReRefer.duplicate
875 referredInteractionList[rIL]
879 addCellToReRefer = false;
885 // Check for cellToRefer being referred back
886 // ontop of a real cell
890 cellToReRefer.duplicate
897 addCellToReRefer = false;
900 if (addCellToReRefer)
902 referredInteractionList.append(cellToReRefer);
909 if (Pstream::parRun())
911 labelList procPatches(mesh.globalData().processorPatches());
913 forAll(procPatches,pP)
915 const processorPolyPatch& patch =
916 refCast<const processorPolyPatch>
918 mesh.boundaryMesh()[procPatches[pP]]
921 DynamicList<referredCell> referredCellsToTransfer;
923 const vectorList& neighbFaceCentres =
924 allNeighbourFaceCentres[pP];
926 const vectorList& neighbFaceAreas = allNeighbourFaceAreas[pP];
932 nUP = -nUndecomposedPatches;
933 nUP <= nUndecomposedPatches;
937 // faceT is used to specify one face on this patch segment
938 // that will be used to calculate the transformation values.
939 // All faces are guaranteed to produce the same transform
940 // because of the checks carried out at the start of the
941 // function. Setting to -1 until the 1st face on this
946 DynamicList<label> meshFacesOnThisSegment;
948 forAll (patch, faceI)
950 if (processorPatchSegmentMapping[pP][faceI] == nUP)
957 meshFacesOnThisSegment.append
959 faceI + patch.start()
964 meshFacesOnThisSegment.shrink();
966 DynamicList<label> meshEdgesOnThisSegment;
968 DynamicList<label> meshPointsOnThisSegment;
970 forAll(meshFacesOnThisSegment, mFOTS)
972 const label segFace = meshFacesOnThisSegment[mFOTS];
974 const labelList& faceEdges = mesh.faceEdges()[segFace];
976 forAll (faceEdges, fE)
978 const label faceEdge(faceEdges[fE]);
984 meshEdgesOnThisSegment,
991 meshEdgesOnThisSegment.append(faceEdge);
995 const face& facePoints(mesh.faces()[segFace]);
997 forAll (facePoints, fP)
999 const label facePoint(facePoints[fP]);
1005 meshPointsOnThisSegment,
1012 meshPointsOnThisSegment.append(facePoint);
1017 meshEdgesOnThisSegment.shrink();
1019 meshPointsOnThisSegment.shrink();
1021 if (meshFacesOnThisSegment.size())
1025 FatalErrorIn ("referredCellList.C")
1026 << nl << "faceT == -1 encountered but "
1027 << meshFacesOnThisSegment.size()
1028 << " faces found on patch segment."
1029 << abort(FatalError);
1032 if (iterationNo == 0)
1034 // Assessing real cells in range is only required on
1035 // the 1st iteration because they do not change from
1036 // iteration to iteration.
1038 labelList realCellsFoundInRange
1040 il_.realCellsInRangeOfSegment
1042 meshFacesOnThisSegment,
1043 meshEdgesOnThisSegment,
1044 meshPointsOnThisSegment
1048 forAll(realCellsFoundInRange,cFIR)
1050 const label realCell =
1051 realCellsFoundInRange[cFIR];
1053 referredCell cellToRefer
1056 Pstream::myProcNo(),
1058 patch.faceCentres()[faceT],
1059 neighbFaceCentres[faceT],
1060 patch.faceNormals()[faceT],
1061 neighbFaceAreas[faceT]
1062 /(mag(neighbFaceAreas[faceT]) + VSMALL)
1065 referredCellsToTransfer.append(cellToRefer);
1067 // add real cells found in range of processor
1068 // patch to whole mesh list
1070 if (findIndex (rCellsWRRP, realCell) == -1)
1072 rCellsWRRP.append(realCell);
1077 referredInteractionList.shrink();
1079 labelList referredCellsFoundInRange
1081 il_.referredCellsInRangeOfSegment
1083 referredInteractionList,
1084 meshFacesOnThisSegment,
1085 meshEdgesOnThisSegment,
1086 meshPointsOnThisSegment
1090 forAll(referredCellsFoundInRange,cFIR)
1092 referredCell& existingRefCell =
1093 referredInteractionList
1095 referredCellsFoundInRange[cFIR]
1098 referredCell cellToReRefer =
1099 existingRefCell.reRefer
1101 patch.faceCentres()[faceT],
1102 neighbFaceCentres[faceT],
1103 patch.faceNormals()[faceT],
1104 neighbFaceAreas[faceT]
1105 /(mag(neighbFaceAreas[faceT]) + VSMALL)
1108 referredCellsToTransfer.append(cellToReRefer);
1113 referredCellsToTransfer.shrink();
1115 // Send these cells to the neighbouring processor.
1118 OPstream toNeighbProc
1121 patch.neighbProcNo()
1124 toNeighbProc << referredCellsToTransfer;
1128 forAll(procPatches,pP)
1130 const processorPolyPatch& patch =
1131 refCast<const processorPolyPatch>
1133 mesh.boundaryMesh()[procPatches[pP]]
1136 // Receive the cells from neighbour
1138 List<referredCell> referredCellsFromNeighbour(patch.size());
1141 IPstream fromNeighbProc
1144 patch.neighbProcNo()
1147 fromNeighbProc >> referredCellsFromNeighbour;
1150 // Check to see if they are duplicates, if not append
1151 // them to the referredInteractionList
1153 forAll(referredCellsFromNeighbour,rCFN)
1155 referredCell& cellToRefer =
1156 referredCellsFromNeighbour[rCFN];
1158 // Test all existing referred and real cells to check
1159 // duplicates are not being made or cells aren't being
1160 // referred back onto themselves
1162 bool addCellToRefer = true;
1164 // Check if cellToRefer is an existing referred cell
1166 forAll(referredInteractionList, rIL)
1168 if (cellToRefer.duplicate(referredInteractionList[rIL]))
1170 addCellToRefer = false;
1176 // Check for cellToRefer being referred back ontop of a real
1181 cellToRefer.duplicate
1183 Pstream::myProcNo(),
1188 addCellToRefer = false;
1193 referredInteractionList.append(cellToRefer);
1199 if (iterationNo == 0)
1201 // record all real cells in range of any referring patch (cyclic or
1202 // processor) on the first iteration when the real cells are
1205 rCellsWRRP.shrink();
1207 // construct {faces, edges, points}WithinRCutMaxOfAnyReferringPatch
1209 forAll(rCellsWRRP, rCWR)
1211 const label realCell(rCellsWRRP[rCWR]);
1213 const labelList& rCFaces
1215 mesh.cells()[realCell]
1218 forAll(rCFaces, rCF)
1220 const label f(rCFaces[rCF]);
1222 if (findIndex(rFacesWRRP,f) == -1)
1224 rFacesWRRP.append(f);
1228 const labelList& rCEdges
1230 mesh.cellEdges()[realCell]
1233 forAll(rCEdges, rCE)
1235 const label e(rCEdges[rCE]);
1237 if (findIndex(rEdgesWRRP,e) == -1)
1239 rEdgesWRRP.append(e);
1243 const labelList& rCPoints
1245 mesh.cellPoints()[realCell]
1248 forAll(rCPoints, rCP)
1250 const label p(rCPoints[rCP]);
1252 if (findIndex(rPointsWRRP,p) == -1)
1254 rPointsWRRP.append(p);
1259 rFacesWRRP.shrink();
1261 rEdgesWRRP.shrink();
1263 rPointsWRRP.shrink();
1268 cellsReferredThisIteration =
1269 referredInteractionList.size() - refIntListStartSize;
1271 reduce(cellsReferredThisIteration, sumOp<label>());
1273 Info<< tab << "Cells added this iteration: "
1274 << cellsReferredThisIteration << endl;
1277 referredInteractionList.shrink();
1279 // Info<< "referredInteractionList.size() = "
1280 // << referredInteractionList.size() << endl;
1282 // forAll(referredInteractionList,rIL)
1284 // Info<< referredInteractionList[rIL];
1289 referredInteractionList.size()
1292 forAll(referredInteractionList, rIL)
1294 (*this)[rIL] = referredInteractionList[rIL];
1297 Info<< nl << "Finding real cells in range of referred cells" << endl;
1301 const polyMesh& mesh(il_.mesh());
1303 referredCell& refCell = (*this)[rC];
1305 DynamicList<label> realCellsFoundInRange;
1307 const vectorList& refCellPoints = refCell.vertexPositions();
1309 forAll(rFacesWRRP, rCF)
1311 const label f(rFacesWRRP[rCF]);
1313 if (il_.testPointFaceDistance(refCellPoints,f))
1315 const label cellO(mesh.faceOwner()[f]);
1317 if (findIndex(realCellsFoundInRange, cellO) == -1)
1319 realCellsFoundInRange.append(cellO);
1322 if (mesh.isInternalFace(f))
1324 // boundary faces will not have neighbour information
1326 const label cellN(mesh.faceNeighbour()[f]);
1328 if (findIndex(realCellsFoundInRange, cellN) == -1)
1330 realCellsFoundInRange.append(cellN);
1336 forAll(rPointsWRRP, rCP)
1338 const label p(rPointsWRRP[rCP]);
1340 if (il_.testPointFaceDistance(p,refCell))
1342 const labelList& pCells(mesh.pointCells()[p]);
1346 const label cellI(pCells[pC]);
1348 if (findIndex(realCellsFoundInRange, cellI) == -1)
1350 realCellsFoundInRange.append(cellI);
1357 const edgeList& refCellEdges = refCell.edges();
1359 forAll(rEdgesWRRP, rCE)
1361 const label edgeIIndex(rEdgesWRRP[rCE]);
1363 const edge& eI(mesh.edges()[edgeIIndex]);
1365 forAll(refCellEdges, rCE)
1367 const edge& eJ(refCellEdges[rCE]);
1371 il_.testEdgeEdgeDistance
1374 refCellPoints[eJ.start()],
1375 refCellPoints[eJ.end()]
1379 const labelList& eICells(mesh.edgeCells()[edgeIIndex]);
1381 forAll(eICells, eIC)
1383 const label cellI(eICells[eIC]);
1385 if (findIndex(realCellsFoundInRange, cellI) == -1)
1387 realCellsFoundInRange.append(cellI);
1394 // scalar rCutMaxSqr = molCloud_.rCutMax()*molCloud_.rCutMax();
1396 // forAll (molCloud_.mesh().points(), pointIIndex)
1400 // molCloud_.mesh().points()[pointIIndex]
1403 // forAll(refCellPoints, rCP)
1405 // if (magSqr(ptI - refCellPoints[rCP]) <= rCutMaxSqr)
1407 // const labelList& ptICells
1409 // molCloud_.mesh().pointCells()[pointIIndex]
1412 // forAll(ptICells, pIC)
1414 // const label cellI(ptICells[pIC]);
1416 // if (findIndex(realCellsFoundInRange, cellI) == -1)
1418 // realCellsFoundInRange.append(cellI);
1425 refCell.realCells() = realCellsFoundInRange.shrink();
1430 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
1432 Foam::referredCellList::referredCellList
1434 interactionLists& il,
1435 bool pointPointListBuild
1438 List<referredCell>(),
1441 buildReferredCellList(pointPointListBuild);
1445 Foam::referredCellList::referredCellList(interactionLists& il)
1447 List<referredCell>(),
1450 Info<< "Read referredCellList from disk not implemented" << endl;
1454 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
1456 Foam::referredCellList::~referredCellList()
1460 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1462 void Foam::referredCellList::referMolecules
1464 const List<DynamicList<molecule*> >& cellOccupancy
1467 // Create referred molecules for sending using cell occupancy and
1468 // cellSendingReferralLists
1470 forAll(il_.cellSendingReferralLists(), cSRL)
1472 const sendingReferralList& sRL
1474 il_.cellSendingReferralLists()[cSRL]
1477 List<DynamicList<referredMolecule> > molsToReferOut(sRL.size());
1481 List<molecule*> realMols = cellOccupancy[sRL[sRLI]];
1483 forAll (realMols, rM)
1485 molecule* mol = realMols[rM];
1487 molsToReferOut[sRLI].append
1493 mol->sitePositions()
1498 molsToReferOut[sRLI].shrink();
1501 // Send lists of referred molecules to other processors
1503 if (sRL.destinationProc() != Pstream::myProcNo())
1505 if (Pstream::parRun())
1507 OPstream toInteractingProc
1510 sRL.destinationProc()
1513 toInteractingProc << molsToReferOut;
1518 // Refer molecules directly for referred cells on the same
1521 const receivingReferralList& rRL
1523 il_.cellReceivingReferralLists()[cSRL]
1528 forAll(rRL[rRLI], rC)
1530 referredCell& refCellToRefMolsTo = (*this)[rRL[rRLI][rC]];
1532 refCellToRefMolsTo.referInMols(molsToReferOut[rRLI]);
1538 // Receive referred molecule lists to and distribute to referredCells
1539 // according tocellReceivingReferralLists, referredCells deal with the
1540 // transformations themselves
1542 forAll(il_.cellReceivingReferralLists(), cRRL)
1544 const receivingReferralList& rRL
1546 il_.cellReceivingReferralLists()[cRRL]
1549 List<List<referredMolecule> > molsToReferIn(rRL.size());
1551 if (rRL.sourceProc() != Pstream::myProcNo())
1553 if (Pstream::parRun())
1555 IPstream fromInteractingProc
1561 fromInteractingProc >> molsToReferIn;
1566 forAll(rRL[rRLI], rC)
1568 referredCell& refCellToRefMolsTo = (*this)[rRL[rRLI][rC]];
1570 refCellToRefMolsTo.referInMols(molsToReferIn[rRLI]);
1578 // ************************************************************************* //