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 vectorTensorTransform& 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 vectorTensorTransform& transform = globalTransforms.transform
408 globalTransforms.transformIndex(wfiat)
411 treeBoundBox tempTransformedBb
413 transform.invTransformPosition(wallFaceBbsToExchange[bbI].points())
416 treeBoundBox extendedBb
418 tempTransformedBb.min() - interactionVec,
419 tempTransformedBb.max() + interactionVec
425 coupledPatchRangeTree.findBox(extendedBb)
428 if (!interactingElems.empty())
430 wallFaceBbRequiredByAnyCell[bbI] =
true;
433 rwfil_[bbI].
setSize(interactingElems.size(), -1);
435 forAll(interactingElems, i)
437 label elemI = interactingElems[i];
443 label c = coupledPatchRangeTree.shapes().cellLabels()[elemI];
466 wallFaceBbsToExchange.setSize(0);
468 wallFaceMap().reverseDistribute
470 preDistributionWallFaceMapSize,
471 wallFaceBbRequiredByAnyCell
474 wallFaceMap().reverseDistribute
476 preDistributionWallFaceMapSize,
477 wallFaceIAndTToExchange
483 preDistributionWallFaceMapSize = -1;
488 inplaceSubset(wallFaceBbRequiredByAnyCell, wallFaceIAndTToExchange);
490 inplaceSubset(wallFaceBbRequiredByAnyCell, procToDistributeWallFaceTo);
492 preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
495 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
498 wallFaceIndexAndTransformToDistribute_.transfer(wallFaceIAndTToExchange);
502 rwfilInverse_.setSize(mesh_.nCells());
505 List<DynamicList<label>> rwfilInverseTemp(rwfilInverse_.size());
508 forAll(rwfil_, refWallFacei)
510 const labelList& realCells = rwfil_[refWallFacei];
516 forAll(realCells, realCelli)
518 rwfilInverseTemp[realCells[realCelli]].append(refWallFacei);
522 forAll(rwfilInverse_, celli)
524 rwfilInverse_[celli].transfer(rwfilInverseTemp[celli]);
528 referredWallFaces_.setSize(wallFaceIndexAndTransformToDistribute_.size());
530 forAll(referredWallFaces_, rWFI)
532 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWFI];
534 label wallFaceIndex = globalTransforms.index(wfiat);
536 const vectorTensorTransform& transform = globalTransforms.transform
538 globalTransforms.transformIndex(wfiat)
541 const face& f = mesh_.faces()[wallFaceIndex];
543 label patchi = mesh_.boundaryMesh().patchID()
545 wallFaceIndex - mesh_.nInternalFaces()
548 referredWallFaces_[rWFI] = referredWallFace
551 transform.invTransformPosition(f.points(mesh_.points())),
556 wallFaceMap().distribute(referredWallFaces_);
560 writeReferredWallFaces();
565 Info<<
" Building direct interaction lists" <<
endl;
567 indexedOctree<treeDataFace> wallFacesTree
569 treeDataFace(
true, mesh_, localWallFaces),
576 dil_.setSize(mesh_.nCells());
578 dwfil_.setSize(mesh_.nCells());
582 const treeBoundBox& cellBb = cellBbs[celli];
584 treeBoundBox extendedBb
586 cellBb.min() - interactionVec,
587 cellBb.max() + interactionVec
591 labelList interactingElems(allCellsTree.findBox(extendedBb));
594 DynamicList<label> cellDIL(interactingElems.size());
596 forAll(interactingElems, i)
598 label elemI = interactingElems[i];
600 label c = allCellsTree.shapes().cellLabels()[elemI];
614 dil_[celli].transfer(cellDIL);
617 interactingElems = wallFacesTree.findBox(extendedBb);
619 dwfil_[celli].setSize(interactingElems.size(), -1);
621 forAll(interactingElems, i)
623 label elemI = interactingElems[i];
625 label f = wallFacesTree.shapes().faceLabels()[elemI];
627 dwfil_[celli][i] =
f;
633 template<
class ParticleType>
636 const treeBoundBox& procBb,
637 const List<treeBoundBox>& allExtendedProcBbs,
638 const globalIndexAndTransform& globalTransforms,
639 List<treeBoundBox>& extendedProcBbsInRange,
640 List<label>& extendedProcBbsTransformIndex,
641 List<label>& extendedProcBbsOrigProc
644 extendedProcBbsInRange.setSize(0);
645 extendedProcBbsTransformIndex.setSize(0);
646 extendedProcBbsOrigProc.setSize(0);
648 DynamicList<treeBoundBox> tmpExtendedProcBbsInRange;
649 DynamicList<label> tmpExtendedProcBbsTransformIndex;
650 DynamicList<label> tmpExtendedProcBbsOrigProc;
652 label nTrans = globalTransforms.nIndependentTransforms();
654 forAll(allExtendedProcBbs, proci)
656 List<label> permutationIndices(nTrans, 0);
658 if (nTrans == 0 && proci != Pstream::myProcNo())
660 treeBoundBox extendedReferredProcBb = allExtendedProcBbs[proci];
662 if (procBb.overlaps(extendedReferredProcBb))
664 tmpExtendedProcBbsInRange.append(extendedReferredProcBb);
668 tmpExtendedProcBbsTransformIndex.append(0);
670 tmpExtendedProcBbsOrigProc.append(proci);
673 else if (nTrans == 3)
675 label& i = permutationIndices[0];
676 label& j = permutationIndices[1];
677 label& k = permutationIndices[2];
679 for (i = -1; i <= 1; i++)
681 for (j = -1; j <= 1; j++)
683 for (k = -1; k <= 1; k++)
690 && proci == Pstream::myProcNo()
698 label transI = globalTransforms.encodeTransformIndex
703 const vectorTensorTransform& transform =
704 globalTransforms.transform(transI);
706 treeBoundBox extendedReferredProcBb
708 transform.transformPosition
710 allExtendedProcBbs[proci].points()
714 if (procBb.overlaps(extendedReferredProcBb))
716 tmpExtendedProcBbsInRange.append
718 extendedReferredProcBb
721 tmpExtendedProcBbsTransformIndex.append(transI);
723 tmpExtendedProcBbsOrigProc.append(proci);
729 else if (nTrans == 2)
731 label& i = permutationIndices[0];
732 label& j = permutationIndices[1];
734 for (i = -1; i <= 1; i++)
736 for (j = -1; j <= 1; j++)
738 if (i == 0 && j == 0 && proci == Pstream::myProcNo())
745 label transI = globalTransforms.encodeTransformIndex
750 const vectorTensorTransform& transform =
751 globalTransforms.transform(transI);
753 treeBoundBox extendedReferredProcBb
755 transform.transformPosition
757 allExtendedProcBbs[proci].points()
761 if (procBb.overlaps(extendedReferredProcBb))
763 tmpExtendedProcBbsInRange.append
765 extendedReferredProcBb
768 tmpExtendedProcBbsTransformIndex.append(transI);
770 tmpExtendedProcBbsOrigProc.append(proci);
775 else if (nTrans == 1)
777 label& i = permutationIndices[0];
779 for (i = -1; i <= 1; i++)
781 if (i == 0 && proci == Pstream::myProcNo())
788 label transI = globalTransforms.encodeTransformIndex
793 const vectorTensorTransform& transform =
794 globalTransforms.transform(transI);
796 treeBoundBox extendedReferredProcBb
798 transform.transformPosition
800 allExtendedProcBbs[proci].points()
804 if (procBb.overlaps(extendedReferredProcBb))
806 tmpExtendedProcBbsInRange.append
808 extendedReferredProcBb
811 tmpExtendedProcBbsTransformIndex.append(transI);
813 tmpExtendedProcBbsOrigProc.append(proci);
819 extendedProcBbsInRange = move(tmpExtendedProcBbsInRange);
820 extendedProcBbsTransformIndex = move(tmpExtendedProcBbsTransformIndex);
821 extendedProcBbsOrigProc = move(tmpExtendedProcBbsOrigProc);
825 template<
class ParticleType>
828 autoPtr<mapDistribute>& mapPtr,
829 const List<label>& toProc
840 label proci = toProc[i];
850 sendMap[proci].setSize(nSend[proci]);
858 label proci = toProc[i];
860 sendMap[proci][nSend[proci]++] = i;
865 Pstream::exchangeSizes(sendMap, recvSizes);
874 constructMap[Pstream::myProcNo()] =
identity 876 sendMap[Pstream::myProcNo()].size()
879 label constructSize = constructMap[Pstream::myProcNo()].size();
881 forAll(constructMap, proci)
883 if (proci != Pstream::myProcNo())
885 label nRecv = recvSizes[proci];
887 constructMap[proci].setSize(nRecv);
889 for (
label i = 0; i < nRecv; i++)
891 constructMap[proci][i] = constructSize++;
908 template<
class ParticleType>
914 const globalIndexAndTransform& globalTransforms =
915 mesh_.globalData().globalTransforms();
917 referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
921 forAll(referredParticles_, i)
923 referredParticles_[i].clear();
929 forAll(cellIndexAndTransformToDistribute_, i)
931 const labelPair ciat = cellIndexAndTransformToDistribute_[i];
933 label cellIndex = globalTransforms.index(ciat);
935 List<ParticleType*> realParticles =
cellOccupancy[cellIndex];
937 IDLList<ParticleType>& particlesToRefer = referredParticles_[i];
941 const ParticleType& particle = *realParticles[rM];
943 particlesToRefer.append(particle.clone().ptr());
945 prepareParticleToBeReferred(particlesToRefer.last(), ciat);
951 template<
class ParticleType>
954 ParticleType* particle,
958 const globalIndexAndTransform& globalTransforms =
959 mesh_.globalData().globalTransforms();
961 const vectorTensorTransform& transform = globalTransforms.transform
963 globalTransforms.transformIndex(ciat)
966 particle->prepareForInteractionListReferral(transform);
970 template<
class ParticleType>
975 forAll(referredParticles_, refCelli)
977 const IDLList<ParticleType>& refCell =
978 referredParticles_[refCelli];
984 static_cast<ParticleType*>(iter().
clone().ptr())
992 template<
class ParticleType>
995 const globalIndexAndTransform& globalTransforms =
996 mesh_.globalData().globalTransforms();
998 referredWallData_.setSize
1000 wallFaceIndexAndTransformToDistribute_.size()
1005 forAll(referredWallData_, rWVI)
1007 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWVI];
1009 label wallFaceIndex = globalTransforms.index(wfiat);
1011 const vectorTensorTransform& transform = globalTransforms.transform
1013 globalTransforms.transformIndex(wfiat)
1016 label patchi = mesh_.boundaryMesh().patchID()
1018 wallFaceIndex - mesh_.nInternalFaces()
1023 - mesh_.boundaryMesh()[
patchi].start();
1027 referredWallData_[rWVI] = U.boundaryField()[
patchi][patchFacei];
1029 if (transform.hasR())
1031 referredWallData_[rWVI] =
1032 transform.R().T() & referredWallData_[rWVI];
1038 template<
class ParticleType>
1041 if (referredWallFaces_.empty())
1046 fileName objDir = mesh_.time().timePath()/cloud::prefix;
1050 fileName objFileName =
"referredWallFaces.obj";
1052 OFstream str(objDir/objFileName);
1055 << mesh_.time().timeName()/cloud::prefix/objFileName
1060 forAll(referredWallFaces_, rWFI)
1062 const referredWallFace& rwf = referredWallFaces_[rWFI];
1073 str<<
' ' << fPtI + offset;
1078 offset += rwf.size();
1085 template<
class ParticleType>
1089 cloud_(mesh_,
"nullptr_Cloud",
IDLList<ParticleType>()),
1098 cellIndexAndTransformToDistribute_(),
1099 wallFaceIndexAndTransformToDistribute_(),
1100 referredWallFaces_(),
1101 UName_(
"unknown_U"),
1102 referredWallData_(),
1103 referredParticles_()
1107 template<
class ParticleType>
1118 writeCloud_(writeCloud),
1121 maxDistance_(maxDistance),
1126 cellIndexAndTransformToDistribute_(),
1127 wallFaceIndexAndTransformToDistribute_(),
1128 referredWallFaces_(),
1130 referredWallData_(),
1131 referredParticles_()
1133 buildInteractionLists();
1139 template<
class ParticleType>
1146 template<
class ParticleType>
1153 if (mesh_.changing())
1156 <<
"Mesh changing, rebuilding InteractionLists form scratch." 1159 buildInteractionLists();
1162 prepareWallDataToRefer();
1166 for (
label domain = 0; domain < Pstream::nProcs(); domain++)
1168 const labelList& subMap = cellMap().subMap()[domain];
1180 forAll(subMappedParticles, i)
1182 toDomain << subMappedParticles[i];
1190 wallFaceMap().send(pBufs, referredWallData_);
1194 template<
class ParticleType>
1198 const label startOfRequests
1201 Pstream::waitRequests(startOfRequests);
1203 referredParticles_.setSize(cellMap().constructSize());
1205 for (
label domain = 0; domain < Pstream::nProcs(); domain++)
1207 const labelList& constructMap = cellMap().constructMap()[domain];
1209 if (constructMap.
size())
1218 typename ParticleType::iNew(mesh_)
1224 forAll(referredParticles_, refCelli)
1229 iter().correctAfterInteractionListReferral(ril_[refCelli][0]);
1233 fillReferredParticleCloud();
1235 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
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...
volScalarField & e
Elementary charge.
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.
const dimensionedScalar c
Speed of light in a vacuum.
InteractionLists(const polyMesh &mesh)
Construct null from mesh.
Mesh consisting of general polyhedral cells.
void sendReferredData(const List< DynamicList< ParticleType *>> &cellOccupancy, PstreamBuffers &pBufs)
Prepare and send referred particles and wall data,.