58 const int neighbProcNo,
65 neighbProcNo_(neighbProcNo),
68 neighbFaceCellCentres_()
79 const int neighbProcNo,
86 newName(myProcNo, neighbProcNo),
95 neighbProcNo_(neighbProcNo),
98 neighbFaceCellCentres_()
108 const word& patchType
114 neighbFaceCentres_(),
116 neighbFaceCellCentres_()
127 myProcNo_(pp.myProcNo_),
128 neighbProcNo_(pp.neighbProcNo_),
129 neighbFaceCentres_(),
131 neighbFaceCellCentres_()
145 myProcNo_(pp.myProcNo_),
146 neighbProcNo_(pp.neighbProcNo_),
147 neighbFaceCentres_(),
149 neighbFaceCellCentres_()
163 myProcNo_(pp.myProcNo_),
164 neighbProcNo_(pp.neighbProcNo_),
165 neighbFaceCentres_(),
167 neighbFaceCellCentres_()
175 neighbPointsPtr_.clear();
176 neighbEdgesPtr_.clear();
184 const label myProcNo,
185 const label neighbProcNo
200 UOPstream toNeighbProc(neighbProcNo(), pBufs);
205 << faceCellCentres();
215 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
218 >> neighbFaceCentres_
220 >> neighbFaceCellCentres_;
227 vectorField nbrFaceNormals(neighbFaceAreas_.size());
233 forAll(faceNormals, facei)
235 scalar magSf =
mag(faceAreas()[facei]);
236 scalar nbrMagSf =
mag(neighbFaceAreas_[facei]);
237 scalar avSf = (magSf + nbrMagSf)/2.0;
241 if (magSf < small || nbrMagSf < small)
245 faceNormals[facei] =
point(1, 0, 0);
246 nbrFaceNormals[facei] = -faceNormals[facei];
249 else if (
mag(magSf - nbrMagSf) > matchTolerance()*
sqr(tols[facei]))
257 Pout<<
"processorPolyPatch::calcGeometry : Writing my " 259 <<
" faces to OBJ file " << nm <<
endl;
266 /
name() +
"_faceCentresConnections.obj" 269 Pout<<
"processorPolyPatch::calcGeometry :" 270 <<
" Dumping cell centre lines between" 271 <<
" corresponding face centres to OBJ file" << ccStr.
name()
276 forAll(faceCentres(), facej)
278 const point& c0 = neighbFaceCentres_[facej];
279 const point&
c1 = faceCentres()[facej];
285 <<
"face " << facei <<
" area does not match neighbour by " 286 << 100*
mag(magSf - nbrMagSf)/avSf
287 <<
"% -- possible face ordering problem." << endl
288 <<
"patch:" <<
name()
289 <<
" my area:" << magSf
290 <<
" neighbour area:" << nbrMagSf
291 <<
" matching tolerance:" 292 << matchTolerance()*
sqr(tols[facei])
294 <<
"Mesh face:" << start()+facei
298 <<
"If you are certain your matching is correct" 299 <<
" you can increase the 'matchTolerance' setting" 300 <<
" in the patch dictionary in the boundary file." 302 <<
"Rerun with processor debug flag set for" 307 faceNormals[facei] = faceAreas()[facei]/magSf;
308 nbrFaceNormals[facei] = neighbFaceAreas_[facei]/nbrMagSf;
318 matchTolerance()*tols,
357 for (
label patchPointi = 0; patchPointi <
nPoints(); patchPointi++)
359 label facei = pointFaces()[patchPointi][0];
361 pointFace[patchPointi] = facei;
363 const face&
f = localFaces()[facei];
365 pointIndex[patchPointi] =
findIndex(f, patchPointi);
372 for (
label patchEdgeI = 0; patchEdgeI < nEdges(); patchEdgeI++)
374 label facei = edgeFaces()[patchEdgeI][0];
376 edgeFace[patchEdgeI] = facei;
378 const labelList& fEdges = faceEdges()[facei];
380 edgeIndex[patchEdgeI] =
findIndex(fEdges, patchEdgeI);
383 UOPstream toNeighbProc(neighbProcNo(), pBufs);
399 neighbPointsPtr_.clear();
400 neighbEdgesPtr_.clear();
418 UIPstream fromNeighbProc(neighbProcNo(), pBufs);
434 labelList& neighbPoints = neighbPointsPtr_();
436 forAll(nbrPointFace, nbrPointi)
439 const face&
f = localFaces()[nbrPointFace[nbrPointi]];
441 label index = (f.
size() - nbrPointIndex[nbrPointi]) % f.
size();
442 label patchPointi = f[index];
444 if (neighbPoints[patchPointi] == -1)
447 neighbPoints[patchPointi] = nbrPointi;
449 else if (neighbPoints[patchPointi] >= 0)
452 neighbPoints[patchPointi] = -2;
457 forAll(neighbPoints, patchPointi)
459 if (neighbPoints[patchPointi] == -2)
461 neighbPoints[patchPointi] = -1;
468 neighbEdgesPtr_.reset(
new labelList(nEdges(), -1));
469 labelList& neighbEdges = neighbEdgesPtr_();
471 forAll(nbrEdgeFace, nbrEdgeI)
474 const labelList&
f = faceEdges()[nbrEdgeFace[nbrEdgeI]];
475 label index = (f.
size() - nbrEdgeIndex[nbrEdgeI] - 1) % f.
size();
476 label patchEdgeI = f[index];
478 if (neighbEdges[patchEdgeI] == -1)
481 neighbEdges[patchEdgeI] = nbrEdgeI;
483 else if (neighbEdges[patchEdgeI] >= 0)
486 neighbEdges[patchEdgeI] = -2;
491 forAll(neighbEdges, patchEdgeI)
493 if (neighbEdges[patchEdgeI] == -2)
495 neighbEdges[patchEdgeI] = -1;
508 if (!neighbPointsPtr_.valid())
511 <<
"No extended addressing calculated for patch " <<
name()
514 return neighbPointsPtr_();
520 if (!neighbEdgesPtr_.valid())
523 <<
"No extended addressing calculated for patch " <<
name()
526 return neighbEdgesPtr_();
552 Pout<<
"processorPolyPatch::order : Writing my " << pp.size()
553 <<
" faces to OBJ file " << nm <<
endl;
562 /
name() +
"_localFaceCentres.obj" 564 Pout<<
"processorPolyPatch::order : " 565 <<
"Dumping " << fc.size()
566 <<
" local faceCentres to " << localStr.
name() <<
endl;
579 UOPstream toNeighbour(neighbProcNo(), pBufs);
599 facePointAverages[fI] += ppPoints[facePoints[pI]];
602 facePointAverages[fI] /= facePoints.
size();
606 UOPstream toNeighbour(neighbProcNo(), pBufs);
608 << anchors << facePointAverages;
620 const bool sameOrientation,
621 const scalar absTolSqr,
633 if (!sameOrientation)
640 scalar closestMatchDistSqr =
sqr(great);
647 const scalar diffSqr =
magSqr(aPts[aCirc()] - bPts[bCirc()]);
649 if (diffSqr < absTolSqr)
657 if (!sameOrientation)
666 matchDistSqr = diffSqr;
670 const scalar diffSqr2 =
magSqr(aPts[aCirc()] - bPts[bCirc2()]);
672 if (diffSqr2 > absTolSqr)
678 matchDistSqr += diffSqr2;
688 if (matchDistSqr < closestMatchDistSqr)
690 closestMatchDistSqr = matchDistSqr;
692 if (!sameOrientation)
701 if (closestMatchDistSqr == 0)
712 }
while (bCirc.
circulate(circulateDirection));
714 matchDistSqr = closestMatchDistSqr;
751 forAll(faceMap, patchFacei)
753 faceMap[patchFacei] = patchFacei;
768 forAll(faceMap, patchFacei)
770 const point& wantedAnchor = anchors[patchFacei];
772 rotation[patchFacei] = getRotation
780 if (rotation[patchFacei] > 0)
803 UIPstream fromNeighbour(neighbProcNo(), pBufs);
804 fromNeighbour >> masterPts >> masterFaces;
814 const face& localFace = localFaces[lFacei];
815 label faceRotation = -1;
817 const scalar absTolSqr =
sqr(tols[lFacei]);
819 scalar closestMatchDistSqr =
sqr(great);
820 scalar matchDistSqr =
sqr(great);
821 label closestFaceMatch = -1;
822 label closestFaceRotation = -1;
824 forAll(masterFaces, mFacei)
826 const face& masterFace = masterFaces[mFacei];
828 faceRotation = matchFace
842 && matchDistSqr < closestMatchDistSqr
845 closestMatchDistSqr = matchDistSqr;
846 closestFaceMatch = mFacei;
847 closestFaceRotation = faceRotation;
850 if (closestMatchDistSqr == 0)
858 closestFaceRotation != -1
859 && closestMatchDistSqr < absTolSqr
862 faceMap[lFacei] = closestFaceMatch;
864 rotation[lFacei] = closestFaceRotation;
866 if (lFacei != closestFaceMatch || closestFaceRotation > 0)
875 Pout<<
"Number of matches = " << nMatches <<
" / " 876 << pp.size() <<
endl;
881 const label localPtI = localFace[pI];
882 pts[pI] = localPts[localPtI];
886 <<
"No match for face " << localFace <<
nl << pts
902 UIPstream fromNeighbour(neighbProcNo(), pBufs);
903 fromNeighbour >> masterCtrs >> masterNormals
904 >> masterAnchors >> masterFacePointAverages;
907 if (debug || masterCtrs.
size() != pp.size())
913 /
name() +
"_nbrFaceCentres.obj" 915 Pout<<
"processorPolyPatch::order : " 916 <<
"Dumping neighbour faceCentres to " << nbrStr.
name()
920 writeOBJ(nbrStr, masterCtrs[facei]);
924 if (masterCtrs.
size() != pp.size())
927 <<
"in patch:" <<
name() <<
" : " 928 <<
"Local size of patch is " << pp.size() <<
" (faces)." 930 <<
"Received from neighbour " << masterCtrs.
size()
963 facePointAverages[fI] += ppPoints[facePoints[pI]];
966 facePointAverages[fI] /= facePoints.
size();
971 calcFaceTol(pp, pp.
points(), facePointAverages)
978 masterFacePointAverages,
988 if (faceMap[oldFacei] == -1)
990 faceMap[oldFacei] = faceMap2[oldFacei];
998 if (faceMap[oldFacei] == -1)
1005 if (!matchedAll || debug)
1011 /
name() +
"_faces.obj" 1013 Pout<<
"processorPolyPatch::order :" 1014 <<
" Writing faces to OBJ file " << str.
name() <<
endl;
1020 /
name() +
"_faceCentresConnections.obj" 1023 Pout<<
"processorPolyPatch::order :" 1024 <<
" Dumping newly found match as lines between" 1025 <<
" corresponding face centres to OBJ file " 1033 label masterFacei = faceMap[facei];
1035 if (masterFacei != -1)
1037 const point& c0 = masterCtrs[masterFacei];
1047 <<
"in patch:" <<
name() <<
" : " 1048 <<
"Cannot match vectors to faces on both sides of patch" 1050 <<
" masterCtrs[0]:" << masterCtrs[0] <<
endl 1052 <<
" Check your topology changes or maybe you have" 1053 <<
" multiple separated (from cyclics) processor patches" 1055 <<
" Continuing with incorrect face ordering from now on" 1062 forAll(faceMap, oldFacei)
1068 label newFacei = faceMap[oldFacei];
1070 const point& wantedAnchor = masterAnchors[newFacei];
1072 rotation[newFacei] = getRotation
1080 if (rotation[newFacei] == -1)
1083 <<
"in patch " <<
name()
1085 <<
"Cannot find point on face " << pp[oldFacei]
1086 <<
" with vertices " 1088 <<
" that matches point " << wantedAnchor
1089 <<
" when matching the halves of processor patch " 1091 <<
"Continuing with incorrect face ordering from now on" 1100 if (faceMap[facei] != facei || rotation[facei] != 0)
1116 writeEntry(os,
"neighbProcNo", neighbProcNo_);
virtual const fileName & name() const
Return the name of the stream.
#define forAll(list, i)
Loop across all elements in list.
const labelList & neighbPoints() const
Return neighbour point labels. WIP.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
A face is a list of labels corresponding to mesh vertices.
A list of keyword definitions, which are a keyword followed by any number of values (e...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const Field< PointType > & faceCentres() const
Return face centres for patch.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
void size(const label)
Override size to be inconsistent with allocated storage.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
static word newName(const label myProcNo, const label neighbProcNo)
Return the name of a processorPolyPatch.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
direction
Direction type enumeration.
void setIteratorToFulcrum()
Set the iterator to the current position of the fulcrum.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
const fileName & name() const
Return the name of the stream.
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.
void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
Input inter-processor communications stream operating on external buffer.
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.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
A class for handling words, derived from string.
word name() const
Return file name (part beyond last /)
const Field< PointType > & points() const
Return reference to global points.
virtual ~processorPolyPatch()
Destructor.
List< label > labelList
A List of labels.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
const Field< PointType > & faceNormals() const
Return face normals for patch.
errorManip< error > abort(error &err)
label readLabel(Istream &is)
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
dimensioned< scalar > magSqr(const dimensioned< Type > &)
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Output inter-processor communications stream operating on external buffer.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
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.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
word name(const complex &)
Return a string representation of a complex.
difference_type nRotations() const
Return the distance between the iterator and the fulcrum. This is.
void setSize(const label)
Reset size of List.
Template functions to aid in the implementation of demand driven data.
bool circulate(const CirculatorBase::direction dir=CirculatorBase::direction::none)
Circulate around the list in the given direction.
static bool & parRun()
Is this a parallel run?
vector point
Point is a vector.
prefixOSstream Pout(cout, "Pout")
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
A List with indirect addressing.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m^2].
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
dimensioned< scalar > mag(const dimensioned< Type > &)
Walks over a container as if it were circular. The container must have the following members defined:...
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
const labelList & neighbEdges() const
Return neighbour edge labels. WIP.
void setFulcrumToIterator()
Set the fulcrum to the current position of the iterator.
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.
dimensionSet transform(const dimensionSet &)
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
fileName path(UMean.rootPath()/UMean.caseName()/functionObjects::writeFile::outputPrefix/"graphs"/UMean.instance())