36 template<
class ParticleType>
39 Info<<
"Building InteractionLists with interaction distance " 40 << maxDistance_ <<
endl;
42 const vector interactionVec = maxDistance_*vector::one;
44 treeBoundBox procBb(treeBoundBox(mesh_.points()));
46 treeBoundBox extendedProcBb
48 procBb.min() - interactionVec,
49 procBb.max() + interactionVec
54 allExtendedProcBbs[Pstream::myProcNo()] = extendedProcBb;
56 Pstream::gatherList(allExtendedProcBbs);
58 Pstream::scatterList(allExtendedProcBbs);
60 List<treeBoundBox> extendedProcBbsInRange;
61 List<label> extendedProcBbsTransformIndex;
62 List<label> extendedProcBbsOrigProc;
64 findExtendedProcBbsInRange
68 mesh_.globalData().globalTransforms(),
69 extendedProcBbsInRange,
70 extendedProcBbsTransformIndex,
71 extendedProcBbsOrigProc
78 cellBbs[celli] = treeBoundBox
80 mesh_.cells()[celli].points
88 const globalIndexAndTransform& globalTransforms =
89 mesh_.globalData().globalTransforms();
94 PackedBoolList cellInRangeOfCoupledPatch(mesh_.nCells(),
false);
98 DynamicList<labelPair> cellIAndTToExchange;
100 DynamicList<treeBoundBox> cellBbsToExchange;
102 DynamicList<label> procToDistributeCellTo;
104 forAll(extendedProcBbsInRange, ePBIRI)
106 const treeBoundBox& otherExtendedProcBb =
107 extendedProcBbsInRange[ePBIRI];
109 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
111 label origProc = extendedProcBbsOrigProc[ePBIRI];
115 const treeBoundBox& cellBb = cellBbs[celli];
117 if (cellBb.overlaps(otherExtendedProcBb))
122 cellInRangeOfCoupledPatch[celli] =
true;
124 cellIAndTToExchange.append
126 globalTransforms.encode(celli, transformIndex)
129 cellBbsToExchange.append(cellBb);
131 procToDistributeCellTo.append(origProc);
136 buildMap(cellMapPtr_, procToDistributeCellTo);
139 label preDistributionCellMapSize = procToDistributeCellTo.size();
141 cellMap().distribute(cellBbsToExchange);
143 cellMap().distribute(cellIAndTToExchange);
147 DynamicList<label> coupledPatchRangeCells;
149 forAll(cellInRangeOfCoupledPatch, celli)
151 if (cellInRangeOfCoupledPatch[celli])
153 coupledPatchRangeCells.append(celli);
157 treeBoundBox procBbRndExt
159 treeBoundBox(mesh_.points()).extend(1
e-4)
162 indexedOctree<treeDataCell> coupledPatchRangeTree
168 coupledPatchRangeCells,
177 ril_.setSize(cellBbsToExchange.size());
181 boolList cellBbRequiredByAnyCell(cellBbsToExchange.size(),
false);
183 Info<<
" Building referred interaction lists" <<
endl;
185 forAll(cellBbsToExchange, bbI)
187 const labelPair& ciat = cellIAndTToExchange[bbI];
189 const transformer& transform = globalTransforms.transform
191 globalTransforms.transformIndex(ciat)
194 treeBoundBox tempTransformedBb
196 transform.invTransformPosition(cellBbsToExchange[bbI].points())()
199 treeBoundBox extendedBb
201 tempTransformedBb.min() - interactionVec,
202 tempTransformedBb.max() + interactionVec
208 coupledPatchRangeTree.findBox(extendedBb)
211 if (!interactingElems.empty())
213 cellBbRequiredByAnyCell[bbI] =
true;
216 ril_[bbI].
setSize(interactingElems.size(), -1);
218 forAll(interactingElems, i)
220 label elemI = interactingElems[i];
226 label c = coupledPatchRangeTree.shapes().cellLabels()[elemI];
249 cellBbsToExchange.setSize(0);
251 cellMap().reverseDistribute
253 preDistributionCellMapSize,
254 cellBbRequiredByAnyCell
257 cellMap().reverseDistribute
259 preDistributionCellMapSize,
266 preDistributionCellMapSize = -1;
273 inplaceSubset(cellBbRequiredByAnyCell, procToDistributeCellTo);
275 preDistributionCellMapSize = procToDistributeCellTo.size();
278 buildMap(cellMapPtr_, procToDistributeCellTo);
281 cellIndexAndTransformToDistribute_.transfer(cellIAndTToExchange);
285 rilInverse_.setSize(mesh_.nCells());
288 List<DynamicList<label>> rilInverseTemp(rilInverse_.size());
293 const labelList& realCells = ril_[refCelli];
299 forAll(realCells, realCelli)
301 rilInverseTemp[realCells[realCelli]].append(refCelli);
305 forAll(rilInverse_, celli)
307 rilInverse_[celli].transfer(rilInverseTemp[celli]);
314 mesh_.boundaryMesh().checkParallelSync(
true);
317 DynamicList<label> localWallFaces;
321 const polyPatch& patch = mesh_.boundaryMesh()[
patchi];
323 if (isA<wallPolyPatch>(patch))
325 localWallFaces.append(
identity(patch.size()) + patch.start());
333 wallFaceBbs[i] = treeBoundBox
335 mesh_.faces()[localWallFaces[i]].points(mesh_.points())
340 DynamicList<labelPair> wallFaceIAndTToExchange;
342 DynamicList<treeBoundBox> wallFaceBbsToExchange;
344 DynamicList<label> procToDistributeWallFaceTo;
346 forAll(extendedProcBbsInRange, ePBIRI)
348 const treeBoundBox& otherExtendedProcBb =
349 extendedProcBbsInRange[ePBIRI];
351 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
353 label origProc = extendedProcBbsOrigProc[ePBIRI];
357 const treeBoundBox& wallFaceBb = wallFaceBbs[i];
359 if (wallFaceBb.overlaps(otherExtendedProcBb))
364 label wallFacei = localWallFaces[i];
366 wallFaceIAndTToExchange.append
368 globalTransforms.encode(wallFacei, transformIndex)
371 wallFaceBbsToExchange.append(wallFaceBb);
373 procToDistributeWallFaceTo.append(origProc);
378 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
381 label preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
383 wallFaceMap().distribute(wallFaceBbsToExchange);
385 wallFaceMap().distribute(wallFaceIAndTToExchange);
387 indexedOctree<treeDataCell> allCellsTree
389 treeDataCell(
true, mesh_, polyMesh::CELL_TETS),
396 rwfil_.setSize(wallFaceBbsToExchange.size());
400 boolList wallFaceBbRequiredByAnyCell(wallFaceBbsToExchange.size(),
false);
402 forAll(wallFaceBbsToExchange, bbI)
404 const labelPair& wfiat = wallFaceIAndTToExchange[bbI];
406 const transformer& transform = globalTransforms.transform
408 globalTransforms.transformIndex(wfiat)
411 treeBoundBox tempTransformedBb
413 transform.invTransformPosition
415 wallFaceBbsToExchange[bbI].points()
419 treeBoundBox extendedBb
421 tempTransformedBb.min() - interactionVec,
422 tempTransformedBb.max() + interactionVec
428 coupledPatchRangeTree.findBox(extendedBb)
431 if (!interactingElems.empty())
433 wallFaceBbRequiredByAnyCell[bbI] =
true;
436 rwfil_[bbI].
setSize(interactingElems.size(), -1);
438 forAll(interactingElems, i)
440 label elemI = interactingElems[i];
446 label c = coupledPatchRangeTree.shapes().cellLabels()[elemI];
469 wallFaceBbsToExchange.setSize(0);
471 wallFaceMap().reverseDistribute
473 preDistributionWallFaceMapSize,
474 wallFaceBbRequiredByAnyCell
477 wallFaceMap().reverseDistribute
479 preDistributionWallFaceMapSize,
480 wallFaceIAndTToExchange
486 preDistributionWallFaceMapSize = -1;
491 inplaceSubset(wallFaceBbRequiredByAnyCell, wallFaceIAndTToExchange);
493 inplaceSubset(wallFaceBbRequiredByAnyCell, procToDistributeWallFaceTo);
495 preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
498 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
501 wallFaceIndexAndTransformToDistribute_.transfer(wallFaceIAndTToExchange);
505 rwfilInverse_.setSize(mesh_.nCells());
508 List<DynamicList<label>> rwfilInverseTemp(rwfilInverse_.size());
511 forAll(rwfil_, refWallFacei)
513 const labelList& realCells = rwfil_[refWallFacei];
519 forAll(realCells, realCelli)
521 rwfilInverseTemp[realCells[realCelli]].append(refWallFacei);
525 forAll(rwfilInverse_, celli)
527 rwfilInverse_[celli].transfer(rwfilInverseTemp[celli]);
531 referredWallFaces_.setSize(wallFaceIndexAndTransformToDistribute_.size());
533 forAll(referredWallFaces_, rWFI)
535 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWFI];
537 label wallFaceIndex = globalTransforms.index(wfiat);
539 const transformer& transform = globalTransforms.transform
541 globalTransforms.transformIndex(wfiat)
544 const face& f = mesh_.faces()[wallFaceIndex];
546 label patchi = mesh_.boundaryMesh().patchID()
548 wallFaceIndex - mesh_.nInternalFaces()
551 referredWallFaces_[rWFI] = referredWallFace
554 transform.invTransformPosition(f.points(mesh_.points())),
559 wallFaceMap().distribute(referredWallFaces_);
563 writeReferredWallFaces();
568 Info<<
" Building direct interaction lists" <<
endl;
570 indexedOctree<treeDataFace> wallFacesTree
572 treeDataFace(
true, mesh_, localWallFaces),
579 dil_.setSize(mesh_.nCells());
581 dwfil_.setSize(mesh_.nCells());
585 const treeBoundBox& cellBb = cellBbs[celli];
587 treeBoundBox extendedBb
589 cellBb.min() - interactionVec,
590 cellBb.max() + interactionVec
594 labelList interactingElems(allCellsTree.findBox(extendedBb));
597 DynamicList<label> cellDIL(interactingElems.size());
599 forAll(interactingElems, i)
601 label elemI = interactingElems[i];
603 label c = allCellsTree.shapes().cellLabels()[elemI];
617 dil_[celli].transfer(cellDIL);
620 interactingElems = wallFacesTree.findBox(extendedBb);
622 dwfil_[celli].setSize(interactingElems.size(), -1);
624 forAll(interactingElems, i)
626 label elemI = interactingElems[i];
628 label f = wallFacesTree.shapes().faceLabels()[elemI];
630 dwfil_[celli][i] =
f;
636 template<
class ParticleType>
639 const treeBoundBox& procBb,
640 const List<treeBoundBox>& allExtendedProcBbs,
641 const globalIndexAndTransform& globalTransforms,
642 List<treeBoundBox>& extendedProcBbsInRange,
643 List<label>& extendedProcBbsTransformIndex,
644 List<label>& extendedProcBbsOrigProc
647 extendedProcBbsInRange.setSize(0);
648 extendedProcBbsTransformIndex.setSize(0);
649 extendedProcBbsOrigProc.setSize(0);
651 DynamicList<treeBoundBox> tmpExtendedProcBbsInRange;
652 DynamicList<label> tmpExtendedProcBbsTransformIndex;
653 DynamicList<label> tmpExtendedProcBbsOrigProc;
655 label nTrans = globalTransforms.nIndependentTransforms();
657 forAll(allExtendedProcBbs, proci)
659 List<label> permutationIndices(nTrans, 0);
661 if (nTrans == 0 && proci != Pstream::myProcNo())
663 treeBoundBox extendedReferredProcBb = allExtendedProcBbs[proci];
665 if (procBb.overlaps(extendedReferredProcBb))
667 tmpExtendedProcBbsInRange.append(extendedReferredProcBb);
671 tmpExtendedProcBbsTransformIndex.append(0);
673 tmpExtendedProcBbsOrigProc.append(proci);
676 else if (nTrans == 3)
678 label& i = permutationIndices[0];
679 label& j = permutationIndices[1];
680 label& k = permutationIndices[2];
682 for (i = -1; i <= 1; i++)
684 for (j = -1; j <= 1; j++)
686 for (k = -1; k <= 1; k++)
693 && proci == Pstream::myProcNo()
701 label transI = globalTransforms.encodeTransformIndex
706 const transformer& transform =
707 globalTransforms.transform(transI);
709 treeBoundBox extendedReferredProcBb
711 transform.transformPosition
713 allExtendedProcBbs[proci].points()
717 if (procBb.overlaps(extendedReferredProcBb))
719 tmpExtendedProcBbsInRange.append
721 extendedReferredProcBb
724 tmpExtendedProcBbsTransformIndex.append(transI);
726 tmpExtendedProcBbsOrigProc.append(proci);
732 else if (nTrans == 2)
734 label& i = permutationIndices[0];
735 label& j = permutationIndices[1];
737 for (i = -1; i <= 1; i++)
739 for (j = -1; j <= 1; j++)
741 if (i == 0 && j == 0 && proci == Pstream::myProcNo())
748 label transI = globalTransforms.encodeTransformIndex
753 const transformer& transform =
754 globalTransforms.transform(transI);
756 treeBoundBox extendedReferredProcBb
758 transform.transformPosition
760 allExtendedProcBbs[proci].points()
764 if (procBb.overlaps(extendedReferredProcBb))
766 tmpExtendedProcBbsInRange.append
768 extendedReferredProcBb
771 tmpExtendedProcBbsTransformIndex.append(transI);
773 tmpExtendedProcBbsOrigProc.append(proci);
778 else if (nTrans == 1)
780 label& i = permutationIndices[0];
782 for (i = -1; i <= 1; i++)
784 if (i == 0 && proci == Pstream::myProcNo())
791 label transI = globalTransforms.encodeTransformIndex
796 const transformer& transform =
797 globalTransforms.transform(transI);
799 treeBoundBox extendedReferredProcBb
801 transform.transformPosition
803 allExtendedProcBbs[proci].points()
807 if (procBb.overlaps(extendedReferredProcBb))
809 tmpExtendedProcBbsInRange.append
811 extendedReferredProcBb
814 tmpExtendedProcBbsTransformIndex.append(transI);
816 tmpExtendedProcBbsOrigProc.append(proci);
822 extendedProcBbsInRange = move(tmpExtendedProcBbsInRange);
823 extendedProcBbsTransformIndex = move(tmpExtendedProcBbsTransformIndex);
824 extendedProcBbsOrigProc = move(tmpExtendedProcBbsOrigProc);
828 template<
class ParticleType>
831 autoPtr<mapDistribute>& mapPtr,
832 const List<label>& toProc
843 label proci = toProc[i];
853 sendMap[proci].setSize(nSend[proci]);
861 label proci = toProc[i];
863 sendMap[proci][nSend[proci]++] = i;
868 Pstream::exchangeSizes(sendMap, recvSizes);
877 constructMap[Pstream::myProcNo()] =
identity 879 sendMap[Pstream::myProcNo()].size()
882 label constructSize = constructMap[Pstream::myProcNo()].size();
884 forAll(constructMap, proci)
886 if (proci != Pstream::myProcNo())
888 label nRecv = recvSizes[proci];
890 constructMap[proci].setSize(nRecv);
892 for (
label i = 0; i < nRecv; i++)
894 constructMap[proci][i] = constructSize++;
911 template<
class ParticleType>
917 const globalIndexAndTransform& globalTransforms =
918 mesh_.globalData().globalTransforms();
920 referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
924 forAll(referredParticles_, i)
926 referredParticles_[i].clear();
932 forAll(cellIndexAndTransformToDistribute_, i)
934 const labelPair ciat = cellIndexAndTransformToDistribute_[i];
936 label cellIndex = globalTransforms.index(ciat);
938 List<ParticleType*> realParticles =
cellOccupancy[cellIndex];
940 IDLList<ParticleType>& particlesToRefer = referredParticles_[i];
944 const ParticleType& particle = *realParticles[rM];
946 particlesToRefer.append(particle.clone().ptr());
948 prepareParticleToBeReferred(particlesToRefer.last(), ciat);
954 template<
class ParticleType>
957 ParticleType* particle,
961 const globalIndexAndTransform& globalTransforms =
962 mesh_.globalData().globalTransforms();
964 const transformer& transform = globalTransforms.transform
966 globalTransforms.transformIndex(ciat)
969 particle->prepareForInteractionListReferral(transform);
973 template<
class ParticleType>
978 forAll(referredParticles_, refCelli)
980 const IDLList<ParticleType>& refCell =
981 referredParticles_[refCelli];
987 static_cast<ParticleType*>(iter().
clone().ptr())
995 template<
class ParticleType>
998 const globalIndexAndTransform& globalTransforms =
999 mesh_.globalData().globalTransforms();
1001 referredWallData_.setSize
1003 wallFaceIndexAndTransformToDistribute_.size()
1008 forAll(referredWallData_, rWVI)
1010 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWVI];
1012 label wallFaceIndex = globalTransforms.index(wfiat);
1014 const transformer& transform = globalTransforms.transform
1016 globalTransforms.transformIndex(wfiat)
1019 label patchi = mesh_.boundaryMesh().patchID()
1021 wallFaceIndex - mesh_.nInternalFaces()
1026 - mesh_.boundaryMesh()[
patchi].start();
1030 referredWallData_[rWVI] = U.boundaryField()[
patchi][patchFacei];
1032 if (transform.transforms())
1034 referredWallData_[rWVI] =
1035 transform.invTransform(referredWallData_[rWVI]);
1041 template<
class ParticleType>
1044 if (referredWallFaces_.empty())
1049 fileName objDir = mesh_.time().timePath()/cloud::prefix;
1053 fileName objFileName =
"referredWallFaces.obj";
1055 OFstream str(objDir/objFileName);
1058 << mesh_.time().timeName()/cloud::prefix/objFileName
1063 forAll(referredWallFaces_, rWFI)
1065 const referredWallFace& rwf = referredWallFaces_[rWFI];
1076 str<<
' ' << fPtI + offset;
1081 offset += rwf.size();
1088 template<
class ParticleType>
1092 cloud_(mesh_,
"nullptr_Cloud",
IDLList<ParticleType>()),
1101 cellIndexAndTransformToDistribute_(),
1102 wallFaceIndexAndTransformToDistribute_(),
1103 referredWallFaces_(),
1104 UName_(
"unknown_U"),
1105 referredWallData_(),
1106 referredParticles_()
1110 template<
class ParticleType>
1121 writeCloud_(writeCloud),
1124 maxDistance_(maxDistance),
1129 cellIndexAndTransformToDistribute_(),
1130 wallFaceIndexAndTransformToDistribute_(),
1131 referredWallFaces_(),
1133 referredWallData_(),
1134 referredParticles_()
1136 buildInteractionLists();
1142 template<
class ParticleType>
1149 template<
class ParticleType>
1156 if (mesh_.changing())
1159 <<
"Mesh changing, rebuilding InteractionLists form scratch." 1162 buildInteractionLists();
1165 prepareWallDataToRefer();
1169 for (
label domain = 0; domain < Pstream::nProcs(); domain++)
1171 const labelList& subMap = cellMap().subMap()[domain];
1183 forAll(subMappedParticles, i)
1185 toDomain << subMappedParticles[i];
1193 wallFaceMap().send(pBufs, referredWallData_);
1197 template<
class ParticleType>
1201 const label startOfRequests
1204 Pstream::waitRequests(startOfRequests);
1206 referredParticles_.setSize(cellMap().constructSize());
1208 for (
label domain = 0; domain < Pstream::nProcs(); domain++)
1210 const labelList& constructMap = cellMap().constructMap()[domain];
1212 if (constructMap.
size())
1221 typename ParticleType::iNew(mesh_)
1227 forAll(referredParticles_, refCelli)
1232 iter().correctAfterInteractionListReferral(ril_[refCelli][0]);
1236 fillReferredParticleCloud();
1238 wallFaceMap().receive(pBufs, referredWallData_);
Template class for intrusive linked lists.
void inplaceSubset(const UList< T > &select, const T &value, ListType &)
Inplace extract elements of List when select is a certain value.
List< labelList > labelListList
A List of labelList.
List< treeBoundBox > treeBoundBoxList
List of bounding boxes.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Builds direct interaction list, specifying which local (real) cells are potentially in range of each ...
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
void size(const label)
Override size to be inconsistent with allocated storage.
Ostream & endl(Ostream &os)
Add newline and flush stream.
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, y/n, t/f, or none/any.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Vector< scalar > vector
A scalar version of the templated Vector.
GeometricField< vector, fvPatchField, volMesh > volVectorField
const dimensionedScalar c
Speed of light in a vacuum.
List< bool > boolList
Bool container classes.
Input inter-processor communications stream operating on external buffer.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
A class for handling words, derived from string.
Pair< label > labelPair
Label pair.
List< label > labelList
A List of labels.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Output inter-processor communications stream operating on external buffer.
void receiveReferredData(PstreamBuffers &pBufs, const label startReq=0)
Receive referred data.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
void setSize(const label)
Reset size of List.
const List< DynamicList< molecule * > > & cellOccupancy
#define WarningInFunction
Report a warning using Foam::Warning.
A List with indirect addressing.
InteractionLists(const polyMesh &mesh)
Construct null from mesh.
Mesh consisting of general polyhedral cells.
const dimensionedScalar e
Elementary charge.
void sendReferredData(const List< DynamicList< ParticleType *>> &cellOccupancy, PstreamBuffers &pBufs)
Prepare and send referred particles and wall data,.