46 template<
class Type,
class TrackingData>
76 if (
y.valid(solver_.
data()))
81 meshFacei = patch_.
start() + facei;
103 template<
class Type,
class TrackingData>
107 const label neighbourFacei,
108 const Type& neighbourInfo,
123 const bool propagate =
136 if (changedCell_.set(celli))
138 changedCells_.push_back(celli);
151 template<
class Type,
class TrackingData>
155 const label neighbourCelli,
156 const Type& neighbourInfo,
169 const bool wasValid = faceInfo.valid(td_);
171 const bool propagate =
184 if (changedFace_.set(facei))
186 changedFaces_.push_back(facei);
190 if (!wasValid && faceInfo.valid(td_))
199 template<
class Type,
class TrackingData>
203 const Type& neighbourInfo,
216 const bool wasValid = faceInfo.valid(td_);
218 const bool propagate =
230 if (changedFace_.set(facei))
232 changedFaces_.push_back(facei);
236 if (!wasValid && faceInfo.valid(td_))
245 template<
class Type,
class TrackingData>
254 refCast<const cyclicPolyPatch>(
patch).neighbPatch();
258 const label i1 =
patch.start() + patchFacei;
259 const label i2 = nbrPatch.
start() + patchFacei;
263 !allFaceInfo_[i1].sameGeometry
273 <<
" faceInfo:" << allFaceInfo_[i1]
274 <<
" otherfaceInfo:" << allFaceInfo_[i2]
278 if (changedFace_.test(i1) != changedFace_.test(i2))
281 <<
" faceInfo:" << allFaceInfo_[i1]
282 <<
" otherfaceInfo:" << allFaceInfo_[i2]
283 <<
" changedFace:" << changedFace_.test(i1)
284 <<
" otherchangedFace:" << changedFace_.test(i2)
291 template<
class Type,
class TrackingData>
292 template<
class PatchType>
295 for (
const polyPatch&
p : mesh_.boundaryMesh())
297 if (isA<PatchType>(
p))
306 template<
class Type,
class TrackingData>
313 const bool wasValid = allFaceInfo_[facei].valid(td_);
316 allFaceInfo_[facei] = faceInfo;
319 if (!wasValid && allFaceInfo_[facei].valid(td_))
325 changedFace_.set(facei);
326 changedFaces_.push_back(facei);
330 template<
class Type,
class TrackingData>
337 forAll(changedFaces, changedFacei)
339 const label facei = changedFaces[changedFacei];
341 const bool wasValid = allFaceInfo_[facei].valid(td_);
344 allFaceInfo_[facei] = changedFacesInfo[changedFacei];
347 if (!wasValid && allFaceInfo_[facei].valid(td_))
353 changedFace_.
set(facei);
354 changedFaces_.push_back(facei);
359 template<
class Type,
class TrackingData>
370 for (label changedFacei = 0; changedFacei < nFaces; ++changedFacei)
372 const Type& newInfo = changedFacesInfo[changedFacei];
373 const label patchFacei = changedFaces[changedFacei];
375 const label meshFacei =
patch.start() + patchFacei;
377 Type& currInfo = allFaceInfo_[meshFacei];
379 if (!currInfo.equal(newInfo, td_))
393 template<
class Type,
class TrackingData>
397 const label startFacei,
408 for (label i = 0; i < nFaces; ++i)
410 const label patchFacei = i + startFacei;
411 const label meshFacei =
patch.start() + patchFacei;
413 if (changedFace_.test(meshFacei))
415 changedPatchFaces[nChanged] = patchFacei;
416 changedPatchFacesInfo[nChanged] = allFaceInfo_[meshFacei];
425 template<
class Type,
class TrackingData>
438 for (label i = 0; i < nFaces; ++i)
441 const label meshFacei =
patch.start() + patchFacei;
443 faceInfo[i].leaveDomain(mesh_,
patch, patchFacei, fc[meshFacei], td_);
448 template<
class Type,
class TrackingData>
461 for (label i = 0; i < nFaces; ++i)
464 const label meshFacei =
patch.start() + patchFacei;
466 faceInfo[i].enterDomain(mesh_,
patch, patchFacei, fc[meshFacei], td_);
471 template<
class Type,
class TrackingData>
481 if (rotTensor.
size() == 1)
483 const tensor&
T = rotTensor[0];
485 for (label facei = 0; facei < nFaces; ++facei)
487 faceInfo[facei].transform(mesh_,
T, td_);
492 for (label facei = 0; facei < nFaces; ++facei)
494 faceInfo[facei].transform(mesh_, rotTensor[facei], td_);
500 template<
class Type,
class TrackingData>
504 const label cycOffset,
512 for (label facei = 0; facei < nFaces; ++facei)
514 faces[facei] += cycOffset;
519 template<
class Type,
class TrackingData>
524 const globalMeshData& pData = mesh_.globalData();
527 const labelList& procPatches = pData.processorPatches();
530 const labelList& neighbourProcs = pData.topology().procNeighbours();
539 pBufs_.initRegisterSend();
543 DynamicList<Type> sendFacesInfo;
544 DynamicList<label> sendFaces;
546 for (
const label patchi : procPatches)
548 const auto& procPatch =
549 refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchi]);
551 const label nbrProci = procPatch.neighbProcNo();
554 sendFaces.resize_nocopy(procPatch.size());
555 sendFacesInfo.resize_nocopy(procPatch.size());
558 const label nSendFaces = getChangedPatchFaces
568 sendFaces.resize(nSendFaces);
569 sendFacesInfo.resize(nSendFaces);
582 UOPstream toNbr(nbrProci, pBufs_);
583 toNbr << sendFaces << sendFacesInfo;
586 pBufs_.registerSend(nbrProci, !sendFaces.empty());
590 Pout<<
" Processor patch " << patchi <<
' ' << procPatch.
name()
591 <<
" send:" << sendFaces.size() <<
" to proc:" << nbrProci
599 pBufs_.finishedNeighbourSends(neighbourProcs);
602 for (
const label patchi : procPatches)
604 const auto& procPatch =
605 refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchi]);
607 const label nbrProci = procPatch.neighbProcNo();
609 if (!pBufs_.recvDataCount(nbrProci))
617 List<Type> receiveFacesInfo;
619 UIPstream is(nbrProci, pBufs_);
620 is >> receiveFaces >> receiveFacesInfo;
623 const label nReceiveFaces = receiveFaces.size();
627 Pout<<
" Processor patch " << patchi <<
' ' << procPatch.
name()
628 <<
" recv:" << receiveFaces.size() <<
" from proci:" 633 if (!procPatch.parallel())
637 procPatch.forwardT(),
664 template<
class Type,
class TrackingData>
669 for (
const polyPatch&
patch : mesh_.boundaryMesh())
671 const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(
patch);
675 const auto& cycPatch = *cpp;
676 const auto& nbrPatch = cycPatch.neighbPatch();
680 List<Type> receiveFacesInfo(
patch.size());
683 const label nReceiveFaces = getChangedPatchFaces
701 if (!cycPatch.parallel())
714 Pout<<
" Cyclic patch " 715 << cycPatch.index() <<
' ' << cycPatch.
name()
716 <<
" Changed : " << nReceiveFaces
740 checkCyclic(cycPatch);
747 template<
class Type,
class TrackingData>
752 for (
const polyPatch&
patch : mesh_.boundaryMesh())
754 const cyclicAMIPolyPatch* cpp = isA<cyclicAMIPolyPatch>(
patch);
764 const auto& cycPatch = *cpp;
765 const auto& nbrPatch = cycPatch.neighbPatch();
767 List<Type> receiveInfo;
772 List<Type> sendInfo(nbrPatch.patchSlice(allFaceInfo_));
774 if (!nbrPatch.parallel() || nbrPatch.separated())
777 const vectorField::subField fc = nbrPatch.faceCentres();
780 sendInfo[i].leaveDomain(mesh_, nbrPatch, i, fc[i], td_);
785 combine<Type, TrackingData> cmb(*
this, cycPatch);
787 if (cycPatch.applyLowWeightCorrection())
791 cycPatch.patchInternalList(allCellInfo_)
794 cycPatch.interpolate(sendInfo, cmb, receiveInfo, defVals);
798 cycPatch.interpolate(sendInfo, cmb, receiveInfo);
803 if (!cycPatch.parallel())
813 if (!cycPatch.parallel() || cycPatch.separated())
816 const vectorField::subField fc = cycPatch.faceCentres();
819 receiveInfo[i].enterDomain(mesh_, cycPatch, i, fc[i], td_);
825 const auto areaFraction(
patch.areaFraction());
829 if (areaFraction && areaFraction()[i] <= 0.5)
835 const label meshFacei = cycPatch.start()+i;
837 const Type& newInfo = receiveInfo[i];
839 Type& currInfo = allFaceInfo_[meshFacei];
841 if (newInfo.valid(td_) && !currInfo.equal(newInfo, td_))
857 template<
class Type,
class TrackingData>
860 changedBaffles_.clear();
863 for (
const labelPair& baffle : explicitConnections_)
865 const label f0 = baffle.first();
866 const label f1 = baffle.second();
868 if (changedFace_.test(f0))
871 changedBaffles_.push_back(taggedInfoType(f1, allFaceInfo_[f0]));
874 if (changedFace_.test(f1))
877 changedBaffles_.push_back(taggedInfoType(f0, allFaceInfo_[f1]));
884 for (
const taggedInfoType& updated : changedBaffles_)
886 const label tgtFace = updated.first;
887 const Type& newInfo = updated.second;
889 Type& currInfo = allFaceInfo_[tgtFace];
891 if (!currInfo.equal(newInfo, td_))
903 changedBaffles_.clear();
909 template<
class Type,
class TrackingData>
920 explicitConnections_(),
924 changedBaffles_(2*explicitConnections_.size()),
939 <<
"face and cell storage not the size of mesh faces, cells:" <<
nl 941 <<
" mesh_.nFaces():" << mesh_.nFaces() <<
nl 943 <<
" mesh_.nCells():" << mesh_.nCells() <<
endl 949 template<
class Type,
class TrackingData>
963 explicitConnections_(),
967 changedBaffles_(2*explicitConnections_.size()),
982 <<
"face and cell storage not the size of mesh faces, cells:" <<
nl 984 <<
" mesh_.nFaces():" << mesh_.nFaces() <<
nl 986 <<
" mesh_.nCells():" << mesh_.nCells() <<
endl 991 setFaceInfo(changedFaces, changedFacesInfo);
994 const label iter =
iterate(maxIter);
996 if ((maxIter > 0) && (iter >= maxIter))
999 <<
"Maximum number of iterations reached. Increase maxIter." <<
nl 1000 <<
" maxIter:" << maxIter <<
nl 1001 <<
" nChangedCells:" << nChangedCells() <<
nl 1002 <<
" nChangedFaces:" << nChangedFaces() <<
endl 1008 template<
class Type,
class TrackingData>
1013 const bool handleCyclicAMI,
1018 const label maxIter,
1024 explicitConnections_(explicitConnections),
1028 changedBaffles_(2*explicitConnections_.size()),
1030 hasCyclicAMIPatches_
1044 <<
"face and cell storage not the size of mesh faces, cells:" <<
nl 1046 <<
" mesh_.nFaces():" << mesh_.nFaces() <<
nl 1048 <<
" mesh_.nCells():" << mesh_.nCells() <<
endl 1053 setFaceInfo(changedFaces, changedFacesInfo);
1056 const label iter =
iterate(maxIter);
1058 if ((maxIter > 0) && (iter >= maxIter))
1061 <<
"Maximum number of iterations reached. Increase maxIter." <<
nl 1062 <<
" maxIter:" << maxIter <<
nl 1063 <<
" nChangedCells:" << nChangedCells() <<
nl 1064 <<
" nChangedFaces:" << nChangedFaces() <<
endl 1072 template<
class Type,
class TrackingData>
1077 const labelList& owner = mesh_.faceOwner();
1078 const labelList& neighbour = mesh_.faceNeighbour();
1079 const label nInternalFaces = mesh_.nInternalFaces();
1081 for (
const label facei : changedFaces_)
1083 if (!changedFace_.test(facei))
1087 <<
" not marked as having been changed" 1091 const Type& newInfo = allFaceInfo_[facei];
1097 const label celli = owner[facei];
1098 Type& currInfo = allCellInfo_[celli];
1100 if (!currInfo.equal(newInfo, td_))
1114 if (facei < nInternalFaces)
1116 const label celli = neighbour[facei];
1117 Type& currInfo = allCellInfo_[celli];
1119 if (!currInfo.equal(newInfo, td_))
1133 changedFace_.unset(facei);
1137 changedFaces_.clear();
1141 Pout<<
" Changed cells : " << nChangedCells() <<
endl;
1149 template<
class Type,
class TrackingData>
1156 for (
const label celli : changedCells_)
1158 if (!changedCell_.test(celli))
1161 <<
"Cell " << celli <<
" not marked as having been changed" 1165 const Type& newInfo = allCellInfo_[celli];
1172 Type& currInfo = allFaceInfo_[facei];
1174 if (!currInfo.equal(newInfo, td_))
1188 changedCell_.unset(celli);
1192 changedCells_.clear();
1196 handleExplicitConnections();
1198 if (hasCyclicPatches_)
1200 handleCyclicPatches();
1203 if (hasCyclicAMIPatches_)
1205 handleAMICyclicPatches();
1208 if (Pstream::parRun())
1210 handleProcPatches();
1215 Pout<<
" Changed faces : " << nChangedFaces() <<
endl;
1225 template<
class Type,
class TrackingData>
1233 if (hasCyclicPatches_)
1235 handleCyclicPatches();
1238 if (hasCyclicAMIPatches_)
1240 handleAMICyclicPatches();
1243 if (Pstream::parRun())
1245 handleProcPatches();
1250 for (; iter < maxIter; ++iter)
1254 Info<<
" Iteration " << iter <<
endl;
1258 const label nCells = faceToCell();
1259 const label nFaces = nCells ? cellToFace() : 0;
1263 Info<<
" Total evaluations : " 1265 <<
" Changed cells / faces : " 1266 << nCells <<
" / " << nFaces <<
nl 1267 <<
" Pending cells / faces : " 1268 << nUnvisitedCells_ <<
" / " << nUnvisitedFaces_ <<
nl;
1271 if (!nCells || !nFaces)
void handleAMICyclicPatches()
Merge data from across AMI cyclics.
void handleExplicitConnections()
Merge data across explicitly provided local connections.
void size(const label n)
Older name for setAddressableSize.
Inter-processor communication reduction functions.
List< wallPoints > allCellInfo(mesh_.nCells())
virtual label iterate(const label maxIter)
Iterate until no changes or maxIter reached.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual label cellToFace()
Propagate from cell to face.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
label start() const noexcept
Return start label of this patch in the polyMesh face list.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
wallPoints::trackData td(isBlockedFace, regionToBlockSize)
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Wave propagation of information through grid. Every iteration information goes through one layer of c...
const TrackingData & data() const noexcept
Additional data to be passed into container.
Holds information regarding type of cell. Used in inside/outside determination in cellClassification...
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
labelList faceLabels(nFaceLabels)
void handleProcPatches()
Merge data from across processor boundaries.
static scalar propagationTol() noexcept
Access to propagation tolerance.
#define forAll(list, i)
Loop across all elements in list.
void leaveDomain(const polyPatch &patch, const label nFaces, const labelUList &faceLabels, List< Type > &faceInfo) const
Handle leaving domain. Implementation referred to Type.
bool hasPatch() const
Has cyclic patch?
void clear()
Clear the list, i.e. set size to zero.
void transform(const tensorField &rotTensor, const label nFaces, List< Type > &faceInfo)
Apply transformation to Type.
bool valid(TrackingData &td) const
Changed or contains original (invalid) value.
bool updateCell(const polyMesh &, const label thisCelli, const label neighbourFacei, const cellInfo &neighbourInfo, const scalar tol, TrackingData &td)
Influence of neighbouring face.
const polyMesh & mesh() const noexcept
Return access to the mesh.
Cyclic patch for Arbitrary Mesh Interface (AMI)
void mergeFaceInfo(const polyPatch &patch, const label nFaces, const labelUList &changedFaces, const List< Type > &changedFacesInfo)
Merge received patch data into global data.
errorManip< error > abort(error &err)
bool updateFace(const label facei, const label neighbourCelli, const Type &neighbourInfo, const scalar tol, Type &faceInfo)
Updates faceInfo with information from neighbour.
bool updateCell(const label celli, const label neighbourFacei, const Type &neighbourInfo, const scalar tol, Type &cellInfo)
Updates cellInfo with information from neighbour.
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
void enterDomain(const polyPatch &patch, const label nFaces, const labelUList &faceLabels, List< Type > &faceInfo) const
Handle leaving domain. Implementation referred to Type.
Basic run-time type information using word as the type's name. Used to enhance the standard RTTI to c...
label getChangedPatchFaces(const polyPatch &patch, const label startFacei, const label nFaces, labelList &changedPatchFaces, List< Type > &changedPatchFacesInfo) const
Extract info for single patch only.
wallDistCalc iterate(nIters)
combine(FaceCellWave< Type, TrackingData > &solver, const cyclicAMIPolyPatch &patch)
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
virtual bool owner() const
Does this side own the patch?
return returnReduce(nRefine-oldNRefine, sumOp< label >())
const std::string patch
OpenFOAM patch number as a std::string.
messageStream Info
Information stream (stdout output on master, null elsewhere)
void checkCyclic(const polyPatch &pPatch) const
Debugging: check info on both sides of cyclic.
void handleCyclicPatches()
Merge data from across cyclics.
Mesh consisting of general polyhedral cells.
FaceCellWave(const FaceCellWave &)=delete
No copy construct.
List< label > labelList
A List of labels.
A patch is a list of labels that address the faces in the global face list.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Tensor of scalars, i.e. Tensor<scalar>.
static void offset(const polyPatch &patch, const label off, const label nFaces, labelList &faces)
Offset face labels by constant value.
List< wallPoints > allFaceInfo(mesh_.nFaces())
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
void setFaceInfo(const label facei, const Type &faceInfo)
Set single initial changed face.
virtual label faceToCell()
Propagate from face to cell.