Go to the documentation of this file.
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;
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];
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;
490 neighbEdgesPtr_.reset(
new labelList(nEdges(), -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;
584 /
name() +
"_localFaceCentres.obj"
586 Pout<<
"processorPolyPatch::order : "
587 <<
"Dumping " << fc.size()
588 <<
" local faceCentres to " << localStr.
name() <<
endl;
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,
647 if (a.size() !=
b.size())
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)
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;
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];
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)
int debug
Static debugging option.
const Field< point_type > & points() const noexcept
Return reference to global points.
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
List< label > labelList
A List of labels.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
A class for handling words, derived from Foam::string.
Output inter-processor communications stream operating on external buffer.
A class for handling file names.
virtual void movePoints(PstreamBuffers &, const pointField &p)
Correct patches after moving points.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
virtual const fileName & name() const
Read/write access to the name of the stream.
static constexpr const zero Zero
Global zero (0)
Walks over a container as if it were circular. The container must have the following members defined:
void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void setIteratorToFulcrum()
Set the iterator to the current position of the fulcrum.
const labelList & neighbEdges() const
Return neighbour edge labels. WIP.
Ostream & endl(Ostream &os)
Add newline and flush stream.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
#define forAll(list, i)
Loop across all elements in list.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
virtual void write(Ostream &os) const
Write the polyPatch data as a dictionary.
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.
Determine correspondence between points. See below.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf())
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
virtual const fileName & name() const
Get the name of the stream.
void setSize(const label n)
Alias for resize()
void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Neighbour processor patch.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
OBJstream os(runTime.globalPath()/outputName)
Macros for easy insertion into run-time selection tables.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
errorManip< error > abort(error &err)
difference_type nRotations() const
Return the distance between the iterator and the fulcrum. This is.
void movePoints(PstreamBuffers &, const pointField &)
Correct patches after moving points.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const Field< point_type > & localPoints() const
Return pointField of points in patch.
Output to file stream, using an OSstream.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
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.
direction
Direction type enumeration.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const labelList & neighbPoints() const
Return neighbour point labels. WIP.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
static bool & parRun() noexcept
Test if this a parallel run.
static word newName(const label myProcNo, const label neighbProcNo)
Return the name of a processorPolyPatch.
label comm() const noexcept
Communicator.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
A List with indirect addressing.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
A face is a list of labels corresponding to mesh vertices.
void setFulcrumToIterator()
Set the fulcrum to the current position of the iterator.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Input inter-processor communications stream operating on external buffer.
virtual ~processorPolyPatch()
Destructor.
vector point
Point is a vector.
defineTypeNameAndDebug(combustionModel, 0)
bool circulate(const CirculatorBase::direction dir=NONE)
Circulate around the list in the given direction.
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.
const Field< point_type > & faceCentres() const
Return face centres for patch.
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
A list of faces which address into the list of points.