55 const label neighbProcNo
77 const int neighbProcNo,
84 neighbProcNo_(neighbProcNo),
87 neighbFaceCellCentres_()
98 const int neighbProcNo,
100 const word& patchType
105 newName(myProcNo, neighbProcNo),
114 neighbProcNo_(neighbProcNo),
115 neighbFaceCentres_(),
117 neighbFaceCellCentres_()
127 const word& patchType
131 myProcNo_(
dict.
get<label>(
"myProcNo")),
132 neighbProcNo_(
dict.
get<label>(
"neighbProcNo")),
133 neighbFaceCentres_(),
135 neighbFaceCellCentres_()
146 myProcNo_(
pp.myProcNo_),
147 neighbProcNo_(
pp.neighbProcNo_),
148 neighbFaceCentres_(),
150 neighbFaceCellCentres_()
164 myProcNo_(
pp.myProcNo_),
165 neighbProcNo_(
pp.neighbProcNo_),
166 neighbFaceCentres_(),
168 neighbFaceCellCentres_()
182 myProcNo_(
pp.myProcNo_),
183 neighbProcNo_(
pp.neighbProcNo_),
184 neighbFaceCentres_(),
186 neighbFaceCellCentres_()
194 neighbPointsPtr_.clear();
195 neighbEdgesPtr_.clear();
205 if (neighbProcNo() >= pBufs.
nProcs())
208 <<
"On patch " <<
name()
209 <<
" trying to access out of range neighbour processor " 210 << neighbProcNo() <<
". This can happen if" <<
nl 211 <<
" trying to run on an incorrect number of processors" 215 UOPstream toNeighbProc(neighbProcNo(), pBufs);
220 << faceCellCentres();
230 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
233 >> neighbFaceCentres_
235 >> neighbFaceCellCentres_;
242 vectorField nbrFaceNormals(neighbFaceAreas_.size());
248 forAll(faceNormals, facei)
250 const scalar magSf =
mag(faceAreas()[facei]);
251 const scalar nbrMagSf =
mag(neighbFaceAreas_[facei]);
255 if (magSf < SMALL || nbrMagSf < SMALL)
259 faceNormals[facei] =
point(1, 0, 0);
260 nbrFaceNormals[facei] = -faceNormals[facei];
263 else if (
mag(magSf - nbrMagSf) > matchTolerance()*
sqr(tols[facei]))
265 const scalar avgMagSf = 0.5*(magSf + nbrMagSf);
273 Pout<<
"processorPolyPatch::calcGeometry : Writing my " 275 <<
" faces to OBJ file " << nm <<
endl;
282 /
name() +
"_faceCentresConnections.obj" 285 Pout<<
"processorPolyPatch::calcGeometry :" 286 <<
" Dumping cell centre lines between" 287 <<
" corresponding face centres to OBJ file" << ccStr.
name()
294 forAll(ownFaceCentres, facej)
296 const point& c0 = neighbFaceCentres_[facej];
297 const point&
c1 = ownFaceCentres[facej];
303 <<
"face " << facei <<
" area does not match neighbour by " 304 << 100*
mag(magSf - nbrMagSf)/avgMagSf
305 <<
"% -- possible face ordering problem." <<
endl 306 <<
"patch:" <<
name()
307 <<
" my area:" << magSf
308 <<
" neighbour area:" << nbrMagSf
309 <<
" matching tolerance:" 310 << matchTolerance()*
sqr(tols[facei])
312 <<
"Mesh face:" << start()+facei
314 << UIndirectList<point>(
points(), operator[](facei))
316 <<
"If you are certain your matching is correct" 317 <<
" you can increase the 'matchTolerance' setting" 318 <<
" in the patch dictionary in the boundary file." 320 <<
"Rerun with processor debug flag set for" 325 faceNormals[facei] = faceAreas()[facei]/magSf;
326 nbrFaceNormals[facei] = neighbFaceAreas_[facei]/nbrMagSf;
336 matchTolerance()*tols,
346 PstreamBuffers& pBufs,
371 if (neighbProcNo() >= pBufs.
nProcs())
374 <<
"On patch " <<
name()
375 <<
" trying to access out of range neighbour processor " 376 << neighbProcNo() <<
". This can happen if" <<
nl 377 <<
" trying to run on an incorrect number of processors" 385 for (label patchPointi = 0; patchPointi <
nPoints(); patchPointi++)
387 label facei = pointFaces()[patchPointi][0];
389 pointFace[patchPointi] = facei;
391 const face&
f = localFaces()[facei];
393 pointIndex[patchPointi] =
f.
find(patchPointi);
400 for (label patchEdgeI = 0; patchEdgeI < nEdges(); patchEdgeI++)
402 label facei = edgeFaces()[patchEdgeI][0];
404 edgeFace[patchEdgeI] = facei;
406 const labelList& fEdges = faceEdges()[facei];
408 edgeIndex[patchEdgeI] = fEdges.
find(patchEdgeI);
411 UOPstream toNeighbProc(neighbProcNo(), pBufs);
427 neighbPointsPtr_.clear();
428 neighbEdgesPtr_.clear();
446 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
462 labelList& neighbPoints = neighbPointsPtr_();
464 forAll(nbrPointFace, nbrPointi)
467 const face&
f = localFaces()[nbrPointFace[nbrPointi]];
469 label index = (
f.
size() - nbrPointIndex[nbrPointi]) %
f.
size();
470 label patchPointi =
f[index];
472 if (neighbPoints[patchPointi] == -1)
475 neighbPoints[patchPointi] = nbrPointi;
477 else if (neighbPoints[patchPointi] >= 0)
480 neighbPoints[patchPointi] = -2;
485 forAll(neighbPoints, patchPointi)
487 if (neighbPoints[patchPointi] == -2)
489 neighbPoints[patchPointi] = -1;
496 neighbEdgesPtr_.reset(
new labelList(nEdges(), -1));
497 labelList& neighbEdges = neighbEdgesPtr_();
499 forAll(nbrEdgeFace, nbrEdgeI)
502 const labelList&
f = faceEdges()[nbrEdgeFace[nbrEdgeI]];
503 label index = (
f.
size() - nbrEdgeIndex[nbrEdgeI] - 1) %
f.
size();
504 label patchEdgeI =
f[index];
506 if (neighbEdges[patchEdgeI] == -1)
509 neighbEdges[patchEdgeI] = nbrEdgeI;
511 else if (neighbEdges[patchEdgeI] >= 0)
514 neighbEdges[patchEdgeI] = -2;
519 forAll(neighbEdges, patchEdgeI)
521 if (neighbEdges[patchEdgeI] == -2)
523 neighbEdges[patchEdgeI] = -1;
536 if (!neighbPointsPtr_)
539 <<
"No extended addressing calculated for patch " <<
name()
542 return *neighbPointsPtr_;
548 if (!neighbEdgesPtr_)
551 <<
"No extended addressing calculated for patch " <<
name()
554 return *neighbEdgesPtr_;
560 PstreamBuffers& pBufs,
580 Pout<<
"processorPolyPatch::order : Writing my " <<
pp.size()
581 <<
" faces to OBJ file " << nm <<
endl;
590 /
name() +
"_localFaceCentres.obj" 592 Pout<<
"processorPolyPatch::order : " 593 <<
"Dumping " << fc.size()
594 <<
" local faceCentres to " << localStr.
name() <<
endl;
607 UOPstream toNeighbour(neighbProcNo(), pBufs);
627 facePointAverages[fI] += ppPoints[facePoints[pI]];
630 facePointAverages[fI] /= facePoints.size();
634 UOPstream toNeighbour(neighbProcNo(), pBufs);
636 << anchors << facePointAverages;
648 const bool sameOrientation,
649 const scalar absTolSqr,
653 if (a.size() !=
b.size())
661 if (!sameOrientation)
668 scalar closestMatchDistSqr =
sqr(GREAT);
670 ConstCirculator<face> aCirc(a);
671 ConstCirculator<face> bCirc(
b);
675 const scalar diffSqr =
magSqr(aPts[*aCirc] - bPts[*bCirc]);
677 if (diffSqr < absTolSqr)
680 ConstCirculator<face> bCirc2(bCirc);
683 bCirc2.setFulcrumToIterator();
685 if (!sameOrientation)
694 matchDistSqr = diffSqr;
698 const scalar diffSqr2 =
magSqr(aPts[*aCirc] - bPts[*bCirc2]);
700 if (diffSqr2 > absTolSqr)
706 matchDistSqr += diffSqr2;
711 bCirc2.circulate(circulateDirection)
714 if (!aCirc.circulate())
716 if (matchDistSqr < closestMatchDistSqr)
718 closestMatchDistSqr = matchDistSqr;
720 if (!sameOrientation)
722 matchFp = a.size() - bCirc.nRotations();
726 matchFp = bCirc.nRotations();
729 if (closestMatchDistSqr == 0)
737 aCirc.setIteratorToFulcrum();
740 }
while (bCirc.circulate(circulateDirection));
742 matchDistSqr = closestMatchDistSqr;
781 faceMap[patchFacei] = patchFacei;
798 const point& wantedAnchor = anchors[patchFacei];
800 rotation[patchFacei] = getRotation
808 if (rotation[patchFacei] > 0)
831 UIPstream fromNeighbour(neighbProcNo(), pBufs);
832 fromNeighbour >> masterPts >> masterFaces;
842 const face& localFace = localFaces[lFacei];
843 label faceRotation = -1;
845 const scalar absTolSqr =
sqr(tols[lFacei]);
847 scalar closestMatchDistSqr =
sqr(GREAT);
848 scalar matchDistSqr =
sqr(GREAT);
849 label closestFaceMatch = -1;
850 label closestFaceRotation = -1;
852 forAll(masterFaces, mFacei)
854 const face& masterFace = masterFaces[mFacei];
856 faceRotation = matchFace
870 && matchDistSqr < closestMatchDistSqr
873 closestMatchDistSqr = matchDistSqr;
874 closestFaceMatch = mFacei;
875 closestFaceRotation = faceRotation;
878 if (closestMatchDistSqr == 0)
886 closestFaceRotation != -1
887 && closestMatchDistSqr < absTolSqr
890 faceMap[lFacei] = closestFaceMatch;
892 rotation[lFacei] = closestFaceRotation;
894 if (lFacei != closestFaceMatch || closestFaceRotation > 0)
903 Pout<<
"Number of matches = " << nMatches <<
" / " 909 const label localPtI = localFace[pI];
910 pts[pI] = localPts[localPtI];
914 <<
"No match for face " << localFace <<
nl <<
pts 930 UIPstream fromNeighbour(neighbProcNo(), pBufs);
931 fromNeighbour >> masterCtrs >> masterNormals
932 >> masterAnchors >> masterFacePointAverages;
935 if (
debug || masterCtrs.size() !=
pp.size())
941 /
name() +
"_nbrFaceCentres.obj" 943 Pout<<
"processorPolyPatch::order : " 944 <<
"Dumping neighbour faceCentres to " << nbrStr.
name()
948 writeOBJ(nbrStr, masterCtrs[facei]);
952 if (masterCtrs.size() !=
pp.size())
955 <<
"in patch:" <<
name() <<
" : " 956 <<
"Local size of patch is " <<
pp.size() <<
" (faces)." 958 <<
"Received from neighbour " << masterCtrs.size()
991 facePointAverages[fI] += ppPoints[facePoints[pI]];
994 facePointAverages[fI] /= facePoints.size();
1000 *calcFaceTol(
pp,
pp.
points(), facePointAverages)
1012 masterFacePointAverages,
1024 faceMap[oldFacei] = faceMap2[oldFacei];
1034 if (!matchedAll ||
debug)
1039 boundaryMesh().
mesh().time().
path()
1040 /
name() +
"_faces.obj" 1042 Pout<<
"processorPolyPatch::order :" 1043 <<
" Writing faces to OBJ file " << str.
name() <<
endl;
1048 boundaryMesh().
mesh().time().
path()
1049 /
name() +
"_faceCentresConnections.obj" 1052 Pout<<
"processorPolyPatch::order :" 1053 <<
" Dumping newly found match as lines between" 1054 <<
" corresponding face centres to OBJ file " 1062 label masterFacei =
faceMap[facei];
1064 if (masterFacei != -1)
1066 const point& c0 = masterCtrs[masterFacei];
1076 <<
"in patch:" <<
name() <<
" : " 1077 <<
"Cannot match vectors to faces on both sides of patch" 1079 <<
" masterCtrs[0]:" << masterCtrs[0] <<
endl 1081 <<
" Check your topology changes or maybe you have" 1082 <<
" multiple separated (from cyclics) processor patches" 1084 <<
" Continuing with incorrect face ordering from now on" 1097 label newFacei =
faceMap[oldFacei];
1099 const point& wantedAnchor = masterAnchors[newFacei];
1101 rotation[newFacei] = getRotation
1109 if (rotation[newFacei] == -1)
1112 <<
"in patch " <<
name()
1114 <<
"Cannot find point on face " <<
pp[oldFacei]
1115 <<
" with vertices " 1116 << UIndirectList<point>(
pp.
points(),
pp[oldFacei])
1117 <<
" that matches point " << wantedAnchor
1118 <<
" when matching the halves of processor patch " 1120 <<
"Continuing with incorrect face ordering from now on" 1129 if (
faceMap[facei] != facei || rotation[facei] != 0)
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
void size(const label n)
Older name for setAddressableSize.
const labelList & neighbPoints() const
Return neighbour point labels. WIP.
virtual void write(Ostream &os) const
Write the polyPatch data as a dictionary.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const Field< point_type > & localPoints() const
Return pointField of points in patch.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline '\n' character (0x0a)
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
static word newName(const label myProcNo, const label neighbProcNo)
Return the name of a processorPolyPatch ("procBoundary..") constructed from the pair of processor IDs...
Ostream & endl(Ostream &os)
Add newline and flush stream.
void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
static bool & parRun() noexcept
Test if this a parallel run.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
direction
Direction type enumeration.
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
void movePoints(PstreamBuffers &, const pointField &)
Correct patches after moving points.
Determine correspondence between points. See below.
Macros for easy insertion into run-time selection tables.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
virtual void movePoints(PstreamBuffers &, const pointField &p)
Correct patches after moving points.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Neighbour processor patch.
#define forAll(list, i)
Loop across all elements in list.
void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
List< face > faceList
List of faces.
A list of faces which address into the list of points.
bool matchPoints(const UList< point > &pts0, const UList< point > &pts1, const UList< scalar > &matchDistance, const bool verbose, labelList &from0To1, const point &origin=point::zero)
Determine correspondence between pointFields. Gets passed.
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const Field< point_type > & faceCentres() const
Return face centres for patch.
virtual ~processorPolyPatch()
Destructor.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
const Field< point_type > & points() const noexcept
Return reference to global points.
errorManip< error > abort(error &err)
label find(const T &val) const
Find index of the first occurrence of the value.
void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
Output inter-processor communications stream using MPI send/recv etc. - operating on external buffer...
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineTypeNameAndDebug(combustionModel, 0)
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
static label matchFace(const face &localFace, const pointField &localPts, const face &masterFace, const pointField &masterPts, const bool sameOrientation, const scalar absTolSqr, scalar &matchDistSqr)
Returns rotation.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field...
int neighbProcNo() const noexcept
Return neighbour processor number.
vector point
Point is a vector.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
SubField< vector > subField
Declare type of subField.
Field< vector > vectorField
Specialisation of Field<T> for vector.
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
List< label > labelList
A List of labels.
A patch is a list of labels that address the faces in the global face list.
const labelList & neighbEdges() const
Return neighbour edge labels. WIP.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
int myProcNo() const noexcept
Return processor number.
processorPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const int myProcNo, const int neighbProcNo, const transformType transform=UNKNOWN, const word &patchType=typeName)
Construct from components with specified name.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
static constexpr const zero Zero
Global zero (0)