FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

processorPolyPatch.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "processorPolyPatch.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <OpenFOAM/dictionary.H>
00029 #include <OpenFOAM/SubField.H>
00030 #include <OpenFOAM/demandDrivenData.H>
00031 #include <OpenFOAM/matchPoints.H>
00032 #include <OpenFOAM/OFstream.H>
00033 #include <OpenFOAM/polyMesh.H>
00034 #include <OpenFOAM/Time.H>
00035 #include <OpenFOAM/transformList.H>
00036 
00037 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00038 
00039 namespace Foam
00040 {
00041     defineTypeNameAndDebug(processorPolyPatch, 0);
00042     addToRunTimeSelectionTable(polyPatch, processorPolyPatch, dictionary);
00043 }
00044 
00045 
00046 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00047 
00048 Foam::processorPolyPatch::processorPolyPatch
00049 (
00050     const word& name,
00051     const label size,
00052     const label start,
00053     const label index,
00054     const polyBoundaryMesh& bm,
00055     const int myProcNo,
00056     const int neighbProcNo
00057 )
00058 :
00059     coupledPolyPatch(name, size, start, index, bm),
00060     myProcNo_(myProcNo),
00061     neighbProcNo_(neighbProcNo),
00062     neighbFaceCentres_(),
00063     neighbFaceAreas_(),
00064     neighbFaceCellCentres_(),
00065     neighbPointsPtr_(NULL),
00066     neighbEdgesPtr_(NULL)
00067 {}
00068 
00069 
00070 Foam::processorPolyPatch::processorPolyPatch
00071 (
00072     const word& name,
00073     const dictionary& dict,
00074     const label index,
00075     const polyBoundaryMesh& bm
00076 )
00077 :
00078     coupledPolyPatch(name, dict, index, bm),
00079     myProcNo_(readLabel(dict.lookup("myProcNo"))),
00080     neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))),
00081     neighbFaceCentres_(),
00082     neighbFaceAreas_(),
00083     neighbFaceCellCentres_(),
00084     neighbPointsPtr_(NULL),
00085     neighbEdgesPtr_(NULL)
00086 {}
00087 
00088 
00089 Foam::processorPolyPatch::processorPolyPatch
00090 (
00091     const processorPolyPatch& pp,
00092     const polyBoundaryMesh& bm
00093 )
00094 :
00095     coupledPolyPatch(pp, bm),
00096     myProcNo_(pp.myProcNo_),
00097     neighbProcNo_(pp.neighbProcNo_),
00098     neighbFaceCentres_(),
00099     neighbFaceAreas_(),
00100     neighbFaceCellCentres_(),
00101     neighbPointsPtr_(NULL),
00102     neighbEdgesPtr_(NULL)
00103 {}
00104 
00105 
00106 Foam::processorPolyPatch::processorPolyPatch
00107 (
00108     const processorPolyPatch& pp,
00109     const polyBoundaryMesh& bm,
00110     const label index,
00111     const label newSize,
00112     const label newStart
00113 )
00114 :
00115     coupledPolyPatch(pp, bm, index, newSize, newStart),
00116     myProcNo_(pp.myProcNo_),
00117     neighbProcNo_(pp.neighbProcNo_),
00118     neighbFaceCentres_(),
00119     neighbFaceAreas_(),
00120     neighbFaceCellCentres_(),
00121     neighbPointsPtr_(NULL),
00122     neighbEdgesPtr_(NULL)
00123 {}
00124 
00125 
00126 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00127 
00128 Foam::processorPolyPatch::~processorPolyPatch()
00129 {
00130     deleteDemandDrivenData(neighbPointsPtr_);
00131     deleteDemandDrivenData(neighbEdgesPtr_);
00132 }
00133 
00134 
00135 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00136 
00137 void Foam::processorPolyPatch::initGeometry()
00138 {
00139     if (Pstream::parRun())
00140     {
00141         OPstream toNeighbProc
00142         (
00143             Pstream::blocking,
00144             neighbProcNo(),
00145             3*(sizeof(label) + size()*sizeof(vector) + sizeof(scalar))
00146         );
00147 
00148         toNeighbProc
00149             << faceCentres()
00150             << faceAreas()
00151             << faceCellCentres();
00152     }
00153 }
00154 
00155 
00156 void Foam::processorPolyPatch::calcGeometry()
00157 {
00158     if (Pstream::parRun())
00159     {
00160         {
00161             IPstream fromNeighbProc
00162             (
00163                 Pstream::blocking,
00164                 neighbProcNo(),
00165                 3*(sizeof(label) + size()*sizeof(vector) + sizeof(scalar))
00166             );
00167             fromNeighbProc
00168                 >> neighbFaceCentres_
00169                 >> neighbFaceAreas_
00170                 >> neighbFaceCellCentres_;
00171         }
00172 
00173         // My normals
00174         vectorField faceNormals(size());
00175 
00176         // Neighbour normals
00177         vectorField nbrFaceNormals(neighbFaceAreas_.size());
00178 
00179         // Calculate normals from areas and check
00180         forAll(faceNormals, facei)
00181         {
00182             scalar magSf = mag(faceAreas()[facei]);
00183             scalar nbrMagSf = mag(neighbFaceAreas_[facei]);
00184             scalar avSf = (magSf + nbrMagSf)/2.0;
00185 
00186             if (magSf < ROOTVSMALL && nbrMagSf < ROOTVSMALL)
00187             {
00188                 // Undetermined normal. Use dummy normal to force separation
00189                 // check. (note use of sqrt(VSMALL) since that is how mag
00190                 // scales)
00191                 faceNormals[facei] = point(1, 0, 0);
00192                 nbrFaceNormals[facei] = faceNormals[facei];
00193             }
00194             else if (mag(magSf - nbrMagSf)/avSf > coupledPolyPatch::matchTol)
00195             {
00196                 FatalErrorIn
00197                 (
00198                     "processorPolyPatch::calcGeometry()"
00199                 )   << "face " << facei << " area does not match neighbour by "
00200                     << 100*mag(magSf - nbrMagSf)/avSf
00201                     << "% -- possible face ordering problem." << endl
00202                     << "patch:" << name()
00203                     << " my area:" << magSf
00204                     << " neighbour area:" << nbrMagSf
00205                     << " matching tolerance:" << coupledPolyPatch::matchTol
00206                     << endl
00207                     << "Mesh face:" << start()+facei
00208                     << " vertices:"
00209                     << UIndirectList<point>(points(), operator[](facei))()
00210                     << endl
00211                     << "Rerun with processor debug flag set for"
00212                     << " more information." << exit(FatalError);
00213             }
00214             else
00215             {
00216                 faceNormals[facei] = faceAreas()[facei]/magSf;
00217                 nbrFaceNormals[facei] = neighbFaceAreas_[facei]/nbrMagSf;
00218             }
00219         }
00220 
00221         calcTransformTensors
00222         (
00223             faceCentres(),
00224             neighbFaceCentres_,
00225             faceNormals,
00226             nbrFaceNormals,
00227             calcFaceTol(*this, points(), faceCentres())
00228         );
00229     }
00230 }
00231 
00232 
00233 void Foam::processorPolyPatch::initMovePoints(const pointField& p)
00234 {
00235     polyPatch::movePoints(p);
00236     processorPolyPatch::initGeometry();
00237 }
00238 
00239 
00240 void Foam::processorPolyPatch::movePoints(const pointField&)
00241 {
00242     processorPolyPatch::calcGeometry();
00243 }
00244 
00245 
00246 void Foam::processorPolyPatch::initUpdateMesh()
00247 {
00248     polyPatch::initUpdateMesh();
00249 
00250     deleteDemandDrivenData(neighbPointsPtr_);
00251     deleteDemandDrivenData(neighbEdgesPtr_);
00252 
00253     if (Pstream::parRun())
00254     {
00255         // Express all points as patch face and index in face.
00256         labelList pointFace(nPoints());
00257         labelList pointIndex(nPoints());
00258 
00259         for (label patchPointI = 0; patchPointI < nPoints(); patchPointI++)
00260         {
00261             label faceI = pointFaces()[patchPointI][0];
00262 
00263             pointFace[patchPointI] = faceI;
00264 
00265             const face& f = localFaces()[faceI];
00266 
00267             pointIndex[patchPointI] = findIndex(f, patchPointI);
00268         }
00269 
00270         // Express all edges as patch face and index in face.
00271         labelList edgeFace(nEdges());
00272         labelList edgeIndex(nEdges());
00273 
00274         for (label patchEdgeI = 0; patchEdgeI < nEdges(); patchEdgeI++)
00275         {
00276             label faceI = edgeFaces()[patchEdgeI][0];
00277 
00278             edgeFace[patchEdgeI] = faceI;
00279 
00280             const labelList& fEdges = faceEdges()[faceI];
00281 
00282             edgeIndex[patchEdgeI] = findIndex(fEdges, patchEdgeI);
00283         }
00284 
00285         OPstream toNeighbProc
00286         (
00287             Pstream::blocking,
00288             neighbProcNo(),
00289             8*sizeof(label)             // four headers of labelList
00290           + 2*nPoints()*sizeof(label)   // two point-based labellists
00291           + 2*nEdges()*sizeof(label)    // two edge-based labelLists
00292         );
00293 
00294         toNeighbProc
00295             << pointFace
00296             << pointIndex
00297             << edgeFace
00298             << edgeIndex;
00299     }
00300 }
00301 
00302 
00303 void Foam::processorPolyPatch::updateMesh()
00304 {
00305     // For completeness
00306     polyPatch::updateMesh();
00307 
00308     if (Pstream::parRun())
00309     {
00310         labelList nbrPointFace;
00311         labelList nbrPointIndex;
00312         labelList nbrEdgeFace;
00313         labelList nbrEdgeIndex;
00314 
00315         {
00316             // Note cannot predict exact size since opposite nPoints might
00317             // be different from one over here.
00318             IPstream fromNeighbProc(Pstream::blocking, neighbProcNo());
00319 
00320             fromNeighbProc
00321                 >> nbrPointFace
00322                 >> nbrPointIndex
00323                 >> nbrEdgeFace
00324                 >> nbrEdgeIndex;
00325         }
00326 
00327         // Convert neighbour faces and indices into face back into
00328         // my edges and points.
00329 
00330         // Convert points.
00331         // ~~~~~~~~~~~~~~~
00332 
00333         neighbPointsPtr_ = new labelList(nPoints(), -1);
00334         labelList& neighbPoints = *neighbPointsPtr_;
00335 
00336         forAll(nbrPointFace, nbrPointI)
00337         {
00338             // Find face and index in face on this side.
00339             const face& f = localFaces()[nbrPointFace[nbrPointI]];
00340             label index = (f.size() - nbrPointIndex[nbrPointI]) % f.size();
00341             label patchPointI = f[index];
00342 
00343             if (neighbPoints[patchPointI] == -1)
00344             {
00345                 // First reference of point
00346                 neighbPoints[patchPointI] = nbrPointI;
00347             }
00348             else if (neighbPoints[patchPointI] >= 0)
00349             {
00350                 // Point already visited. Mark as duplicate.
00351                 neighbPoints[patchPointI] = -2;
00352             }
00353         }
00354 
00355         // Reset all duplicate entries to -1.
00356         forAll(neighbPoints, patchPointI)
00357         {
00358             if (neighbPoints[patchPointI] == -2)
00359             {
00360                 neighbPoints[patchPointI] = -1;
00361             }
00362         }
00363 
00364         // Convert edges.
00365         // ~~~~~~~~~~~~~~
00366 
00367         neighbEdgesPtr_ = new labelList(nEdges(), -1);
00368         labelList& neighbEdges = *neighbEdgesPtr_;
00369 
00370         forAll(nbrEdgeFace, nbrEdgeI)
00371         {
00372             // Find face and index in face on this side.
00373             const labelList& f = faceEdges()[nbrEdgeFace[nbrEdgeI]];
00374             label index = (f.size() - nbrEdgeIndex[nbrEdgeI] - 1) % f.size();
00375             label patchEdgeI = f[index];
00376 
00377             if (neighbEdges[patchEdgeI] == -1)
00378             {
00379                 // First reference of edge
00380                 neighbEdges[patchEdgeI] = nbrEdgeI;
00381             }
00382             else if (neighbEdges[patchEdgeI] >= 0)
00383             {
00384                 // Edge already visited. Mark as duplicate.
00385                 neighbEdges[patchEdgeI] = -2;
00386             }
00387         }
00388 
00389         // Reset all duplicate entries to -1.
00390         forAll(neighbEdges, patchEdgeI)
00391         {
00392             if (neighbEdges[patchEdgeI] == -2)
00393             {
00394                 neighbEdges[patchEdgeI] = -1;
00395             }
00396         }
00397 
00398         // Remove any addressing used for shared points/edges calculation
00399         primitivePatch::clearOut();
00400     }
00401 }
00402 
00403 
00404 const Foam::labelList& Foam::processorPolyPatch::neighbPoints() const
00405 {
00406     if (!neighbPointsPtr_)
00407     {
00408         FatalErrorIn("processorPolyPatch::neighbPoints() const")
00409             << "No extended addressing calculated for patch " << name()
00410             << abort(FatalError);
00411     }
00412     return *neighbPointsPtr_;
00413 }
00414 
00415 
00416 const Foam::labelList& Foam::processorPolyPatch::neighbEdges() const
00417 {
00418     if (!neighbEdgesPtr_)
00419     {
00420         FatalErrorIn("processorPolyPatch::neighbEdges() const")
00421             << "No extended addressing calculated for patch " << name()
00422             << abort(FatalError);
00423     }
00424     return *neighbEdgesPtr_;
00425 }
00426 
00427 
00428 void Foam::processorPolyPatch::initOrder(const primitivePatch& pp) const
00429 {
00430     if (!Pstream::parRun())
00431     {
00432         return;
00433     }
00434 
00435     if (debug)
00436     {
00437         fileName nm
00438         (
00439             boundaryMesh().mesh().time().path()
00440            /name()+"_faces.obj"
00441         );
00442         Pout<< "processorPolyPatch::order : Writing my " << pp.size()
00443             << " faces to OBJ file " << nm << endl;
00444         writeOBJ(nm, pp, pp.points());
00445 
00446         // Calculate my face centres
00447         pointField ctrs(calcFaceCentres(pp, pp.points()));
00448 
00449         OFstream localStr
00450         (
00451             boundaryMesh().mesh().time().path()
00452            /name() + "_localFaceCentres.obj"
00453         );
00454         Pout<< "processorPolyPatch::order : "
00455             << "Dumping " << ctrs.size()
00456             << " local faceCentres to " << localStr.name() << endl;
00457 
00458         forAll(ctrs, faceI)
00459         {
00460             writeOBJ(localStr, ctrs[faceI]);
00461         }
00462     }
00463 
00464     const bool isMaster = Pstream::myProcNo() < neighbProcNo();
00465 
00466     if (isMaster)
00467     {
00468         pointField ctrs(calcFaceCentres(pp, pp.points()));
00469 
00470         pointField anchors(getAnchorPoints(pp, pp.points()));
00471 
00472         // Now send all info over to the neighbour
00473         OPstream toNeighbour(Pstream::blocking, neighbProcNo());
00474         toNeighbour << ctrs << anchors;
00475     }
00476 }
00477 
00478 
00479 // Return new ordering. Ordering is -faceMap: for every face index
00480 // the new face -rotation:for every new face the clockwise shift
00481 // of the original face. Return false if nothing changes (faceMap
00482 // is identity, rotation is 0)
00483 bool Foam::processorPolyPatch::order
00484 (
00485     const primitivePatch& pp,
00486     labelList& faceMap,
00487     labelList& rotation
00488 ) const
00489 {
00490     if (!Pstream::parRun())
00491     {
00492         return false;
00493     }
00494 
00495     faceMap.setSize(pp.size());
00496     faceMap = -1;
00497 
00498     rotation.setSize(pp.size());
00499     rotation = 0;
00500 
00501     const bool isMaster = Pstream::myProcNo() < neighbProcNo();
00502 
00503     if (isMaster)
00504     {
00505         // Do nothing (i.e. identical mapping, zero rotation).
00506         // See comment at top.
00507         forAll(faceMap, patchFaceI)
00508         {
00509             faceMap[patchFaceI] = patchFaceI;
00510         }
00511 
00512         return false;
00513     }
00514     else
00515     {
00516         vectorField masterCtrs;
00517         vectorField masterAnchors;
00518 
00519         // Receive data from neighbour
00520         {
00521             IPstream fromNeighbour(Pstream::blocking, neighbProcNo());
00522             fromNeighbour >> masterCtrs >> masterAnchors;
00523         }
00524 
00525         // Calculate my face centres
00526         pointField ctrs(calcFaceCentres(pp, pp.points()));
00527 
00528         // Calculate typical distance from face centre
00529         scalarField tols(calcFaceTol(pp, pp.points(), ctrs));
00530 
00531         if (debug || masterCtrs.size() != pp.size())
00532         {
00533             {
00534                 OFstream nbrStr
00535                 (
00536                     boundaryMesh().mesh().time().path()
00537                    /name() + "_nbrFaceCentres.obj"
00538                 );
00539                 Pout<< "processorPolyPatch::order : "
00540                     << "Dumping neighbour faceCentres to " << nbrStr.name()
00541                     << endl;
00542                 forAll(masterCtrs, faceI)
00543                 {
00544                     writeOBJ(nbrStr, masterCtrs[faceI]);
00545                 }
00546             }
00547 
00548             if (masterCtrs.size() != pp.size())
00549             {
00550                 FatalErrorIn
00551                 (
00552                     "processorPolyPatch::order(const primitivePatch&"
00553                     ", labelList&, labelList&) const"
00554                 )   << "in patch:" << name() << " : "
00555                     << "Local size of patch is " << pp.size() << " (faces)."
00556                     << endl
00557                     << "Received from neighbour " << masterCtrs.size()
00558                     << " faceCentres!"
00559                     << abort(FatalError);
00560             }
00561         }
00562 
00563         // Geometric match of face centre vectors
00564         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00565 
00566         // 1. Try existing ordering and transformation
00567         bool matchedAll = false;
00568 
00569         if
00570         (
00571             separated()
00572          && (separation().size() == 1 || separation().size() == pp.size())
00573         )
00574         {
00575             vectorField transformedCtrs;
00576 
00577             const vectorField& v = separation();
00578 
00579             if (v.size() == 1)
00580             {
00581                 transformedCtrs = masterCtrs-v[0];
00582             }
00583             else
00584             {
00585                 transformedCtrs = masterCtrs-v;
00586             }
00587             matchedAll = matchPoints
00588             (
00589                 ctrs,
00590                 transformedCtrs,
00591                 tols,
00592                 true,
00593                 faceMap
00594             );
00595 
00596             if (matchedAll)
00597             {
00598                 // Use transformed centers from now on
00599                 masterCtrs = transformedCtrs;
00600 
00601                 // Transform anchors
00602                 if (v.size() == 1)
00603                 {
00604                     masterAnchors -= v[0];
00605                 }
00606                 else
00607                 {
00608                     masterAnchors -= v;
00609                 }
00610             }
00611         }
00612         else if
00613         (
00614            !parallel()
00615          && (forwardT().size() == 1 || forwardT().size() == pp.size())
00616         )
00617         {
00618             vectorField transformedCtrs = masterCtrs;
00619             transformList(forwardT(), transformedCtrs);
00620             matchedAll = matchPoints
00621             (
00622                 ctrs,
00623                 transformedCtrs,
00624                 tols,
00625                 true,
00626                 faceMap
00627             );
00628 
00629             if (matchedAll)
00630             {
00631                 // Use transformed centers from now on
00632                 masterCtrs = transformedCtrs;
00633 
00634                 // Transform anchors
00635                 transformList(forwardT(), masterAnchors);
00636             }
00637         }
00638 
00639 
00640         // 2. Try zero separation automatic matching
00641         if (!matchedAll)
00642         {
00643             matchedAll = matchPoints(ctrs, masterCtrs, tols, true, faceMap);
00644         }
00645 
00646         if (!matchedAll || debug)
00647         {
00648             // Dump faces
00649             fileName str
00650             (
00651                 boundaryMesh().mesh().time().path()
00652                /name()/name()+"_faces.obj"
00653             );
00654             Pout<< "processorPolyPatch::order :"
00655                 << " Writing faces to OBJ file " << str.name() << endl;
00656             writeOBJ(str, pp, pp.points());
00657 
00658             OFstream ccStr
00659             (
00660                 boundaryMesh().mesh().time().path()
00661                /name() + "_faceCentresConnections.obj"
00662             );
00663 
00664             Pout<< "processorPolyPatch::order :"
00665                 << " Dumping newly found match as lines between"
00666                 << " corresponding face centres to OBJ file " << ccStr.name()
00667                 << endl;
00668 
00669             label vertI = 0;
00670 
00671             forAll(ctrs, faceI)
00672             {
00673                 label masterFaceI = faceMap[faceI];
00674 
00675                 if (masterFaceI != -1)
00676                 {
00677                     const point& c0 = masterCtrs[masterFaceI];
00678                     const point& c1 = ctrs[faceI];
00679                     writeOBJ(ccStr, c0, c1, vertI);
00680                 }
00681             }
00682         }
00683 
00684         if (!matchedAll)
00685         {
00686             SeriousErrorIn
00687             (
00688                 "processorPolyPatch::order(const primitivePatch&"
00689                 ", labelList&, labelList&) const"
00690             )   << "in patch:" << name() << " : "
00691                 << "Cannot match vectors to faces on both sides of patch"
00692                 << endl
00693                 << "    masterCtrs[0]:" << masterCtrs[0] << endl
00694                 << "    ctrs[0]:" << ctrs[0] << endl
00695                 << "    Please check your topology changes or maybe you have"
00696                 << " multiple separated (from cyclics) processor patches"
00697                 << endl
00698                 << "    Continuing with incorrect face ordering from now on!"
00699                 << endl;
00700 
00701             return false;
00702         }
00703 
00704         // Set rotation.
00705         forAll(faceMap, oldFaceI)
00706         {
00707             // The face f will be at newFaceI (after morphing) and we want its
00708             // anchorPoint (= f[0]) to align with the anchorpoint for the
00709             // corresponding face on the other side.
00710 
00711             label newFaceI = faceMap[oldFaceI];
00712 
00713             const point& wantedAnchor = masterAnchors[newFaceI];
00714 
00715             rotation[newFaceI] = getRotation
00716             (
00717                 pp.points(),
00718                 pp[oldFaceI],
00719                 wantedAnchor,
00720                 tols[oldFaceI]
00721             );
00722 
00723             if (rotation[newFaceI] == -1)
00724             {
00725                 SeriousErrorIn
00726                 (
00727                     "processorPolyPatch::order(const primitivePatch&"
00728                     ", labelList&, labelList&) const"
00729                 )   << "in patch " << name()
00730                     << " : "
00731                     << "Cannot find point on face " << pp[oldFaceI]
00732                     << " with vertices "
00733                     << UIndirectList<point>(pp.points(), pp[oldFaceI])()
00734                     << " that matches point " << wantedAnchor
00735                     << " when matching the halves of processor patch " << name()
00736                     << "Continuing with incorrect face ordering from now on!"
00737                     << endl;
00738 
00739                 return false;
00740             }
00741         }
00742 
00743         forAll(faceMap, faceI)
00744         {
00745             if (faceMap[faceI] != faceI || rotation[faceI] != 0)
00746             {
00747                 return true;
00748             }
00749         }
00750 
00751         return false;
00752     }
00753 }
00754 
00755 
00756 void Foam::processorPolyPatch::write(Ostream& os) const
00757 {
00758     polyPatch::write(os);
00759     os.writeKeyword("myProcNo") << myProcNo_
00760         << token::END_STATEMENT << nl;
00761     os.writeKeyword("neighbProcNo") << neighbProcNo_
00762         << token::END_STATEMENT << nl;
00763 }
00764 
00765 
00766 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines