60 const int neighbProcNo,
67 neighbProcNo_(neighbProcNo),
70 neighbFaceCellCentres_()
81 const int neighbProcNo,
88 newName(myProcNo, neighbProcNo),
97 neighbProcNo_(neighbProcNo),
100 neighbFaceCellCentres_()
110 const word& patchType
114 myProcNo_(
dict.get<label>(
"myProcNo")),
115 neighbProcNo_(
dict.get<label>(
"neighbProcNo")),
116 neighbFaceCentres_(),
118 neighbFaceCellCentres_()
129 myProcNo_(pp.myProcNo_),
130 neighbProcNo_(pp.neighbProcNo_),
131 neighbFaceCentres_(),
133 neighbFaceCellCentres_()
147 myProcNo_(pp.myProcNo_),
148 neighbProcNo_(pp.neighbProcNo_),
149 neighbFaceCentres_(),
151 neighbFaceCellCentres_()
165 myProcNo_(pp.myProcNo_),
166 neighbProcNo_(pp.neighbProcNo_),
167 neighbFaceCentres_(),
169 neighbFaceCellCentres_()
177 neighbPointsPtr_.clear();
178 neighbEdgesPtr_.clear();
186 const label myProcNo,
187 const label neighbProcNo
205 <<
"On patch " <<
name()
206 <<
" trying to access out of range neighbour processor "
207 << neighbProcNo() <<
". This can happen if" <<
nl
208 <<
" trying to run on an incorrect number of processors"
212 UOPstream toNeighbProc(neighbProcNo(), pBufs);
217 << faceCellCentres();
227 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
230 >> neighbFaceCentres_
232 >> neighbFaceCellCentres_;
239 vectorField nbrFaceNormals(neighbFaceAreas_.size());
247 scalar magSf =
mag(faceAreas()[facei]);
248 scalar nbrMagSf =
mag(neighbFaceAreas_[facei]);
249 scalar avSf = (magSf + nbrMagSf)/2.0;
253 if (magSf < SMALL || nbrMagSf < SMALL)
261 else if (
mag(magSf - nbrMagSf) > matchTolerance()*
sqr(tols[facei]))
269 Pout<<
"processorPolyPatch::calcGeometry : Writing my "
271 <<
" faces to OBJ file " << nm <<
endl;
273 writeOBJ(nm, *
this,
points());
278 /
name() +
"_faceCentresConnections.obj"
281 Pout<<
"processorPolyPatch::calcGeometry :"
282 <<
" Dumping cell centre lines between"
283 <<
" corresponding face centres to OBJ file" << ccStr.
name()
288 forAll(faceCentres(), facej)
290 const point& c0 = neighbFaceCentres_[facej];
291 const point& c1 = faceCentres()[facej];
293 writeOBJ(ccStr, c0, c1, vertI);
297 <<
"face " << facei <<
" area does not match neighbour by "
298 << 100*
mag(magSf - nbrMagSf)/avSf
299 <<
"% -- possible face ordering problem." <<
endl
300 <<
"patch:" <<
name()
301 <<
" my area:" << magSf
302 <<
" neighbour area:" << nbrMagSf
303 <<
" matching tolerance:"
304 << matchTolerance()*
sqr(tols[facei])
306 <<
"Mesh face:" << start()+facei
310 <<
"If you are certain your matching is correct"
311 <<
" you can increase the 'matchTolerance' setting"
312 <<
" in the patch dictionary in the boundary file."
314 <<
"Rerun with processor debug flag set for"
320 nbrFaceNormals[facei] = neighbFaceAreas_[facei]/nbrMagSf;
330 matchTolerance()*tols,
368 <<
"On patch " <<
name()
369 <<
" trying to access out of range neighbour processor "
370 << neighbProcNo() <<
". This can happen if" <<
nl
371 <<
" trying to run on an incorrect number of processors"
379 for (label patchPointi = 0; patchPointi <
nPoints(); patchPointi++)
381 label facei = pointFaces()[patchPointi][0];
383 pointFace[patchPointi] = facei;
385 const face&
f = localFaces()[facei];
387 pointIndex[patchPointi] =
f.
find(patchPointi);
394 for (label patchEdgeI = 0; patchEdgeI <
nEdges(); patchEdgeI++)
396 label facei = edgeFaces()[patchEdgeI][0];
398 edgeFace[patchEdgeI] = facei;
400 const labelList& fEdges = faceEdges()[facei];
402 edgeIndex[patchEdgeI] = fEdges.
find(patchEdgeI);
405 UOPstream toNeighbProc(neighbProcNo(), pBufs);
421 neighbPointsPtr_.clear();
422 neighbEdgesPtr_.clear();
440 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
456 labelList& neighbPoints = neighbPointsPtr_();
458 forAll(nbrPointFace, nbrPointi)
461 const face&
f = localFaces()[nbrPointFace[nbrPointi]];
463 label index = (
f.
size() - nbrPointIndex[nbrPointi]) %
f.
size();
464 label patchPointi =
f[index];
466 if (neighbPoints[patchPointi] == -1)
469 neighbPoints[patchPointi] = nbrPointi;
471 else if (neighbPoints[patchPointi] >= 0)
474 neighbPoints[patchPointi] = -2;
479 forAll(neighbPoints, patchPointi)
481 if (neighbPoints[patchPointi] == -2)
483 neighbPoints[patchPointi] = -1;
491 labelList& neighbEdges = neighbEdgesPtr_();
493 forAll(nbrEdgeFace, nbrEdgeI)
496 const labelList&
f = faceEdges()[nbrEdgeFace[nbrEdgeI]];
497 label index = (
f.
size() - nbrEdgeIndex[nbrEdgeI] - 1) %
f.
size();
498 label patchEdgeI =
f[index];
500 if (neighbEdges[patchEdgeI] == -1)
503 neighbEdges[patchEdgeI] = nbrEdgeI;
505 else if (neighbEdges[patchEdgeI] >= 0)
508 neighbEdges[patchEdgeI] = -2;
513 forAll(neighbEdges, patchEdgeI)
515 if (neighbEdges[patchEdgeI] == -2)
517 neighbEdges[patchEdgeI] = -1;
530 if (!neighbPointsPtr_)
533 <<
"No extended addressing calculated for patch " <<
name()
536 return *neighbPointsPtr_;
542 if (!neighbEdgesPtr_)
545 <<
"No extended addressing calculated for patch " <<
name()
548 return *neighbEdgesPtr_;
574 Pout<<
"processorPolyPatch::order : Writing my " << pp.size()
575 <<
" faces to OBJ file " << nm <<
endl;
576 writeOBJ(nm, pp, pp.
points());
584 /
name() +
"_localFaceCentres.obj"
586 Pout<<
"processorPolyPatch::order : "
587 <<
"Dumping " << fc.
size()
588 <<
" local faceCentres to " << localStr.
name() <<
endl;
592 writeOBJ(localStr, fc[facei]);
601 UOPstream toNeighbour(neighbProcNo(), pBufs);
621 facePointAverages[fI] += ppPoints[facePoints[pI]];
624 facePointAverages[fI] /= facePoints.
size();
628 UOPstream toNeighbour(neighbProcNo(), pBufs);
630 << anchors << facePointAverages;
642 const bool sameOrientation,
643 const scalar absTolSqr,
655 if (!sameOrientation)
662 scalar closestMatchDistSqr =
sqr(GREAT);
669 const scalar diffSqr =
magSqr(aPts[*aCirc] - bPts[*bCirc]);
671 if (diffSqr < absTolSqr)
679 if (!sameOrientation)
688 matchDistSqr = diffSqr;
692 const scalar diffSqr2 =
magSqr(aPts[*aCirc] - bPts[*bCirc2]);
694 if (diffSqr2 > absTolSqr)
700 matchDistSqr += diffSqr2;
710 if (matchDistSqr < closestMatchDistSqr)
712 closestMatchDistSqr = matchDistSqr;
714 if (!sameOrientation)
716 matchFp = a.
size() - bCirc.nRotations();
720 matchFp = bCirc.nRotations();
723 if (closestMatchDistSqr == 0)
734 }
while (bCirc.
circulate(circulateDirection));
736 matchDistSqr = closestMatchDistSqr;
775 faceMap[patchFacei] = patchFacei;
792 const point& wantedAnchor = anchors[patchFacei];
794 rotation[patchFacei] = getRotation
802 if (rotation[patchFacei] > 0)
825 UIPstream fromNeighbour(neighbProcNo(), pBufs);
826 fromNeighbour >> masterPts >> masterFaces;
836 const face& localFace = localFaces[lFacei];
837 label faceRotation = -1;
839 const scalar absTolSqr =
sqr(tols[lFacei]);
841 scalar closestMatchDistSqr =
sqr(GREAT);
842 scalar matchDistSqr =
sqr(GREAT);
843 label closestFaceMatch = -1;
844 label closestFaceRotation = -1;
846 forAll(masterFaces, mFacei)
848 const face& masterFace = masterFaces[mFacei];
850 faceRotation = matchFace
864 && matchDistSqr < closestMatchDistSqr
867 closestMatchDistSqr = matchDistSqr;
868 closestFaceMatch = mFacei;
869 closestFaceRotation = faceRotation;
872 if (closestMatchDistSqr == 0)
880 closestFaceRotation != -1
881 && closestMatchDistSqr < absTolSqr
884 faceMap[lFacei] = closestFaceMatch;
886 rotation[lFacei] = closestFaceRotation;
888 if (lFacei != closestFaceMatch || closestFaceRotation > 0)
897 Pout<<
"Number of matches = " << nMatches <<
" / "
898 << pp.size() <<
endl;
903 const label localPtI = localFace[pI];
904 pts[pI] = localPts[localPtI];
908 <<
"No match for face " << localFace <<
nl << pts
924 UIPstream fromNeighbour(neighbProcNo(), pBufs);
925 fromNeighbour >> masterCtrs >> masterNormals
926 >> masterAnchors >> masterFacePointAverages;
929 if (debug || masterCtrs.
size() != pp.size())
935 /
name() +
"_nbrFaceCentres.obj"
937 Pout<<
"processorPolyPatch::order : "
938 <<
"Dumping neighbour faceCentres to " << nbrStr.
name()
942 writeOBJ(nbrStr, masterCtrs[facei]);
946 if (masterCtrs.
size() != pp.size())
949 <<
"in patch:" <<
name() <<
" : "
950 <<
"Local size of patch is " << pp.size() <<
" (faces)."
952 <<
"Received from neighbour " << masterCtrs.
size()
985 facePointAverages[fI] += ppPoints[facePoints[pI]];
988 facePointAverages[fI] /= facePoints.
size();
994 *calcFaceTol(pp, pp.
points(), facePointAverages)
1006 masterFacePointAverages,
1018 faceMap[oldFacei] = faceMap2[oldFacei];
1028 if (!matchedAll || debug)
1034 /
name() +
"_faces.obj"
1036 Pout<<
"processorPolyPatch::order :"
1037 <<
" Writing faces to OBJ file " << str.
name() <<
endl;
1038 writeOBJ(str, pp, pp.
points());
1043 /
name() +
"_faceCentresConnections.obj"
1046 Pout<<
"processorPolyPatch::order :"
1047 <<
" Dumping newly found match as lines between"
1048 <<
" corresponding face centres to OBJ file "
1056 label masterFacei =
faceMap[facei];
1058 if (masterFacei != -1)
1060 const point& c0 = masterCtrs[masterFacei];
1062 writeOBJ(ccStr, c0, c1, vertI);
1070 <<
"in patch:" <<
name() <<
" : "
1071 <<
"Cannot match vectors to faces on both sides of patch"
1073 <<
" masterCtrs[0]:" << masterCtrs[0] <<
endl
1075 <<
" Check your topology changes or maybe you have"
1076 <<
" multiple separated (from cyclics) processor patches"
1078 <<
" Continuing with incorrect face ordering from now on"
1091 label newFacei =
faceMap[oldFacei];
1093 const point& wantedAnchor = masterAnchors[newFacei];
1095 rotation[newFacei] = getRotation
1103 if (rotation[newFacei] == -1)
1106 <<
"in patch " <<
name()
1108 <<
"Cannot find point on face " << pp[oldFacei]
1109 <<
" with vertices "
1111 <<
" that matches point " << wantedAnchor
1112 <<
" when matching the halves of processor patch "
1114 <<
"Continuing with incorrect face ordering from now on"
1123 if (
faceMap[facei] != facei || rotation[facei] != 0)
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
direction
Direction type enumeration.
void setFulcrumToIterator()
Set the fulcrum to the current position of the iterator.
bool circulate(const CirculatorBase::direction dir=CirculatorBase::NONE)
void setIteratorToFulcrum()
Set the iterator to the current position of the fulcrum.
Like Foam::Circulator, but with const-access iterators.
void setSize(const label n)
Alias for resize()
Output to file stream, using an OSstream.
virtual const fileName & name() const
Read/write access to the name of the stream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
A list of faces which address into the list of points.
const Field< point_type > & localPoints() const
Return pointField of points in patch.
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
const Field< point_type > & points() const noexcept
Return reference to global points.
const Field< point_type > & faceCentres() const
Return face centres for patch.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
label comm() const noexcept
Communicator.
A List with indirect addressing. Like IndirectList but does not store addressing.
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
void size(const label n)
Older name for setAddressableSize.
static bool & parRun() noexcept
Test if this a parallel run.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
void calcGeometry()
Calculate the geometry for the patches.
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
virtual bool write()
Write the output fields.
virtual void initMovePoints()
Initialise the patches for moving points.
order
Enumeration specifying required accuracy.
void movePoints()
Update for new mesh geometry.
void updateMesh()
Update for new mesh topology.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
A patch is a list of labels that address the faces in the global face list.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
Neighbour processor patch.
virtual ~processorPolyPatch()
Destructor.
const labelList & neighbPoints() const
Return neighbour point labels. WIP.
void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
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.
const labelList & neighbEdges() const
Return neighbour edge labels. WIP.
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.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
const labelList nEdges(UPstream::listGatherValues< label >(aMesh.nEdges()))
surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf())
Determine correspondence between points. See below.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
vector point
Point is a vector.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
static constexpr const zero Zero
Global zero (0)
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.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
constexpr char nl
The newline '\n' character (0x0a)
#define forAll(list, i)
Loop across all elements in list.