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)
797 UIPstream fromNeighbour(neighbProcNo(), pBufs);
798 fromNeighbour >> masterPts >> masterFaces;
808 const face& localFace = localFaces[lFacei];
809 label faceRotation = -1;
811 const scalar absTolSqr =
sqr(SMALL);
813 scalar closestMatchDistSqr =
sqr(GREAT);
814 scalar matchDistSqr =
sqr(GREAT);
815 label closestFaceMatch = -1;
816 label closestFaceRotation = -1;
818 forAll(masterFaces, mFacei)
820 const face& masterFace = masterFaces[mFacei];
822 faceRotation = matchFace
836 && matchDistSqr < closestMatchDistSqr
839 closestMatchDistSqr = matchDistSqr;
840 closestFaceMatch = mFacei;
841 closestFaceRotation = faceRotation;
844 if (closestMatchDistSqr == 0)
850 if (closestFaceRotation != -1 && closestMatchDistSqr == 0)
852 faceMap[lFacei] = closestFaceMatch;
854 rotation[lFacei] = closestFaceRotation;
856 if (lFacei != closestFaceMatch || closestFaceRotation > 0)
865 Pout<<
"Number of matches = " << nMatches <<
" / " 866 << pp.size() <<
endl;
871 const label localPtI = localFace[pI];
872 pts[pI] = localPts[localPtI];
876 <<
"No match for face " << localFace <<
nl << pts
892 UIPstream fromNeighbour(neighbProcNo(), pBufs);
893 fromNeighbour >> masterCtrs >> masterNormals
894 >> masterAnchors >> masterFacePointAverages;
903 if (debug || masterCtrs.
size() != pp.size())
909 /
name() +
"_nbrFaceCentres.obj" 911 Pout<<
"processorPolyPatch::order : " 912 <<
"Dumping neighbour faceCentres to " << nbrStr.
name()
916 writeOBJ(nbrStr, masterCtrs[facei]);
920 if (masterCtrs.
size() != pp.size())
923 <<
"in patch:" <<
name() <<
" : " 924 <<
"Local size of patch is " << pp.size() <<
" (faces)." 926 <<
"Received from neighbour " << masterCtrs.
size()
959 facePointAverages[fI] += ppPoints[facePoints[pI]];
962 facePointAverages[fI] /= facePoints.
size();
967 calcFaceTol(pp, pp.
points(), facePointAverages)
974 masterFacePointAverages,
984 if (faceMap[oldFacei] == -1)
986 faceMap[oldFacei] = faceMap2[oldFacei];
994 if (faceMap[oldFacei] == -1)
1001 if (!matchedAll || debug)
1007 /
name() +
"_faces.obj" 1009 Pout<<
"processorPolyPatch::order :" 1010 <<
" Writing faces to OBJ file " << str.
name() <<
endl;
1016 /
name() +
"_faceCentresConnections.obj" 1019 Pout<<
"processorPolyPatch::order :" 1020 <<
" Dumping newly found match as lines between" 1021 <<
" corresponding face centres to OBJ file " 1029 label masterFacei = faceMap[facei];
1031 if (masterFacei != -1)
1033 const point& c0 = masterCtrs[masterFacei];
1043 <<
"in patch:" <<
name() <<
" : " 1044 <<
"Cannot match vectors to faces on both sides of patch" 1046 <<
" masterCtrs[0]:" << masterCtrs[0] <<
endl 1048 <<
" Check your topology changes or maybe you have" 1049 <<
" multiple separated (from cyclics) processor patches" 1051 <<
" Continuing with incorrect face ordering from now on" 1058 forAll(faceMap, oldFacei)
1064 label newFacei = faceMap[oldFacei];
1066 const point& wantedAnchor = masterAnchors[newFacei];
1068 rotation[newFacei] = getRotation
1076 if (rotation[newFacei] == -1)
1079 <<
"in patch " <<
name()
1081 <<
"Cannot find point on face " << pp[oldFacei]
1082 <<
" with vertices " 1084 <<
" that matches point " << wantedAnchor
1085 <<
" when matching the halves of processor patch " 1087 <<
"Continuing with incorrect face ordering from now on" 1096 if (faceMap[facei] != facei || rotation[facei] != 0)
#define forAll(list, i)
Loop across all elements in list.
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.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
const labelList & neighbEdges() const
Return neighbour edge labels. WIP.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
void size(const label)
Override size to be inconsistent with allocated storage.
bool circulate(const CirculatorBase::direction dir=NONE)
Circulate around the list in the given direction.
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.
const Field< PointType > & points() const
Return reference to global points.
difference_type nRotations() const
Return the distance between the iterator and the fulcrum. This is.
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.
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.
word name() const
Return file name (part beyond last /)
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.
virtual const fileName & name() const
Return the name of the stream.
virtual ~processorPolyPatch()
Destructor.
List< label > labelList
A List of labels.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
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.
prefixOSstream Pout(cout,"Pout")
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineTypeNameAndDebug(combustionModel, 0)
const Field< PointType > & faceCentres() const
Return face centres for patch.
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.
Ostream & writeKeyword(const keyType &)
Write the keyword followed by an appropriate indentation.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
word name(const complex &)
Return a string representation of a complex.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
void setSize(const label)
Reset size of List.
Template functions to aid in the implementation of demand driven data.
static bool & parRun()
Is this a parallel run?
const Field< PointType > & faceNormals() const
Return face normals for patch.
vector point
Point is a vector.
A List with indirect addressing.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
const labelList & neighbPoints() const
Return neighbour point labels. WIP.
dimensioned< scalar > mag(const dimensioned< Type > &)
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
Walks over a container as if it were circular. The container must have the following members defined:...
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.
const fileName & name() const
Return the name of the stream.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
dimensionSet transform(const dimensionSet &)
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.