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;
321 forAll(mesh_.boundaryMesh(), patchI)
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 sendSizes[Pstream::myProcNo()] = nSend;
861 sendMap[procI].setSize(nSend[procI]);
869 label procI = toProc[i];
871 sendMap[procI][nSend[procI]++] = i;
880 constructMap[Pstream::myProcNo()] =
identity 882 sendMap[Pstream::myProcNo()].size()
885 label constructSize = constructMap[Pstream::myProcNo()].size();
887 forAll(constructMap, procI)
889 if (procI != Pstream::myProcNo())
891 label nRecv = sendSizes[procI][Pstream::myProcNo()];
893 constructMap[procI].setSize(nRecv);
895 for (
label i = 0; i < nRecv; i++)
897 constructMap[procI][i] = constructSize++;
914 template<
class ParticleType>
920 const globalIndexAndTransform& globalTransforms =
921 mesh_.globalData().globalTransforms();
923 referredParticles_.setSize(cellIndexAndTransformToDistribute_.size());
927 forAll(referredParticles_, i)
929 referredParticles_[i].clear();
935 forAll(cellIndexAndTransformToDistribute_, i)
937 const labelPair ciat = cellIndexAndTransformToDistribute_[i];
939 label cellIndex = globalTransforms.index(ciat);
941 List<ParticleType*> realParticles =
cellOccupancy[cellIndex];
943 IDLList<ParticleType>& particlesToRefer = referredParticles_[i];
947 const ParticleType& particle = *realParticles[rM];
949 particlesToRefer.append(particle.clone().ptr());
951 prepareParticleToBeReferred(particlesToRefer.last(), ciat);
957 template<
class ParticleType>
960 ParticleType* particle,
964 const globalIndexAndTransform& globalTransforms =
965 mesh_.globalData().globalTransforms();
967 const vectorTensorTransform& transform = globalTransforms.transform
969 globalTransforms.transformIndex(ciat)
972 particle->position() = transform.invTransformPosition(particle->position());
974 particle->transformProperties(-transform.t());
976 if (transform.hasR())
978 particle->transformProperties(transform.R().T());
983 template<
class ParticleType>
988 forAll(referredParticles_, refCellI)
990 const IDLList<ParticleType>& refCell =
991 referredParticles_[refCellI];
997 static_cast<ParticleType*>(iter().clone().ptr())
1005 template<
class ParticleType>
1008 const globalIndexAndTransform& globalTransforms =
1009 mesh_.globalData().globalTransforms();
1011 referredWallData_.setSize
1013 wallFaceIndexAndTransformToDistribute_.size()
1018 forAll(referredWallData_, rWVI)
1020 const labelPair& wfiat = wallFaceIndexAndTransformToDistribute_[rWVI];
1022 label wallFaceIndex = globalTransforms.index(wfiat);
1024 const vectorTensorTransform& transform = globalTransforms.transform
1026 globalTransforms.transformIndex(wfiat)
1029 label patchI = mesh_.boundaryMesh().patchID()
1031 wallFaceIndex - mesh_.nInternalFaces()
1036 - mesh_.boundaryMesh()[patchI].start();
1040 referredWallData_[rWVI] = U.boundaryField()[patchI][patchFaceI];
1042 if (transform.hasR())
1044 referredWallData_[rWVI] =
1045 transform.R().T() & referredWallData_[rWVI];
1051 template<
class ParticleType>
1054 if (referredWallFaces_.empty())
1059 fileName objDir = mesh_.time().timePath()/cloud::prefix;
1063 fileName objFileName =
"referredWallFaces.obj";
1065 OFstream str(objDir/objFileName);
1068 << mesh_.time().timeName()/cloud::prefix/objFileName
1073 forAll(referredWallFaces_, rWFI)
1075 const referredWallFace& rwf = referredWallFaces_[rWFI];
1086 str<<
' ' << fPtI + offset;
1091 offset += rwf.size();
1098 template<
class ParticleType>
1102 cloud_(mesh_,
"NULL_Cloud",
IDLList<ParticleType>()),
1111 cellIndexAndTransformToDistribute_(),
1112 wallFaceIndexAndTransformToDistribute_(),
1113 referredWallFaces_(),
1114 UName_(
"unknown_UName"),
1115 referredWallData_(),
1116 referredParticles_()
1120 template<
class ParticleType>
1131 writeCloud_(writeCloud),
1134 maxDistance_(maxDistance),
1139 cellIndexAndTransformToDistribute_(),
1140 wallFaceIndexAndTransformToDistribute_(),
1141 referredWallFaces_(),
1143 referredWallData_(),
1144 referredParticles_()
1146 buildInteractionLists();
1152 template<
class ParticleType>
1159 template<
class ParticleType>
1170 "void Foam::InteractionLists<ParticleType>::sendReferredData" 1172 "const List<DynamicList<ParticleType*> >& cellOccupancy," 1173 "PstreamBuffers& pBufs" 1176 <<
"Mesh changing, rebuilding InteractionLists form scratch." 1179 buildInteractionLists();
1182 prepareWallDataToRefer();
1200 forAll(subMappedParticles, i)
1202 toDomain << subMappedParticles[i];
1214 template<
class ParticleType>
1218 const label startOfRequests
1223 referredParticles_.setSize(
cellMap().constructSize());
1229 if (constructMap.
size())
1238 typename ParticleType::iNew(mesh_)
1244 fillReferredParticleCloud();
void receive(PstreamBuffers &, List< T > &) const
Do all receives using PstreamBuffers.
void send(PstreamBuffers &, const List< T > &) const
Do all sends using PstreamBuffers.
const labelListList & subMap() const
From subsetted data back to original data.
const mapDistribute & cellMap() const
Return access to the cellMap.
cachedRandom rndGen(label(0),-1)
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Output inter-processor communications stream operating on external buffer.
Input inter-processor communications stream operating on external buffer.
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
bool changing() const
Is mesh changing (topology changing and/or moving)
A class for handling words, derived from string.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
void size(const label)
Override size to be inconsistent with allocated storage.
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.
void receiveReferredData(PstreamBuffers &pBufs, const label startReq=0)
Receive referred data.
Intrusive doubly-linked list.
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
static label nProcs(const label communicator=0)
Number of processes in parallel run.
void setSize(const label)
Reset size of List.
Ostream & endl(Ostream &os)
Add newline and flush stream.
#define WarningIn(functionName)
Report a warning using Foam::Warning.
A List with indirect addressing.
const dimensionedScalar e
Elementary charge.
List< treeBoundBox > treeBoundBoxList
List of bounding boxes.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Builds direct interaction list, specifying which local (real) cells are potentially in range of each ...
GeometricField< vector, fvPatchField, volMesh > volVectorField
void sendReferredData(const List< DynamicList< ParticleType * > > &cellOccupancy, PstreamBuffers &pBufs)
Prepare and send referred particles and wall data,.
Mesh consisting of general polyhedral cells.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
const List< DynamicList< molecule * > > & cellOccupancy
List< label > labelList
A List of labels.
Pair< label > labelPair
Label pair.
const mapDistribute & wallFaceMap() const
Return access to the wallFaceMap.
const dimensionedScalar c
Speed of light in a vacuum.
Vector< scalar > vector
A scalar version of the templated Vector.
void inplaceSubset(const UList< T > &select, const T &value, ListType &)
Inplace extract elements of List when select is a certain value.
void combineReduce(const List< UPstream::commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
List< labelList > labelListList
A List of labelList.
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
List< bool > boolList
Bool container classes.