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_);
826 const label meshFacei = cycPatch.start()+i;
828 const Type& newInfo = receiveInfo[i];
830 Type& currInfo = allFaceInfo_[meshFacei];
832 if (newInfo.valid(td_) && !currInfo.equal(newInfo, td_))
848 template<
class Type,
class TrackingData>
851 changedBaffles_.clear();
854 for (
const labelPair& baffle : explicitConnections_)
856 const label f0 = baffle.first();
857 const label f1 = baffle.second();
859 if (changedFace_.test(f0))
862 changedBaffles_.push_back(taggedInfoType(f1, allFaceInfo_[f0]));
865 if (changedFace_.test(f1))
868 changedBaffles_.push_back(taggedInfoType(f0, allFaceInfo_[f1]));
875 for (
const taggedInfoType& updated : changedBaffles_)
877 const label tgtFace = updated.first;
878 const Type& newInfo = updated.second;
880 Type& currInfo = allFaceInfo_[tgtFace];
882 if (!currInfo.equal(newInfo, td_))
894 changedBaffles_.clear();
900 template<
class Type,
class TrackingData>
911 explicitConnections_(),
912 allFaceInfo_(allFaceInfo),
913 allCellInfo_(allCellInfo),
915 changedBaffles_(2*explicitConnections_.size()),
925 allFaceInfo.
size() != mesh_.nFaces()
926 || allCellInfo.
size() != mesh_.nCells()
930 <<
"face and cell storage not the size of mesh faces, cells:" <<
nl 931 <<
" allFaceInfo :" << allFaceInfo.
size() <<
nl 932 <<
" mesh_.nFaces():" << mesh_.nFaces() <<
nl 933 <<
" allCellInfo :" << allCellInfo.
size() <<
nl 934 <<
" mesh_.nCells():" << mesh_.nCells() <<
endl 940 template<
class Type,
class TrackingData>
954 explicitConnections_(),
955 allFaceInfo_(allFaceInfo),
956 allCellInfo_(allCellInfo),
958 changedBaffles_(2*explicitConnections_.size()),
968 allFaceInfo.
size() != mesh_.nFaces()
969 || allCellInfo.
size() != mesh_.nCells()
973 <<
"face and cell storage not the size of mesh faces, cells:" <<
nl 974 <<
" allFaceInfo :" << allFaceInfo.
size() <<
nl 975 <<
" mesh_.nFaces():" << mesh_.nFaces() <<
nl 976 <<
" allCellInfo :" << allCellInfo.
size() <<
nl 977 <<
" mesh_.nCells():" << mesh_.nCells() <<
endl 982 setFaceInfo(changedFaces, changedFacesInfo);
985 const label iter = iterate(maxIter);
987 if ((maxIter > 0) && (iter >= maxIter))
990 <<
"Maximum number of iterations reached. Increase maxIter." <<
nl 991 <<
" maxIter:" << maxIter <<
nl 992 <<
" nChangedCells:" << nChangedCells() <<
nl 993 <<
" nChangedFaces:" << nChangedFaces() <<
endl 999 template<
class Type,
class TrackingData>
1004 const bool handleCyclicAMI,
1009 const label maxIter,
1015 explicitConnections_(explicitConnections),
1016 allFaceInfo_(allFaceInfo),
1017 allCellInfo_(allCellInfo),
1019 changedBaffles_(2*explicitConnections_.size()),
1021 hasCyclicAMIPatches_
1030 allFaceInfo.
size() != mesh_.nFaces()
1031 || allCellInfo.
size() != mesh_.nCells()
1035 <<
"face and cell storage not the size of mesh faces, cells:" <<
nl 1036 <<
" allFaceInfo :" << allFaceInfo.
size() <<
nl 1037 <<
" mesh_.nFaces():" << mesh_.nFaces() <<
nl 1038 <<
" allCellInfo :" << allCellInfo.
size() <<
nl 1039 <<
" mesh_.nCells():" << mesh_.nCells() <<
endl 1044 setFaceInfo(changedFaces, changedFacesInfo);
1047 const label iter = iterate(maxIter);
1049 if ((maxIter > 0) && (iter >= maxIter))
1052 <<
"Maximum number of iterations reached. Increase maxIter." <<
nl 1053 <<
" maxIter:" << maxIter <<
nl 1054 <<
" nChangedCells:" << nChangedCells() <<
nl 1055 <<
" nChangedFaces:" << nChangedFaces() <<
endl 1063 template<
class Type,
class TrackingData>
1068 const labelList& owner = mesh_.faceOwner();
1069 const labelList& neighbour = mesh_.faceNeighbour();
1070 const label nInternalFaces = mesh_.nInternalFaces();
1072 for (
const label facei : changedFaces_)
1074 if (!changedFace_.test(facei))
1078 <<
" not marked as having been changed" 1082 const Type& newInfo = allFaceInfo_[facei];
1088 const label celli = owner[facei];
1089 Type& currInfo = allCellInfo_[celli];
1091 if (!currInfo.equal(newInfo, td_))
1105 if (facei < nInternalFaces)
1107 const label celli = neighbour[facei];
1108 Type& currInfo = allCellInfo_[celli];
1110 if (!currInfo.equal(newInfo, td_))
1124 changedFace_.unset(facei);
1128 changedFaces_.clear();
1132 Pout<<
" Changed cells : " << nChangedCells() <<
endl;
1140 template<
class Type,
class TrackingData>
1147 for (
const label celli : changedCells_)
1149 if (!changedCell_.test(celli))
1152 <<
"Cell " << celli <<
" not marked as having been changed" 1156 const Type& newInfo = allCellInfo_[celli];
1163 Type& currInfo = allFaceInfo_[facei];
1165 if (!currInfo.equal(newInfo, td_))
1179 changedCell_.unset(celli);
1183 changedCells_.clear();
1187 handleExplicitConnections();
1189 if (hasCyclicPatches_)
1191 handleCyclicPatches();
1194 if (hasCyclicAMIPatches_)
1196 handleAMICyclicPatches();
1199 if (Pstream::parRun())
1201 handleProcPatches();
1206 Pout<<
" Changed faces : " << nChangedFaces() <<
endl;
1216 template<
class Type,
class TrackingData>
1224 if (hasCyclicPatches_)
1226 handleCyclicPatches();
1229 if (hasCyclicAMIPatches_)
1231 handleAMICyclicPatches();
1234 if (Pstream::parRun())
1236 handleProcPatches();
1241 for (; iter < maxIter; ++iter)
1245 Info<<
" Iteration " << iter <<
endl;
1249 const label nCells = faceToCell();
1250 const label nFaces = nCells ? cellToFace() : 0;
1254 Info<<
" Total evaluations : " 1256 <<
" Changed cells / faces : " 1257 << nCells <<
" / " << nFaces <<
nl 1258 <<
" Pending cells / faces : " 1259 << nUnvisitedCells_ <<
" / " << nUnvisitedFaces_ <<
nl;
1262 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.
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.
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)
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
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.
label getChangedPatchFaces(const polyPatch &patch, const label startFacei, const label nFaces, labelList &changedPatchFaces, List< Type > &changedPatchFacesInfo) const
Extract info for single patch only.
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?
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.
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.