39template<
class ParticleType>
42 Info<<
"Building InteractionLists with interaction distance "
43 << maxDistance_ <<
endl;
47 const vector interactionVec = maxDistance_*vector::one;
49 treeBoundBox procBb(treeBoundBox(mesh_.points()));
51 treeBoundBox extendedProcBb
53 procBb.min() - interactionVec,
54 procBb.max() + interactionVec
59 allExtendedProcBbs[Pstream::myProcNo()] = extendedProcBb;
61 Pstream::allGatherList(allExtendedProcBbs);
63 List<treeBoundBox> extendedProcBbsInRange;
64 List<label> extendedProcBbsTransformIndex;
65 List<label> extendedProcBbsOrigProc;
67 findExtendedProcBbsInRange
71 mesh_.globalData().globalTransforms(),
72 extendedProcBbsInRange,
73 extendedProcBbsTransformIndex,
74 extendedProcBbsOrigProc
81 cellBbs[celli] = treeBoundBox
83 mesh_.cells()[celli].points
91 const globalIndexAndTransform& globalTransforms =
92 mesh_.globalData().globalTransforms();
97 bitSet cellInRangeOfCoupledPatch(mesh_.nCells(),
false);
101 DynamicList<labelPair> cellIAndTToExchange;
103 DynamicList<treeBoundBox> cellBbsToExchange;
105 DynamicList<label> procToDistributeCellTo;
107 forAll(extendedProcBbsInRange, ePBIRI)
109 const treeBoundBox& otherExtendedProcBb =
110 extendedProcBbsInRange[ePBIRI];
112 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
114 label origProc = extendedProcBbsOrigProc[ePBIRI];
118 const treeBoundBox& cellBb = cellBbs[celli];
120 if (cellBb.overlaps(otherExtendedProcBb))
125 cellInRangeOfCoupledPatch.set(celli);
127 cellIAndTToExchange.append
129 globalTransforms.encode(celli, transformIndex)
132 cellBbsToExchange.append(cellBb);
134 procToDistributeCellTo.append(origProc);
139 buildMap(cellMapPtr_, procToDistributeCellTo);
142 label preDistributionCellMapSize = procToDistributeCellTo.size();
144 cellMap().distribute(cellBbsToExchange);
146 cellMap().distribute(cellIAndTToExchange);
150 DynamicList<label> coupledPatchRangeCells;
152 forAll(cellInRangeOfCoupledPatch, celli)
154 if (cellInRangeOfCoupledPatch[celli])
156 coupledPatchRangeCells.append(celli);
160 treeBoundBox procBbRndExt
162 treeBoundBox(mesh_.points()).extend(
rndGen, 1
e-4)
165 indexedOctree<treeDataCell> coupledPatchRangeTree
171 coupledPatchRangeCells,
180 ril_.setSize(cellBbsToExchange.size());
184 boolList cellBbRequiredByAnyCell(cellBbsToExchange.size(),
false);
186 Info<<
" Building referred interaction lists" <<
endl;
188 forAll(cellBbsToExchange, bbI)
190 const labelPair& ciat = cellIAndTToExchange[bbI];
192 const vectorTensorTransform&
transform = globalTransforms.transform
194 globalTransforms.transformIndex(ciat)
197 treeBoundBox tempTransformedBb
199 transform.invTransformPosition(cellBbsToExchange[bbI].points())
202 treeBoundBox extendedBb
204 tempTransformedBb.min() - interactionVec,
205 tempTransformedBb.max() + interactionVec
211 coupledPatchRangeTree.findBox(extendedBb)
214 if (!interactingElems.empty())
216 cellBbRequiredByAnyCell[bbI] =
true;
219 ril_[bbI].setSize(interactingElems.size(), -1);
221 forAll(interactingElems, i)
223 label elemI = interactingElems[i];
229 label c = coupledPatchRangeTree.shapes().cellLabels()[elemI];
252 cellBbsToExchange.setSize(0);
254 cellMap().reverseDistribute
256 preDistributionCellMapSize,
257 cellBbRequiredByAnyCell
260 cellMap().reverseDistribute
262 preDistributionCellMapSize,
269 preDistributionCellMapSize = -1;
276 inplaceSubset(cellBbRequiredByAnyCell, procToDistributeCellTo);
278 preDistributionCellMapSize = procToDistributeCellTo.size();
281 buildMap(cellMapPtr_, procToDistributeCellTo);
284 cellIndexAndTransformToDistribute_.transfer(cellIAndTToExchange);
288 rilInverse_.setSize(mesh_.nCells());
296 const labelList& realCells = ril_[refCelli];
302 forAll(realCells, realCelli)
304 rilInverseTemp[realCells[realCelli]].append(refCelli);
308 forAll(rilInverse_, celli)
310 rilInverse_[celli].transfer(rilInverseTemp[celli]);
317 mesh_.boundaryMesh().checkParallelSync(
true);
320 DynamicList<label> localWallFaces;
322 for (
const polyPatch& patch : mesh_.boundaryMesh())
324 if (isA<wallPolyPatch>(patch))
328 forAll(areaFraction, facei)
330 if (areaFraction[facei] > 0.5)
332 localWallFaces.append(facei +
patch.start());
346 mesh_.faces()[localWallFaces[i]]
351 DynamicList<labelPair> wallFaceIAndTToExchange;
353 DynamicList<treeBoundBox> wallFaceBbsToExchange;
355 DynamicList<label> procToDistributeWallFaceTo;
357 forAll(extendedProcBbsInRange, ePBIRI)
359 const treeBoundBox& otherExtendedProcBb =
360 extendedProcBbsInRange[ePBIRI];
362 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
364 label origProc = extendedProcBbsOrigProc[ePBIRI];
368 const treeBoundBox& wallFaceBb = wallFaceBbs[i];
370 if (wallFaceBb.overlaps(otherExtendedProcBb))
375 label wallFacei = localWallFaces[i];
377 wallFaceIAndTToExchange.append
379 globalTransforms.encode(wallFacei, transformIndex)
382 wallFaceBbsToExchange.append(wallFaceBb);
384 procToDistributeWallFaceTo.append(origProc);
389 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
392 label preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
394 wallFaceMap().distribute(wallFaceBbsToExchange);
396 wallFaceMap().distribute(wallFaceIAndTToExchange);
398 indexedOctree<treeDataCell> allCellsTree
400 treeDataCell(
true, mesh_, polyMesh::CELL_TETS),
407 rwfil_.setSize(wallFaceBbsToExchange.size());
411 boolList wallFaceBbRequiredByAnyCell(wallFaceBbsToExchange.size(),
false);
413 forAll(wallFaceBbsToExchange, bbI)
415 const labelPair& wfiat = wallFaceIAndTToExchange[bbI];
417 const vectorTensorTransform&
transform = globalTransforms.transform
419 globalTransforms.transformIndex(wfiat)
422 treeBoundBox tempTransformedBb
424 transform.invTransformPosition(wallFaceBbsToExchange[bbI].points())
427 treeBoundBox extendedBb
429 tempTransformedBb.min() - interactionVec,
430 tempTransformedBb.max() + interactionVec
436 coupledPatchRangeTree.findBox(extendedBb)
439 if (!interactingElems.empty())
441 wallFaceBbRequiredByAnyCell[bbI] =
true;
444 rwfil_[bbI].setSize(interactingElems.size(), -1);
446 forAll(interactingElems, i)
448 label elemI = interactingElems[i];
454 label
c = coupledPatchRangeTree.shapes().cellLabels()[elemI];
477 wallFaceBbsToExchange.setSize(0);
479 wallFaceMap().reverseDistribute
481 preDistributionWallFaceMapSize,
482 wallFaceBbRequiredByAnyCell
485 wallFaceMap().reverseDistribute
487 preDistributionWallFaceMapSize,
488 wallFaceIAndTToExchange
494 preDistributionWallFaceMapSize = -1;
499 inplaceSubset(wallFaceBbRequiredByAnyCell, wallFaceIAndTToExchange);
501 inplaceSubset(wallFaceBbRequiredByAnyCell, procToDistributeWallFaceTo);
503 preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
506 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
509 wallFaceIndexAndTransformToDistribute_.transfer(wallFaceIAndTToExchange);
513 rwfilInverse_.setSize(mesh_.nCells());
516 List<DynamicList<label>> rwfilInverseTemp(rwfilInverse_.size());
519 forAll(rwfil_, refWallFacei)
521 const labelList& realCells = rwfil_[refWallFacei];
527 forAll(realCells, realCelli)
529 rwfilInverseTemp[realCells[realCelli]].append(refWallFacei);
533 forAll(rwfilInverse_, celli)
535 rwfilInverse_[celli].transfer(rwfilInverseTemp[celli]);
539 referredWallFaces_.setSize(wallFaceIndexAndTransformToDistribute_.size());
541 forAll(referredWallFaces_, rWFI)
543 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWFI];
545 label wallFaceIndex = globalTransforms.index(wfiat);
547 const vectorTensorTransform&
transform = globalTransforms.transform
549 globalTransforms.transformIndex(wfiat)
552 const face&
f = mesh_.faces()[wallFaceIndex];
554 label patchi = mesh_.boundaryMesh().patchID()
556 wallFaceIndex - mesh_.nInternalFaces()
559 referredWallFaces_[rWFI] = referredWallFace
562 transform.invTransformPosition(
f.points(mesh_.points())),
567 wallFaceMap().distribute(referredWallFaces_);
571 writeReferredWallFaces();
576 Info<<
" Building direct interaction lists" <<
endl;
578 indexedOctree<treeDataFace> wallFacesTree
580 treeDataFace(
true, mesh_, localWallFaces),
587 dil_.setSize(mesh_.nCells());
589 dwfil_.setSize(mesh_.nCells());
593 const treeBoundBox& cellBb = cellBbs[celli];
595 treeBoundBox extendedBb
597 cellBb.min() - interactionVec,
598 cellBb.max() + interactionVec
602 labelList interactingElems(allCellsTree.findBox(extendedBb));
605 DynamicList<label> cellDIL(interactingElems.size());
607 for (
const label elemi : interactingElems)
609 const label
c = allCellsTree.shapes().cellLabels()[elemi];
623 dil_[celli].transfer(cellDIL);
626 interactingElems = wallFacesTree.findBox(extendedBb);
628 dwfil_[celli].setSize(interactingElems.size(), -1);
630 forAll(interactingElems, i)
632 const label elemi = interactingElems[i];
634 const label
f = wallFacesTree.shapes().faceLabels()[elemi];
636 dwfil_[celli][i] =
f;
642template<
class ParticleType>
645 const treeBoundBox& procBb,
646 const List<treeBoundBox>& allExtendedProcBbs,
647 const globalIndexAndTransform& globalTransforms,
648 List<treeBoundBox>& extendedProcBbsInRange,
649 List<label>& extendedProcBbsTransformIndex,
650 List<label>& extendedProcBbsOrigProc
653 extendedProcBbsInRange.setSize(0);
654 extendedProcBbsTransformIndex.setSize(0);
655 extendedProcBbsOrigProc.setSize(0);
657 DynamicList<treeBoundBox> tmpExtendedProcBbsInRange;
658 DynamicList<label> tmpExtendedProcBbsTransformIndex;
659 DynamicList<label> tmpExtendedProcBbsOrigProc;
661 label nTrans = globalTransforms.nIndependentTransforms();
663 forAll(allExtendedProcBbs, proci)
665 labelList permutationIndices(nTrans, Zero);
667 if (nTrans == 0 && proci != Pstream::myProcNo())
669 treeBoundBox extendedReferredProcBb = allExtendedProcBbs[proci];
671 if (procBb.overlaps(extendedReferredProcBb))
673 tmpExtendedProcBbsInRange.append(extendedReferredProcBb);
677 tmpExtendedProcBbsTransformIndex.append(0);
679 tmpExtendedProcBbsOrigProc.append(proci);
682 else if (nTrans == 3)
684 label& i = permutationIndices[0];
685 label& j = permutationIndices[1];
686 label&
k = permutationIndices[2];
688 for (i = -1; i <= 1; i++)
690 for (j = -1; j <= 1; j++)
692 for (
k = -1;
k <= 1;
k++)
699 && proci == Pstream::myProcNo()
707 label transI = globalTransforms.encodeTransformIndex
713 globalTransforms.transform(transI);
715 treeBoundBox extendedReferredProcBb
719 allExtendedProcBbs[proci].points()
723 if (procBb.overlaps(extendedReferredProcBb))
725 tmpExtendedProcBbsInRange.append
727 extendedReferredProcBb
730 tmpExtendedProcBbsTransformIndex.append(transI);
732 tmpExtendedProcBbsOrigProc.append(proci);
738 else if (nTrans == 2)
740 label& i = permutationIndices[0];
741 label& j = permutationIndices[1];
743 for (i = -1; i <= 1; i++)
745 for (j = -1; j <= 1; j++)
747 if (i == 0 && j == 0 && proci == Pstream::myProcNo())
754 label transI = globalTransforms.encodeTransformIndex
760 globalTransforms.transform(transI);
762 treeBoundBox extendedReferredProcBb
766 allExtendedProcBbs[proci].points()
770 if (procBb.overlaps(extendedReferredProcBb))
772 tmpExtendedProcBbsInRange.append
774 extendedReferredProcBb
777 tmpExtendedProcBbsTransformIndex.append(transI);
779 tmpExtendedProcBbsOrigProc.append(proci);
784 else if (nTrans == 1)
786 label& i = permutationIndices[0];
788 for (i = -1; i <= 1; i++)
790 if (i == 0 && proci == Pstream::myProcNo())
797 label transI = globalTransforms.encodeTransformIndex
803 globalTransforms.transform(transI);
805 treeBoundBox extendedReferredProcBb
809 allExtendedProcBbs[proci].points()
813 if (procBb.overlaps(extendedReferredProcBb))
815 tmpExtendedProcBbsInRange.append
817 extendedReferredProcBb
820 tmpExtendedProcBbsTransformIndex.append(transI);
822 tmpExtendedProcBbsOrigProc.append(proci);
828 extendedProcBbsInRange.transfer(tmpExtendedProcBbsInRange);
829 extendedProcBbsTransformIndex.transfer(tmpExtendedProcBbsTransformIndex);
830 extendedProcBbsOrigProc.transfer(tmpExtendedProcBbsOrigProc);
834template<
class ParticleType>
837 autoPtr<mapDistribute>& mapPtr,
838 const List<label>& toProc
845 labelList nSend(Pstream::nProcs(), Zero);
847 for (
const label proci : toProc)
857 sendMap[proci].setSize(nSend[proci]);
865 label proci = toProc[i];
867 sendMap[proci][nSend[proci]++] = i;
872 Pstream::exchangeSizes(sendMap, recvSizes);
881 constructMap[Pstream::myProcNo()] =
identity
883 sendMap[Pstream::myProcNo()].size()
886 label constructSize = constructMap[Pstream::myProcNo()].size();
888 forAll(constructMap, proci)
890 if (proci != Pstream::myProcNo())
892 const label nRecv = recvSizes[proci];
894 constructMap[proci].setSize(nRecv);
896 for (label i = 0; i < nRecv; i++)
898 constructMap[proci][i] = constructSize++;
909 std::move(constructMap)
915template<
class ParticleType>
921 const globalIndexAndTransform& globalTransforms =
922 mesh_.globalData().globalTransforms();
924 referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
928 forAll(referredParticles_, i)
930 referredParticles_[i].clear();
936 forAll(cellIndexAndTransformToDistribute_, i)
938 const labelPair ciat = cellIndexAndTransformToDistribute_[i];
940 label cellIndex = globalTransforms.index(ciat);
942 List<ParticleType*> realParticles =
cellOccupancy[cellIndex];
944 IDLList<ParticleType>& particlesToRefer = referredParticles_[i];
948 const ParticleType& particle = *realParticles[rM];
950 particlesToRefer.append(particle.clone().ptr());
952 prepareParticleToBeReferred(particlesToRefer.last(), ciat);
958template<
class ParticleType>
961 ParticleType* particle,
965 const globalIndexAndTransform& globalTransforms =
966 mesh_.globalData().globalTransforms();
968 const vectorTensorTransform&
transform = globalTransforms.transform
970 globalTransforms.transformIndex(ciat)
973 particle->prepareForInteractionListReferral(transform);
977template<
class ParticleType>
982 forAll(referredParticles_, refCelli)
984 const IDLList<ParticleType>& refCell =
985 referredParticles_[refCelli];
987 for (
const ParticleType&
p : refCell)
991 static_cast<ParticleType*
>(
p.clone().ptr())
999template<
class ParticleType>
1002 const globalIndexAndTransform& globalTransforms =
1003 mesh_.globalData().globalTransforms();
1005 referredWallData_.setSize
1007 wallFaceIndexAndTransformToDistribute_.size()
1012 forAll(referredWallData_, rWVI)
1014 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWVI];
1016 label wallFaceIndex = globalTransforms.index(wfiat);
1018 const vectorTensorTransform&
transform = globalTransforms.transform
1020 globalTransforms.transformIndex(wfiat)
1023 label patchi = mesh_.boundaryMesh().patchID()
1025 wallFaceIndex - mesh_.nInternalFaces()
1030 - mesh_.boundaryMesh()[patchi].start();
1034 referredWallData_[rWVI] =
U.boundaryField()[patchi][patchFacei];
1038 referredWallData_[rWVI] =
1039 transform.R().T() & referredWallData_[rWVI];
1045template<
class ParticleType>
1048 if (referredWallFaces_.empty())
1053 fileName objDir = mesh_.time().timePath()/cloud::prefix;
1057 fileName objFileName =
"referredWallFaces.obj";
1059 OFstream str(objDir/objFileName);
1062 << mesh_.time().timeName()/cloud::prefix/objFileName
1067 forAll(referredWallFaces_, rWFI)
1069 const referredWallFace& rwf = referredWallFaces_[rWFI];
1073 meshTools::writeOBJ(str, rwf.points()[rwf[fPtI]]);
1080 str<<
' ' << fPtI + offset;
1085 offset += rwf.size();
1092template<
class ParticleType>
1096 cloud_(mesh_,
"nullptr_Cloud",
IDLList<ParticleType>()),
1105 cellIndexAndTransformToDistribute_(),
1106 wallFaceIndexAndTransformToDistribute_(),
1107 referredWallFaces_(),
1108 UName_(
"unknown_U"),
1109 referredWallData_(),
1110 referredParticles_()
1114template<
class ParticleType>
1124 cloud_(mesh_,
"referredParticleCloud",
IDLList<ParticleType>()),
1125 writeCloud_(writeCloud),
1128 maxDistance_(maxDistance),
1133 cellIndexAndTransformToDistribute_(),
1134 wallFaceIndexAndTransformToDistribute_(),
1135 referredWallFaces_(),
1137 referredWallData_(),
1138 referredParticles_()
1140 buildInteractionLists();
1146template<
class ParticleType>
1153template<
class ParticleType>
1160 if (mesh_.changing())
1163 <<
"Mesh changing, rebuilding InteractionLists from scratch."
1166 buildInteractionLists();
1169 prepareWallDataToRefer();
1175 const labelList& subMap = cellMap().subMap()[domain];
1187 forAll(subMappedParticles, i)
1189 toDomain << subMappedParticles[i];
1197 wallFaceMap().send(pBufs, referredWallData_);
1201template<
class ParticleType>
1205 const label startOfRequests
1210 referredParticles_.setSize(cellMap().constructSize());
1214 const labelList& constructMap = cellMap().constructMap()[domain];
1216 if (constructMap.
size())
1225 typename ParticleType::iNew(mesh_)
1231 forAll(referredParticles_, refCelli)
1234 for (ParticleType&
p : refCell)
1236 p.correctAfterInteractionListReferral(ril_[refCelli][0]);
1240 fillReferredParticleCloud();
1242 wallFaceMap().receive(pBufs, referredWallData_);
const List< DynamicList< molecule * > > & cellOccupancy
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Template class for intrusive linked lists.
Builds direct interaction list, specifying which local (real) cells are potentially in range of each ...
void sendReferredData(const List< DynamicList< ParticleType * > > &cellOccupancy, PstreamBuffers &pBufs)
Prepare and send referred particles and wall data,.
void receiveReferredData(PstreamBuffers &pBufs, const label startReq=0)
Receive referred data.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Buffers for inter-processor communications streams (UOPstream, UIPstream).
UPstream::rangeType allProcs() const noexcept
Range of ranks indices associated with PstreamBuffers.
A List with indirect addressing. Like IndirectList but does not store addressing.
void size(const label n)
Older name for setAddressableSize.
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
Mesh consisting of general polyhedral cells.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
const std::string patch
OpenFOAM patch number as a std::string.
Pair< label > labelPair
A pair of labels.
void inplaceSubset(const BoolListType &select, ListType &input, const bool invert=false)
Inplace extract elements of the input list when select is true.
GeometricField< vector, fvPatchField, volMesh > volVectorField
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
List< label > labelList
A List of labels.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
List< labelList > labelListList
A List of labelList.
List< treeBoundBox > treeBoundBoxList
List of bounding boxes.
List< bool > boolList
A List of bools.
constexpr char nl
The newline '\n' character (0x0a)
#define forAll(list, i)
Loop across all elements in list.
const word UName(propsDict.getOrDefault< word >("U", "U"))