Go to the documentation of this file.
61 const int neighbProcNo,
68 neighbProcNo_(neighbProcNo),
71 neighbFaceCellCentres_()
82 const int neighbProcNo,
89 newName(myProcNo, neighbProcNo),
98 neighbProcNo_(neighbProcNo),
101 neighbFaceCellCentres_()
111 const word& patchType
116 neighbProcNo_(
dict.get<
label>(
"neighbProcNo")),
117 neighbFaceCentres_(),
119 neighbFaceCellCentres_()
130 myProcNo_(pp.myProcNo_),
131 neighbProcNo_(pp.neighbProcNo_),
132 neighbFaceCentres_(),
134 neighbFaceCellCentres_()
148 myProcNo_(pp.myProcNo_),
149 neighbProcNo_(pp.neighbProcNo_),
150 neighbFaceCentres_(),
152 neighbFaceCellCentres_()
166 myProcNo_(pp.myProcNo_),
167 neighbProcNo_(pp.neighbProcNo_),
168 neighbFaceCentres_(),
170 neighbFaceCellCentres_()
178 neighbPointsPtr_.clear();
179 neighbEdgesPtr_.clear();
187 const label myProcNo,
188 const label neighbProcNo
206 <<
"On patch " <<
name()
207 <<
" trying to access out of range neighbour processor "
208 << neighbProcNo() <<
". This can happen if" <<
nl
209 <<
" trying to run on an incorrect number of processors"
213 UOPstream toNeighbProc(neighbProcNo(), pBufs);
218 << faceCellCentres();
228 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
231 >> neighbFaceCentres_
233 >> neighbFaceCellCentres_;
240 vectorField nbrFaceNormals(neighbFaceAreas_.size());
248 scalar magSf =
mag(faceAreas()[facei]);
249 scalar nbrMagSf =
mag(neighbFaceAreas_[facei]);
250 scalar avSf = (magSf + nbrMagSf)/2.0;
254 if (magSf < SMALL || nbrMagSf < SMALL)
262 else if (
mag(magSf - nbrMagSf) > matchTolerance()*
sqr(tols[facei]))
270 Pout<<
"processorPolyPatch::calcGeometry : Writing my "
272 <<
" faces to OBJ file " << nm <<
endl;
279 /
name() +
"_faceCentresConnections.obj"
282 Pout<<
"processorPolyPatch::calcGeometry :"
283 <<
" Dumping cell centre lines between"
284 <<
" corresponding face centres to OBJ file" << ccStr.
name()
289 forAll(faceCentres(), facej)
291 const point& c0 = neighbFaceCentres_[facej];
292 const point&
c1 = faceCentres()[facej];
298 <<
"face " << facei <<
" area does not match neighbour by "
299 << 100*
mag(magSf - nbrMagSf)/avSf
300 <<
"% -- possible face ordering problem." <<
endl
301 <<
"patch:" <<
name()
302 <<
" my area:" << magSf
303 <<
" neighbour area:" << nbrMagSf
304 <<
" matching tolerance:"
305 << matchTolerance()*
sqr(tols[facei])
307 <<
"Mesh face:" <<
start()+facei
311 <<
"If you are certain your matching is correct"
312 <<
" you can increase the 'matchTolerance' setting"
313 <<
" in the patch dictionary in the boundary file."
315 <<
"Rerun with processor debug flag set for"
321 nbrFaceNormals[facei] = neighbFaceAreas_[facei]/nbrMagSf;
331 matchTolerance()*tols,
369 <<
"On patch " <<
name()
370 <<
" trying to access out of range neighbour processor "
371 << neighbProcNo() <<
". This can happen if" <<
nl
372 <<
" trying to run on an incorrect number of processors"
380 for (
label patchPointi = 0; patchPointi <
nPoints(); patchPointi++)
382 label facei = pointFaces()[patchPointi][0];
384 pointFace[patchPointi] = facei;
386 const face&
f = localFaces()[facei];
388 pointIndex[patchPointi] =
f.find(patchPointi);
395 for (
label patchEdgeI = 0; patchEdgeI < nEdges(); patchEdgeI++)
397 label facei = edgeFaces()[patchEdgeI][0];
399 edgeFace[patchEdgeI] = facei;
401 const labelList& fEdges = faceEdges()[facei];
403 edgeIndex[patchEdgeI] = fEdges.find(patchEdgeI);
406 UOPstream toNeighbProc(neighbProcNo(), pBufs);
422 neighbPointsPtr_.clear();
423 neighbEdgesPtr_.clear();
441 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
457 labelList& neighbPoints = neighbPointsPtr_();
459 forAll(nbrPointFace, nbrPointi)
462 const face&
f = localFaces()[nbrPointFace[nbrPointi]];
464 label index = (
f.size() - nbrPointIndex[nbrPointi]) %
f.size();
465 label patchPointi =
f[index];
467 if (neighbPoints[patchPointi] == -1)
470 neighbPoints[patchPointi] = nbrPointi;
472 else if (neighbPoints[patchPointi] >= 0)
475 neighbPoints[patchPointi] = -2;
480 forAll(neighbPoints, patchPointi)
482 if (neighbPoints[patchPointi] == -2)
484 neighbPoints[patchPointi] = -1;
491 neighbEdgesPtr_.reset(
new labelList(nEdges(), -1));
492 labelList& neighbEdges = neighbEdgesPtr_();
494 forAll(nbrEdgeFace, nbrEdgeI)
497 const labelList&
f = faceEdges()[nbrEdgeFace[nbrEdgeI]];
498 label index = (
f.size() - nbrEdgeIndex[nbrEdgeI] - 1) %
f.size();
499 label patchEdgeI =
f[index];
501 if (neighbEdges[patchEdgeI] == -1)
504 neighbEdges[patchEdgeI] = nbrEdgeI;
506 else if (neighbEdges[patchEdgeI] >= 0)
509 neighbEdges[patchEdgeI] = -2;
514 forAll(neighbEdges, patchEdgeI)
516 if (neighbEdges[patchEdgeI] == -2)
518 neighbEdges[patchEdgeI] = -1;
531 if (!neighbPointsPtr_.valid())
534 <<
"No extended addressing calculated for patch " <<
name()
537 return *neighbPointsPtr_;
543 if (!neighbEdgesPtr_.valid())
546 <<
"No extended addressing calculated for patch " <<
name()
549 return *neighbEdgesPtr_;
575 Pout<<
"processorPolyPatch::order : Writing my " << pp.size()
576 <<
" faces to OBJ file " << nm <<
endl;
585 /
name() +
"_localFaceCentres.obj"
587 Pout<<
"processorPolyPatch::order : "
588 <<
"Dumping " << fc.size()
589 <<
" local faceCentres to " << localStr.
name() <<
endl;
602 UOPstream toNeighbour(neighbProcNo(), pBufs);
622 facePointAverages[fI] += ppPoints[facePoints[pI]];
625 facePointAverages[fI] /= facePoints.size();
629 UOPstream toNeighbour(neighbProcNo(), pBufs);
631 << anchors << facePointAverages;
643 const bool sameOrientation,
644 const scalar absTolSqr,
648 if (a.size() !=
b.size())
656 if (!sameOrientation)
663 scalar closestMatchDistSqr =
sqr(GREAT);
670 const scalar diffSqr =
magSqr(aPts[aCirc()] - bPts[bCirc()]);
672 if (diffSqr < absTolSqr)
680 if (!sameOrientation)
689 matchDistSqr = diffSqr;
693 const scalar diffSqr2 =
magSqr(aPts[aCirc()] - bPts[bCirc2()]);
695 if (diffSqr2 > absTolSqr)
701 matchDistSqr += diffSqr2;
711 if (matchDistSqr < closestMatchDistSqr)
713 closestMatchDistSqr = matchDistSqr;
715 if (!sameOrientation)
724 if (closestMatchDistSqr == 0)
735 }
while (bCirc.
circulate(circulateDirection));
737 matchDistSqr = closestMatchDistSqr;
776 faceMap[patchFacei] = patchFacei;
793 const point& wantedAnchor = anchors[patchFacei];
795 rotation[patchFacei] = getRotation
803 if (rotation[patchFacei] > 0)
826 UIPstream fromNeighbour(neighbProcNo(), pBufs);
827 fromNeighbour >> masterPts >> masterFaces;
837 const face& localFace = localFaces[lFacei];
838 label faceRotation = -1;
840 const scalar absTolSqr =
sqr(tols[lFacei]);
842 scalar closestMatchDistSqr =
sqr(GREAT);
843 scalar matchDistSqr =
sqr(GREAT);
844 label closestFaceMatch = -1;
845 label closestFaceRotation = -1;
847 forAll(masterFaces, mFacei)
849 const face& masterFace = masterFaces[mFacei];
851 faceRotation = matchFace
865 && matchDistSqr < closestMatchDistSqr
868 closestMatchDistSqr = matchDistSqr;
869 closestFaceMatch = mFacei;
870 closestFaceRotation = faceRotation;
873 if (closestMatchDistSqr == 0)
881 closestFaceRotation != -1
882 && closestMatchDistSqr < absTolSqr
885 faceMap[lFacei] = closestFaceMatch;
887 rotation[lFacei] = closestFaceRotation;
889 if (lFacei != closestFaceMatch || closestFaceRotation > 0)
898 Pout<<
"Number of matches = " << nMatches <<
" / "
899 << pp.size() <<
endl;
904 const label localPtI = localFace[pI];
905 pts[pI] = localPts[localPtI];
909 <<
"No match for face " << localFace <<
nl << pts
925 UIPstream fromNeighbour(neighbProcNo(), pBufs);
926 fromNeighbour >> masterCtrs >> masterNormals
927 >> masterAnchors >> masterFacePointAverages;
930 if (
debug || masterCtrs.size() != pp.size())
936 /
name() +
"_nbrFaceCentres.obj"
938 Pout<<
"processorPolyPatch::order : "
939 <<
"Dumping neighbour faceCentres to " << nbrStr.
name()
943 writeOBJ(nbrStr, masterCtrs[facei]);
947 if (masterCtrs.size() != pp.size())
950 <<
"in patch:" <<
name() <<
" : "
951 <<
"Local size of patch is " << pp.size() <<
" (faces)."
953 <<
"Received from neighbour " << masterCtrs.size()
986 facePointAverages[fI] += ppPoints[facePoints[pI]];
989 facePointAverages[fI] /= facePoints.size();
995 *calcFaceTol(pp, pp.
points(), facePointAverages)
1007 masterFacePointAverages,
1019 faceMap[oldFacei] = faceMap2[oldFacei];
1029 if (!matchedAll ||
debug)
1035 /
name() +
"_faces.obj"
1037 Pout<<
"processorPolyPatch::order :"
1038 <<
" Writing faces to OBJ file " << str.
name() <<
endl;
1044 /
name() +
"_faceCentresConnections.obj"
1047 Pout<<
"processorPolyPatch::order :"
1048 <<
" Dumping newly found match as lines between"
1049 <<
" corresponding face centres to OBJ file "
1059 if (masterFacei != -1)
1061 const point& c0 = masterCtrs[masterFacei];
1071 <<
"in patch:" <<
name() <<
" : "
1072 <<
"Cannot match vectors to faces on both sides of patch"
1074 <<
" masterCtrs[0]:" << masterCtrs[0] <<
endl
1076 <<
" Check your topology changes or maybe you have"
1077 <<
" multiple separated (from cyclics) processor patches"
1079 <<
" Continuing with incorrect face ordering from now on"
1094 const point& wantedAnchor = masterAnchors[newFacei];
1096 rotation[newFacei] = getRotation
1104 if (rotation[newFacei] == -1)
1107 <<
"in patch " <<
name()
1109 <<
"Cannot find point on face " << pp[oldFacei]
1110 <<
" with vertices "
1112 <<
" that matches point " << wantedAnchor
1113 <<
" when matching the halves of processor patch "
1115 <<
"Continuing with incorrect face ordering from now on"
1124 if (
faceMap[facei] != facei || rotation[facei] != 0)
1140 os.
writeEntry(
"neighbProcNo", neighbProcNo_);
int debug
Static debugging option.
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)
const Field< PointType > & points() const
Return reference to global points.
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.
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.
Template functions to aid in the implementation of demand driven data.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
static label nProcs(const label communicator=0)
Number of processes in parallel run.
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
static bool & parRun()
Is this a parallel run?
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
An Ostream wrapper for parallel output to std::cout.
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)
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].
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf())
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
word name(const complex &c)
Return string representation of complex.
virtual const fileName & name() const
Return the name of the stream.
void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Neighbour processor patch.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Macros for easy insertion into run-time selection tables.
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)
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.
const Field< PointType > & faceNormals() const
Return face unit normals for patch.
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.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label ListType::const_reference const label start
const Field< PointType > & faceCentres() const
Return face centres for patch.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
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.
void setSize(const label newSize)
Alias for resize(const label)
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.
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.