36 template<
class ParticleType>
39 Info<<
"Building InteractionLists with interaction distance " 40 << maxDistance_ <<
endl;
44 const vector interactionVec = maxDistance_*vector::one;
46 treeBoundBox procBb(treeBoundBox(mesh_.points()));
48 treeBoundBox extendedProcBb
50 procBb.min() - interactionVec,
51 procBb.max() + interactionVec
56 allExtendedProcBbs[Pstream::myProcNo()] = extendedProcBb;
58 Pstream::gatherList(allExtendedProcBbs);
60 Pstream::scatterList(allExtendedProcBbs);
62 List<treeBoundBox> extendedProcBbsInRange;
63 List<label> extendedProcBbsTransformIndex;
64 List<label> extendedProcBbsOrigProc;
66 findExtendedProcBbsInRange
70 mesh_.globalData().globalTransforms(),
71 extendedProcBbsInRange,
72 extendedProcBbsTransformIndex,
73 extendedProcBbsOrigProc
80 cellBbs[celli] = treeBoundBox
82 mesh_.cells()[celli].points
90 const globalIndexAndTransform& globalTransforms =
91 mesh_.globalData().globalTransforms();
96 PackedBoolList cellInRangeOfCoupledPatch(mesh_.nCells(),
false);
100 DynamicList<labelPair> cellIAndTToExchange;
102 DynamicList<treeBoundBox> cellBbsToExchange;
104 DynamicList<label> procToDistributeCellTo;
106 forAll(extendedProcBbsInRange, ePBIRI)
108 const treeBoundBox& otherExtendedProcBb =
109 extendedProcBbsInRange[ePBIRI];
111 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
113 label origProc = extendedProcBbsOrigProc[ePBIRI];
117 const treeBoundBox& cellBb = cellBbs[celli];
119 if (cellBb.overlaps(otherExtendedProcBb))
124 cellInRangeOfCoupledPatch[celli] =
true;
126 cellIAndTToExchange.append
128 globalTransforms.encode(celli, transformIndex)
131 cellBbsToExchange.append(cellBb);
133 procToDistributeCellTo.append(origProc);
138 buildMap(cellMapPtr_, procToDistributeCellTo);
141 label preDistributionCellMapSize = procToDistributeCellTo.size();
143 cellMap().distribute(cellBbsToExchange);
145 cellMap().distribute(cellIAndTToExchange);
149 DynamicList<label> coupledPatchRangeCells;
151 forAll(cellInRangeOfCoupledPatch, celli)
153 if (cellInRangeOfCoupledPatch[celli])
155 coupledPatchRangeCells.append(celli);
159 treeBoundBox procBbRndExt
161 treeBoundBox(mesh_.points()).extend(
rndGen, 1
e-4)
164 indexedOctree<treeDataCell> coupledPatchRangeTree
170 coupledPatchRangeCells,
179 ril_.setSize(cellBbsToExchange.size());
183 boolList cellBbRequiredByAnyCell(cellBbsToExchange.size(),
false);
185 Info<<
" Building referred interaction lists" <<
endl;
187 forAll(cellBbsToExchange, bbI)
189 const labelPair& ciat = cellIAndTToExchange[bbI];
191 const vectorTensorTransform& transform = globalTransforms.transform
193 globalTransforms.transformIndex(ciat)
196 treeBoundBox tempTransformedBb
198 transform.invTransformPosition(cellBbsToExchange[bbI].points())
201 treeBoundBox extendedBb
203 tempTransformedBb.min() - interactionVec,
204 tempTransformedBb.max() + interactionVec
210 coupledPatchRangeTree.findBox(extendedBb)
213 if (!interactingElems.empty())
215 cellBbRequiredByAnyCell[bbI] =
true;
218 ril_[bbI].
setSize(interactingElems.size(), -1);
220 forAll(interactingElems, i)
222 label elemI = interactingElems[i];
228 label c = coupledPatchRangeTree.shapes().cellLabels()[elemI];
251 cellBbsToExchange.setSize(0);
253 cellMap().reverseDistribute
255 preDistributionCellMapSize,
256 cellBbRequiredByAnyCell
259 cellMap().reverseDistribute
261 preDistributionCellMapSize,
268 preDistributionCellMapSize = -1;
275 inplaceSubset(cellBbRequiredByAnyCell, procToDistributeCellTo);
277 preDistributionCellMapSize = procToDistributeCellTo.size();
280 buildMap(cellMapPtr_, procToDistributeCellTo);
283 cellIndexAndTransformToDistribute_.transfer(cellIAndTToExchange);
287 rilInverse_.setSize(mesh_.nCells());
290 List<DynamicList<label>> rilInverseTemp(rilInverse_.size());
295 const labelList& realCells = ril_[refCelli];
301 forAll(realCells, realCelli)
303 rilInverseTemp[realCells[realCelli]].append(refCelli);
307 forAll(rilInverse_, celli)
309 rilInverse_[celli].transfer(rilInverseTemp[celli]);
316 mesh_.boundaryMesh().checkParallelSync(
true);
319 DynamicList<label> localWallFaces;
323 const polyPatch& patch = mesh_.boundaryMesh()[
patchi];
325 if (isA<wallPolyPatch>(patch))
327 localWallFaces.append(
identity(patch.size()) + patch.start());
335 wallFaceBbs[i] = treeBoundBox
337 mesh_.faces()[localWallFaces[i]].points(mesh_.points())
342 DynamicList<labelPair> wallFaceIAndTToExchange;
344 DynamicList<treeBoundBox> wallFaceBbsToExchange;
346 DynamicList<label> procToDistributeWallFaceTo;
348 forAll(extendedProcBbsInRange, ePBIRI)
350 const treeBoundBox& otherExtendedProcBb =
351 extendedProcBbsInRange[ePBIRI];
353 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
355 label origProc = extendedProcBbsOrigProc[ePBIRI];
359 const treeBoundBox& wallFaceBb = wallFaceBbs[i];
361 if (wallFaceBb.overlaps(otherExtendedProcBb))
366 label wallFacei = localWallFaces[i];
368 wallFaceIAndTToExchange.append
370 globalTransforms.encode(wallFacei, transformIndex)
373 wallFaceBbsToExchange.append(wallFaceBb);
375 procToDistributeWallFaceTo.append(origProc);
380 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
383 label preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
385 wallFaceMap().distribute(wallFaceBbsToExchange);
387 wallFaceMap().distribute(wallFaceIAndTToExchange);
389 indexedOctree<treeDataCell> allCellsTree
391 treeDataCell(
true, mesh_, polyMesh::CELL_TETS),
398 rwfil_.setSize(wallFaceBbsToExchange.size());
402 boolList wallFaceBbRequiredByAnyCell(wallFaceBbsToExchange.size(),
false);
404 forAll(wallFaceBbsToExchange, bbI)
406 const labelPair& wfiat = wallFaceIAndTToExchange[bbI];
408 const vectorTensorTransform& transform = globalTransforms.transform
410 globalTransforms.transformIndex(wfiat)
413 treeBoundBox tempTransformedBb
415 transform.invTransformPosition(wallFaceBbsToExchange[bbI].points())
418 treeBoundBox extendedBb
420 tempTransformedBb.min() - interactionVec,
421 tempTransformedBb.max() + interactionVec
427 coupledPatchRangeTree.findBox(extendedBb)
430 if (!interactingElems.empty())
432 wallFaceBbRequiredByAnyCell[bbI] =
true;
435 rwfil_[bbI].
setSize(interactingElems.size(), -1);
437 forAll(interactingElems, i)
439 label elemI = interactingElems[i];
445 label c = coupledPatchRangeTree.shapes().cellLabels()[elemI];
468 wallFaceBbsToExchange.setSize(0);
470 wallFaceMap().reverseDistribute
472 preDistributionWallFaceMapSize,
473 wallFaceBbRequiredByAnyCell
476 wallFaceMap().reverseDistribute
478 preDistributionWallFaceMapSize,
479 wallFaceIAndTToExchange
485 preDistributionWallFaceMapSize = -1;
490 inplaceSubset(wallFaceBbRequiredByAnyCell, wallFaceIAndTToExchange);
492 inplaceSubset(wallFaceBbRequiredByAnyCell, procToDistributeWallFaceTo);
494 preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
497 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
500 wallFaceIndexAndTransformToDistribute_.transfer(wallFaceIAndTToExchange);
504 rwfilInverse_.setSize(mesh_.nCells());
507 List<DynamicList<label>> rwfilInverseTemp(rwfilInverse_.size());
510 forAll(rwfil_, refWallFacei)
512 const labelList& realCells = rwfil_[refWallFacei];
518 forAll(realCells, realCelli)
520 rwfilInverseTemp[realCells[realCelli]].append(refWallFacei);
524 forAll(rwfilInverse_, celli)
526 rwfilInverse_[celli].transfer(rwfilInverseTemp[celli]);
530 referredWallFaces_.setSize(wallFaceIndexAndTransformToDistribute_.size());
532 forAll(referredWallFaces_, rWFI)
534 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWFI];
536 label wallFaceIndex = globalTransforms.index(wfiat);
538 const vectorTensorTransform& transform = globalTransforms.transform
540 globalTransforms.transformIndex(wfiat)
543 const face& f = mesh_.faces()[wallFaceIndex];
545 label patchi = mesh_.boundaryMesh().patchID()
547 wallFaceIndex - mesh_.nInternalFaces()
550 referredWallFaces_[rWFI] = referredWallFace
553 transform.invTransformPosition(f.points(mesh_.points())),
558 wallFaceMap().distribute(referredWallFaces_);
562 writeReferredWallFaces();
567 Info<<
" Building direct interaction lists" <<
endl;
569 indexedOctree<treeDataFace> wallFacesTree
571 treeDataFace(
true, mesh_, localWallFaces),
578 dil_.setSize(mesh_.nCells());
580 dwfil_.setSize(mesh_.nCells());
584 const treeBoundBox& cellBb = cellBbs[celli];
586 treeBoundBox extendedBb
588 cellBb.min() - interactionVec,
589 cellBb.max() + interactionVec
593 labelList interactingElems(allCellsTree.findBox(extendedBb));
596 DynamicList<label> cellDIL(interactingElems.size());
598 forAll(interactingElems, i)
600 label elemI = interactingElems[i];
602 label c = allCellsTree.shapes().cellLabels()[elemI];
616 dil_[celli].transfer(cellDIL);
619 interactingElems = wallFacesTree.findBox(extendedBb);
621 dwfil_[celli].setSize(interactingElems.size(), -1);
623 forAll(interactingElems, i)
625 label elemI = interactingElems[i];
627 label f = wallFacesTree.shapes().faceLabels()[elemI];
629 dwfil_[celli][i] =
f;
635 template<
class ParticleType>
638 const treeBoundBox& procBb,
639 const List<treeBoundBox>& allExtendedProcBbs,
640 const globalIndexAndTransform& globalTransforms,
641 List<treeBoundBox>& extendedProcBbsInRange,
642 List<label>& extendedProcBbsTransformIndex,
643 List<label>& extendedProcBbsOrigProc
646 extendedProcBbsInRange.setSize(0);
647 extendedProcBbsTransformIndex.setSize(0);
648 extendedProcBbsOrigProc.setSize(0);
650 DynamicList<treeBoundBox> tmpExtendedProcBbsInRange;
651 DynamicList<label> tmpExtendedProcBbsTransformIndex;
652 DynamicList<label> tmpExtendedProcBbsOrigProc;
654 label nTrans = globalTransforms.nIndependentTransforms();
656 forAll(allExtendedProcBbs, proci)
658 List<label> permutationIndices(nTrans, 0);
660 if (nTrans == 0 && proci != Pstream::myProcNo())
662 treeBoundBox extendedReferredProcBb = allExtendedProcBbs[proci];
664 if (procBb.overlaps(extendedReferredProcBb))
666 tmpExtendedProcBbsInRange.append(extendedReferredProcBb);
670 tmpExtendedProcBbsTransformIndex.append(0);
672 tmpExtendedProcBbsOrigProc.append(proci);
675 else if (nTrans == 3)
677 label& i = permutationIndices[0];
678 label& j = permutationIndices[1];
679 label& k = permutationIndices[2];
681 for (i = -1; i <= 1; i++)
683 for (j = -1; j <= 1; j++)
685 for (k = -1; k <= 1; k++)
692 && proci == Pstream::myProcNo()
700 label transI = globalTransforms.encodeTransformIndex
705 const vectorTensorTransform& transform =
706 globalTransforms.transform(transI);
708 treeBoundBox extendedReferredProcBb
710 transform.transformPosition
712 allExtendedProcBbs[proci].points()
716 if (procBb.overlaps(extendedReferredProcBb))
718 tmpExtendedProcBbsInRange.append
720 extendedReferredProcBb
723 tmpExtendedProcBbsTransformIndex.append(transI);
725 tmpExtendedProcBbsOrigProc.append(proci);
731 else if (nTrans == 2)
733 label& i = permutationIndices[0];
734 label& j = permutationIndices[1];
736 for (i = -1; i <= 1; i++)
738 for (j = -1; j <= 1; j++)
740 if (i == 0 && j == 0 && proci == Pstream::myProcNo())
747 label transI = globalTransforms.encodeTransformIndex
752 const vectorTensorTransform& transform =
753 globalTransforms.transform(transI);
755 treeBoundBox extendedReferredProcBb
757 transform.transformPosition
759 allExtendedProcBbs[proci].points()
763 if (procBb.overlaps(extendedReferredProcBb))
765 tmpExtendedProcBbsInRange.append
767 extendedReferredProcBb
770 tmpExtendedProcBbsTransformIndex.append(transI);
772 tmpExtendedProcBbsOrigProc.append(proci);
777 else if (nTrans == 1)
779 label& i = permutationIndices[0];
781 for (i = -1; i <= 1; i++)
783 if (i == 0 && proci == Pstream::myProcNo())
790 label transI = globalTransforms.encodeTransformIndex
795 const vectorTensorTransform& transform =
796 globalTransforms.transform(transI);
798 treeBoundBox extendedReferredProcBb
800 transform.transformPosition
802 allExtendedProcBbs[proci].points()
806 if (procBb.overlaps(extendedReferredProcBb))
808 tmpExtendedProcBbsInRange.append
810 extendedReferredProcBb
813 tmpExtendedProcBbsTransformIndex.append(transI);
815 tmpExtendedProcBbsOrigProc.append(proci);
821 extendedProcBbsInRange = tmpExtendedProcBbsInRange.xfer();
822 extendedProcBbsTransformIndex = tmpExtendedProcBbsTransformIndex.xfer();
823 extendedProcBbsOrigProc = tmpExtendedProcBbsOrigProc.xfer();
827 template<
class ParticleType>
830 autoPtr<mapDistribute>& mapPtr,
831 const List<label>& toProc
842 label proci = toProc[i];
852 sendMap[proci].setSize(nSend[proci]);
860 label proci = toProc[i];
862 sendMap[proci][nSend[proci]++] = i;
867 Pstream::exchangeSizes(sendMap, recvSizes);
876 constructMap[Pstream::myProcNo()] =
identity 878 sendMap[Pstream::myProcNo()].size()
881 label constructSize = constructMap[Pstream::myProcNo()].size();
883 forAll(constructMap, proci)
885 if (proci != Pstream::myProcNo())
887 label nRecv = recvSizes[proci];
889 constructMap[proci].setSize(nRecv);
891 for (
label i = 0; i < nRecv; i++)
893 constructMap[proci][i] = constructSize++;
910 template<
class ParticleType>
916 const globalIndexAndTransform& globalTransforms =
917 mesh_.globalData().globalTransforms();
919 referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
923 forAll(referredParticles_, i)
925 referredParticles_[i].clear();
931 forAll(cellIndexAndTransformToDistribute_, i)
933 const labelPair ciat = cellIndexAndTransformToDistribute_[i];
935 label cellIndex = globalTransforms.index(ciat);
937 List<ParticleType*> realParticles =
cellOccupancy[cellIndex];
939 IDLList<ParticleType>& particlesToRefer = referredParticles_[i];
943 const ParticleType& particle = *realParticles[rM];
945 particlesToRefer.append(particle.clone().ptr());
947 prepareParticleToBeReferred(particlesToRefer.last(), ciat);
953 template<
class ParticleType>
956 ParticleType* particle,
960 const globalIndexAndTransform& globalTransforms =
961 mesh_.globalData().globalTransforms();
963 const vectorTensorTransform& transform = globalTransforms.transform
965 globalTransforms.transformIndex(ciat)
968 particle->prepareForInteractionListReferral(transform);
972 template<
class ParticleType>
977 forAll(referredParticles_, refCelli)
979 const IDLList<ParticleType>& refCell =
980 referredParticles_[refCelli];
986 static_cast<ParticleType*>(iter().clone().ptr())
994 template<
class ParticleType>
997 const globalIndexAndTransform& globalTransforms =
998 mesh_.globalData().globalTransforms();
1000 referredWallData_.setSize
1002 wallFaceIndexAndTransformToDistribute_.size()
1007 forAll(referredWallData_, rWVI)
1009 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWVI];
1011 label wallFaceIndex = globalTransforms.index(wfiat);
1013 const vectorTensorTransform& transform = globalTransforms.transform
1015 globalTransforms.transformIndex(wfiat)
1018 label patchi = mesh_.boundaryMesh().patchID()
1020 wallFaceIndex - mesh_.nInternalFaces()
1025 - mesh_.boundaryMesh()[
patchi].start();
1029 referredWallData_[rWVI] = U.boundaryField()[
patchi][patchFacei];
1031 if (transform.hasR())
1033 referredWallData_[rWVI] =
1034 transform.R().T() & referredWallData_[rWVI];
1040 template<
class ParticleType>
1043 if (referredWallFaces_.empty())
1048 fileName objDir = mesh_.time().timePath()/cloud::prefix;
1052 fileName objFileName =
"referredWallFaces.obj";
1054 OFstream str(objDir/objFileName);
1057 << mesh_.time().timeName()/cloud::prefix/objFileName
1062 forAll(referredWallFaces_, rWFI)
1064 const referredWallFace& rwf = referredWallFaces_[rWFI];
1075 str<<
' ' << fPtI + offset;
1080 offset += rwf.size();
1087 template<
class ParticleType>
1091 cloud_(mesh_,
"nullptr_Cloud",
IDLList<ParticleType>()),
1100 cellIndexAndTransformToDistribute_(),
1101 wallFaceIndexAndTransformToDistribute_(),
1102 referredWallFaces_(),
1103 UName_(
"unknown_U"),
1104 referredWallData_(),
1105 referredParticles_()
1109 template<
class ParticleType>
1120 writeCloud_(writeCloud),
1123 maxDistance_(maxDistance),
1128 cellIndexAndTransformToDistribute_(),
1129 wallFaceIndexAndTransformToDistribute_(),
1130 referredWallFaces_(),
1132 referredWallData_(),
1133 referredParticles_()
1135 buildInteractionLists();
1141 template<
class ParticleType>
1148 template<
class ParticleType>
1155 if (mesh_.changing())
1158 <<
"Mesh changing, rebuilding InteractionLists form scratch." 1161 buildInteractionLists();
1164 prepareWallDataToRefer();
1168 for (
label domain = 0; domain < Pstream::nProcs(); domain++)
1170 const labelList& subMap = cellMap().subMap()[domain];
1182 forAll(subMappedParticles, i)
1184 toDomain << subMappedParticles[i];
1192 wallFaceMap().send(pBufs, referredWallData_);
1196 template<
class ParticleType>
1200 const label startOfRequests
1203 Pstream::waitRequests(startOfRequests);
1205 referredParticles_.setSize(cellMap().constructSize());
1207 for (
label domain = 0; domain < Pstream::nProcs(); domain++)
1209 const labelList& constructMap = cellMap().constructMap()[domain];
1211 if (constructMap.
size())
1220 typename ParticleType::iNew(mesh_)
1226 forAll(referredParticles_, refCelli)
1231 iter().correctAfterInteractionListReferral(ril_[refCelli][0]);
1235 fillReferredParticleCloud();
1237 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.
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.
const dimensionedScalar e
Elementary charge.
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.
cachedRandom rndGen(label(0), -1)
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.
Mesh consisting of general polyhedral cells.
void sendReferredData(const List< DynamicList< ParticleType *>> &cellOccupancy, PstreamBuffers &pBufs)
Prepare and send referred particles and wall data,.