39 template<
class ParticleType>
42 Info<<
"Building InteractionLists with interaction distance " 43 << maxDistance_ <<
endl;
47 treeBoundBox procBb(mesh_.points());
51 allExtendedProcBbs[Pstream::myProcNo()] = procBb;
52 allExtendedProcBbs[Pstream::myProcNo()].grow(maxDistance_);
54 Pstream::allGatherList(allExtendedProcBbs);
56 List<treeBoundBox> extendedProcBbsInRange;
57 List<label> extendedProcBbsTransformIndex;
58 List<label> extendedProcBbsOrigProc;
60 findExtendedProcBbsInRange
64 mesh_.globalData().globalTransforms(),
65 extendedProcBbsInRange,
66 extendedProcBbsTransformIndex,
67 extendedProcBbsOrigProc
72 const globalIndexAndTransform& globalTransforms =
73 mesh_.globalData().globalTransforms();
78 bitSet cellInRangeOfCoupledPatch(mesh_.nCells(),
false);
82 DynamicList<labelPair> cellIAndTToExchange;
84 DynamicList<treeBoundBox> cellBbsToExchange;
86 DynamicList<label> procToDistributeCellTo;
88 forAll(extendedProcBbsInRange, ePBIRI)
90 const treeBoundBox& otherExtendedProcBb =
91 extendedProcBbsInRange[ePBIRI];
93 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
95 label origProc = extendedProcBbsOrigProc[ePBIRI];
99 const treeBoundBox& cellBb = cellBbs[celli];
101 if (cellBb.overlaps(otherExtendedProcBb))
106 cellInRangeOfCoupledPatch.set(celli);
108 cellIAndTToExchange.append
110 globalTransforms.encode(celli, transformIndex)
113 cellBbsToExchange.append(cellBb);
115 procToDistributeCellTo.append(origProc);
120 buildMap(cellMapPtr_, procToDistributeCellTo);
123 label preDistributionCellMapSize = procToDistributeCellTo.size();
125 cellMap().distribute(cellBbsToExchange);
127 cellMap().distribute(cellIAndTToExchange);
131 DynamicList<label> coupledPatchRangeCells;
133 forAll(cellInRangeOfCoupledPatch, celli)
135 if (cellInRangeOfCoupledPatch[celli])
137 coupledPatchRangeCells.append(celli);
141 treeBoundBox procBbRndExt
143 treeBoundBox(mesh_.points()).extend(
rndGen, 1
e-4)
146 indexedOctree<treeDataCell> coupledPatchRangeTree
152 coupledPatchRangeCells,
161 ril_.setSize(cellBbsToExchange.size());
165 boolList cellBbRequiredByAnyCell(cellBbsToExchange.size(),
false);
167 Info<<
" Building referred interaction lists" <<
endl;
169 forAll(cellBbsToExchange, bbI)
171 const labelPair& ciat = cellIAndTToExchange[bbI];
173 const vectorTensorTransform&
transform = globalTransforms.transform
175 globalTransforms.transformIndex(ciat)
178 treeBoundBox extendedBb
180 transform.invTransformPosition(cellBbsToExchange[bbI].points())
182 extendedBb.grow(maxDistance_);
187 coupledPatchRangeTree.findBox(extendedBb)
190 if (!interactingElems.empty())
192 cellBbRequiredByAnyCell[bbI] =
true;
195 ril_[bbI].
setSize(interactingElems.size(), -1);
197 forAll(interactingElems, i)
199 label elemI = interactingElems[i];
205 label
c = coupledPatchRangeTree.shapes().objectIndex(elemI);
228 cellBbsToExchange.clearStorage();
230 cellMap().reverseDistribute
232 preDistributionCellMapSize,
233 cellBbRequiredByAnyCell
236 cellMap().reverseDistribute
238 preDistributionCellMapSize,
245 preDistributionCellMapSize = -1;
252 inplaceSubset(cellBbRequiredByAnyCell, procToDistributeCellTo);
254 preDistributionCellMapSize = procToDistributeCellTo.size();
257 buildMap(cellMapPtr_, procToDistributeCellTo);
260 cellIndexAndTransformToDistribute_.transfer(cellIAndTToExchange);
264 rilInverse_.setSize(mesh_.nCells());
267 List<DynamicList<label>> rilInverseTemp(rilInverse_.size());
272 const labelList& realCells = ril_[refCelli];
278 forAll(realCells, realCelli)
280 rilInverseTemp[realCells[realCelli]].append(refCelli);
284 forAll(rilInverse_, celli)
286 rilInverse_[celli].transfer(rilInverseTemp[celli]);
293 mesh_.boundaryMesh().checkParallelSync(
true);
296 DynamicList<label> localWallFaces;
298 for (
const polyPatch&
patch : mesh_.boundaryMesh())
300 if (isA<wallPolyPatch>(
patch))
304 forAll(areaFraction, facei)
306 if (areaFraction[facei] > 0.5)
308 localWallFaces.append(facei +
patch.start());
322 mesh_.faces()[localWallFaces[i]]
327 DynamicList<labelPair> wallFaceIAndTToExchange;
329 DynamicList<treeBoundBox> wallFaceBbsToExchange;
331 DynamicList<label> procToDistributeWallFaceTo;
333 forAll(extendedProcBbsInRange, ePBIRI)
335 const treeBoundBox& otherExtendedProcBb =
336 extendedProcBbsInRange[ePBIRI];
338 label transformIndex = extendedProcBbsTransformIndex[ePBIRI];
340 label origProc = extendedProcBbsOrigProc[ePBIRI];
344 const treeBoundBox& wallFaceBb = wallFaceBbs[i];
346 if (wallFaceBb.overlaps(otherExtendedProcBb))
351 label wallFacei = localWallFaces[i];
353 wallFaceIAndTToExchange.append
355 globalTransforms.encode(wallFacei, transformIndex)
358 wallFaceBbsToExchange.append(wallFaceBb);
360 procToDistributeWallFaceTo.append(origProc);
365 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
368 label preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
370 wallFaceMap().distribute(wallFaceBbsToExchange);
372 wallFaceMap().distribute(wallFaceIAndTToExchange);
374 indexedOctree<treeDataCell> allCellsTree
376 treeDataCell(
true, mesh_, polyMesh::CELL_TETS),
383 rwfil_.setSize(wallFaceBbsToExchange.size());
387 boolList wallFaceBbRequiredByAnyCell(wallFaceBbsToExchange.size(),
false);
389 forAll(wallFaceBbsToExchange, bbI)
391 const labelPair& wfiat = wallFaceIAndTToExchange[bbI];
393 const vectorTensorTransform&
transform = globalTransforms.transform
395 globalTransforms.transformIndex(wfiat)
398 treeBoundBox extendedBb
400 transform.invTransformPosition(wallFaceBbsToExchange[bbI].points())
402 extendedBb.grow(maxDistance_);
407 coupledPatchRangeTree.findBox(extendedBb)
410 if (!interactingElems.empty())
412 wallFaceBbRequiredByAnyCell[bbI] =
true;
415 rwfil_[bbI].
setSize(interactingElems.size(), -1);
417 forAll(interactingElems, i)
419 label elemI = interactingElems[i];
425 label
c = coupledPatchRangeTree.shapes().objectIndex(elemI);
448 wallFaceBbsToExchange.setSize(0);
450 wallFaceMap().reverseDistribute
452 preDistributionWallFaceMapSize,
453 wallFaceBbRequiredByAnyCell
456 wallFaceMap().reverseDistribute
458 preDistributionWallFaceMapSize,
459 wallFaceIAndTToExchange
465 preDistributionWallFaceMapSize = -1;
470 inplaceSubset(wallFaceBbRequiredByAnyCell, wallFaceIAndTToExchange);
472 inplaceSubset(wallFaceBbRequiredByAnyCell, procToDistributeWallFaceTo);
474 preDistributionWallFaceMapSize = procToDistributeWallFaceTo.size();
477 buildMap(wallFaceMapPtr_, procToDistributeWallFaceTo);
480 wallFaceIndexAndTransformToDistribute_.transfer(wallFaceIAndTToExchange);
484 rwfilInverse_.setSize(mesh_.nCells());
487 List<DynamicList<label>> rwfilInverseTemp(rwfilInverse_.size());
490 forAll(rwfil_, refWallFacei)
492 const labelList& realCells = rwfil_[refWallFacei];
498 forAll(realCells, realCelli)
500 rwfilInverseTemp[realCells[realCelli]].append(refWallFacei);
504 forAll(rwfilInverse_, celli)
506 rwfilInverse_[celli].transfer(rwfilInverseTemp[celli]);
510 referredWallFaces_.setSize(wallFaceIndexAndTransformToDistribute_.size());
512 forAll(referredWallFaces_, rWFI)
514 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWFI];
516 label wallFaceIndex = globalTransforms.index(wfiat);
518 const vectorTensorTransform&
transform = globalTransforms.transform
520 globalTransforms.transformIndex(wfiat)
523 const face&
f = mesh_.faces()[wallFaceIndex];
525 const label patchi = mesh_.boundaryMesh().patchID(wallFaceIndex);
527 referredWallFaces_[rWFI] = referredWallFace
530 transform.invTransformPosition(
f.points(mesh_.points())),
535 wallFaceMap().distribute(referredWallFaces_);
539 writeReferredWallFaces();
544 Info<<
" Building direct interaction lists" <<
endl;
546 indexedOctree<treeDataFace> wallFacesTree
548 treeDataFace(
true, mesh_, localWallFaces),
555 dil_.setSize(mesh_.nCells());
557 dwfil_.setSize(mesh_.nCells());
561 const treeBoundBox& cellBb = cellBbs[celli];
563 treeBoundBox extendedBb(cellBb);
564 extendedBb.grow(maxDistance_);
567 labelList interactingElems(allCellsTree.findBox(extendedBb));
570 DynamicList<label> cellDIL(interactingElems.size());
572 for (
const label elemi : interactingElems)
574 const label
c = allCellsTree.shapes().objectIndex(elemi);
588 dil_[celli].transfer(cellDIL);
591 interactingElems = wallFacesTree.findBox(extendedBb);
593 dwfil_[celli].setSize(interactingElems.size(), -1);
595 forAll(interactingElems, i)
597 const label elemi = interactingElems[i];
599 const label
f = wallFacesTree.shapes().objectIndex(elemi);
601 dwfil_[celli][i] =
f;
607 template<
class ParticleType>
610 const treeBoundBox& procBb,
611 const List<treeBoundBox>& allExtendedProcBbs,
612 const globalIndexAndTransform& globalTransforms,
613 List<treeBoundBox>& extendedProcBbsInRange,
614 List<label>& extendedProcBbsTransformIndex,
615 List<label>& extendedProcBbsOrigProc
618 extendedProcBbsInRange.setSize(0);
619 extendedProcBbsTransformIndex.setSize(0);
620 extendedProcBbsOrigProc.setSize(0);
622 DynamicList<treeBoundBox> tmpExtendedProcBbsInRange;
623 DynamicList<label> tmpExtendedProcBbsTransformIndex;
624 DynamicList<label> tmpExtendedProcBbsOrigProc;
626 label nTrans = globalTransforms.nIndependentTransforms();
628 forAll(allExtendedProcBbs, proci)
632 if (nTrans == 0 && proci != Pstream::myProcNo())
634 treeBoundBox extendedReferredProcBb = allExtendedProcBbs[proci];
636 if (procBb.overlaps(extendedReferredProcBb))
638 tmpExtendedProcBbsInRange.append(extendedReferredProcBb);
642 tmpExtendedProcBbsTransformIndex.append(0);
644 tmpExtendedProcBbsOrigProc.append(proci);
647 else if (nTrans == 3)
649 label& i = permutationIndices[0];
650 label& j = permutationIndices[1];
651 label&
k = permutationIndices[2];
653 for (i = -1; i <= 1; i++)
655 for (j = -1; j <= 1; j++)
657 for (
k = -1;
k <= 1;
k++)
664 && proci == Pstream::myProcNo()
672 label transI = globalTransforms.encodeTransformIndex
678 globalTransforms.transform(transI);
680 treeBoundBox extendedReferredProcBb
684 allExtendedProcBbs[proci].points()
688 if (procBb.overlaps(extendedReferredProcBb))
690 tmpExtendedProcBbsInRange.append
692 extendedReferredProcBb
695 tmpExtendedProcBbsTransformIndex.append(transI);
697 tmpExtendedProcBbsOrigProc.append(proci);
703 else if (nTrans == 2)
705 label& i = permutationIndices[0];
706 label& j = permutationIndices[1];
708 for (i = -1; i <= 1; i++)
710 for (j = -1; j <= 1; j++)
712 if (i == 0 && j == 0 && proci == Pstream::myProcNo())
719 label transI = globalTransforms.encodeTransformIndex
725 globalTransforms.transform(transI);
727 treeBoundBox extendedReferredProcBb
731 allExtendedProcBbs[proci].points()
735 if (procBb.overlaps(extendedReferredProcBb))
737 tmpExtendedProcBbsInRange.append
739 extendedReferredProcBb
742 tmpExtendedProcBbsTransformIndex.append(transI);
744 tmpExtendedProcBbsOrigProc.append(proci);
749 else if (nTrans == 1)
751 label& i = permutationIndices[0];
753 for (i = -1; i <= 1; i++)
755 if (i == 0 && proci == Pstream::myProcNo())
762 label transI = globalTransforms.encodeTransformIndex
768 globalTransforms.transform(transI);
770 treeBoundBox extendedReferredProcBb
774 allExtendedProcBbs[proci].points()
778 if (procBb.overlaps(extendedReferredProcBb))
780 tmpExtendedProcBbsInRange.append
782 extendedReferredProcBb
785 tmpExtendedProcBbsTransformIndex.append(transI);
787 tmpExtendedProcBbsOrigProc.append(proci);
793 extendedProcBbsInRange.transfer(tmpExtendedProcBbsInRange);
794 extendedProcBbsTransformIndex.transfer(tmpExtendedProcBbsTransformIndex);
795 extendedProcBbsOrigProc.transfer(tmpExtendedProcBbsOrigProc);
799 template<
class ParticleType>
802 autoPtr<mapDistribute>& mapPtr,
803 const List<label>& toProc
812 for (
const label proci : toProc)
822 sendMap[proci].resize_nocopy(nSend[proci]);
829 label proci = toProc[i];
830 sendMap[proci][nSend[proci]++] = i;
833 mapPtr.reset(
new mapDistribute(std::move(sendMap)));
837 template<
class ParticleType>
843 const globalIndexAndTransform& globalTransforms =
844 mesh_.globalData().globalTransforms();
846 referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
850 forAll(referredParticles_, i)
852 referredParticles_[i].clear();
858 forAll(cellIndexAndTransformToDistribute_, i)
860 const labelPair ciat = cellIndexAndTransformToDistribute_[i];
862 label cellIndex = globalTransforms.index(ciat);
864 List<ParticleType*> realParticles =
cellOccupancy[cellIndex];
866 IDLList<ParticleType>& particlesToRefer = referredParticles_[i];
870 const ParticleType& particle = *realParticles[rM];
872 particlesToRefer.append(particle.clone().ptr());
874 prepareParticleToBeReferred(particlesToRefer.last(), ciat);
880 template<
class ParticleType>
883 ParticleType* particle,
887 const globalIndexAndTransform& globalTransforms =
888 mesh_.globalData().globalTransforms();
890 const vectorTensorTransform&
transform = globalTransforms.transform
892 globalTransforms.transformIndex(ciat)
895 particle->prepareForInteractionListReferral(
transform);
899 template<
class ParticleType>
904 forAll(referredParticles_, refCelli)
906 const IDLList<ParticleType>& refCell =
907 referredParticles_[refCelli];
909 for (
const ParticleType&
p : refCell)
913 static_cast<ParticleType*>(
p.clone().ptr())
921 template<
class ParticleType>
924 const globalIndexAndTransform& globalTransforms =
925 mesh_.globalData().globalTransforms();
927 referredWallData_.setSize
929 wallFaceIndexAndTransformToDistribute_.size()
934 forAll(referredWallData_, rWVI)
936 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWVI];
938 label wallFaceIndex = globalTransforms.index(wfiat);
940 const vectorTensorTransform&
transform = globalTransforms.transform
942 globalTransforms.transformIndex(wfiat)
945 const label patchi = mesh_.boundaryMesh().patchID(wallFaceIndex);
947 const label patchFacei =
948 mesh_.boundaryMesh()[patchi].whichFace(wallFaceIndex);
952 referredWallData_[rWVI] =
U.boundaryField()[patchi][patchFacei];
956 referredWallData_[rWVI] =
957 transform.R().T() & referredWallData_[rWVI];
963 template<
class ParticleType>
966 if (referredWallFaces_.empty())
971 fileName objDir = mesh_.time().timePath()/cloud::prefix;
975 fileName objFileName =
"referredWallFaces.obj";
977 OFstream str(objDir/objFileName);
980 << mesh_.time().timeName()/cloud::prefix/objFileName
985 forAll(referredWallFaces_, rWFI)
987 const referredWallFace& rwf = referredWallFaces_[rWFI];
998 str<<
' ' << fPtI + offset;
1003 offset += rwf.size();
1010 template<
class ParticleType>
1014 cloud_(mesh_,
"nullptr_Cloud",
IDLList<ParticleType>()),
1023 cellIndexAndTransformToDistribute_(),
1024 wallFaceIndexAndTransformToDistribute_(),
1025 referredWallFaces_(),
1026 UName_(
"unknown_U"),
1027 referredWallData_(),
1028 referredParticles_()
1032 template<
class ParticleType>
1042 cloud_(mesh_,
"referredParticleCloud",
IDLList<ParticleType>()),
1043 writeCloud_(writeCloud),
1046 maxDistance_(maxDistance),
1051 cellIndexAndTransformToDistribute_(),
1052 wallFaceIndexAndTransformToDistribute_(),
1053 referredWallFaces_(),
1055 referredWallData_(),
1056 referredParticles_()
1058 buildInteractionLists();
1064 template<
class ParticleType>
1071 template<
class ParticleType>
1078 if (mesh_.changing())
1081 <<
"Mesh changing, rebuilding InteractionLists from scratch." 1084 buildInteractionLists();
1087 prepareWallDataToRefer();
1091 for (
const int domain : Pstream::allProcs())
1093 const labelList& subMap = cellMap().subMap()[domain];
1097 UOPstream toDomain(domain, pBufs);
1099 UIndirectList<IDLList<ParticleType>> subMappedParticles
1105 forAll(subMappedParticles, i)
1107 toDomain << subMappedParticles[i];
1115 wallFaceMap().send(pBufs, referredWallData_);
1119 template<
class ParticleType>
1123 const label startOfRequests
1126 Pstream::waitRequests(startOfRequests);
1128 referredParticles_.setSize(cellMap().constructSize());
1130 for (
const int domain : Pstream::allProcs())
1132 const labelList& constructMap = cellMap().constructMap()[domain];
1134 if (constructMap.
size())
1143 typename ParticleType::iNew(mesh_)
1149 forAll(referredParticles_, refCelli)
1151 IDLList<ParticleType>& refCell = referredParticles_[refCelli];
1152 for (ParticleType&
p : refCell)
1154 p.correctAfterInteractionListReferral(ril_[refCelli][0]);
1158 fillReferredParticleCloud();
1160 wallFaceMap().receive(pBufs, referredWallData_);
Template class for intrusive linked lists.
void size(const label n)
Older name for setAddressableSize.
Builds direct interaction list, specifying which local (real) cells are potentially in range of each ...
const word UName(propsDict.getOrDefault< word >("U", "U"))
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
List< treeBoundBox > treeBoundBoxList
A List of treeBoundBox.
label k
Boltzmann constant.
GeometricField< vector, fvPatchField, volMesh > volVectorField
void inplaceSubset(const BoolListType &select, ListType &input, const bool invert=false)
Inplace extract elements of the input list when select is true.
List< labelList > labelListList
List of labelList.
#define forAll(list, i)
Loop across all elements in list.
Input inter-processor communications stream using MPI send/recv etc. - operating on external buffer...
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
ILList< DLListBase, T > IDLList
void receiveReferredData(PstreamBuffers &pBufs, const label startReq=0)
Receive referred data.
Pair< label > labelPair
A pair of labels.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
const List< DynamicList< molecule * > > & cellOccupancy
#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.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Mesh consisting of general polyhedral cells.
List< label > labelList
A List of labels.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
List< bool > boolList
A List of bools.
void sendReferredData(const List< DynamicList< ParticleType *>> &cellOccupancy, PstreamBuffers &pBufs)
Prepare and send referred particles and wall data,.
static constexpr const zero Zero
Global zero (0)