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

processorPointPatch.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 "processorPointPatch.H"
00027 #include <OpenFOAM/pointBoundaryMesh.H>
00028 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00029 #include <OpenFOAM/pointMesh.H>
00030 #include <OpenFOAM/globalPointPatch.H>
00031 #include <OpenFOAM/faceList.H>
00032 #include <OpenFOAM/primitiveFacePatch.H>
00033 #include <OpenFOAM/emptyPolyPatch.H>
00034 
00035 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00036 
00037 namespace Foam
00038 {
00039 
00040 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00041 
00042 defineTypeNameAndDebug(processorPointPatch, 0);
00043 
00044 addToRunTimeSelectionTable
00045 (
00046     facePointPatch,
00047     processorPointPatch,
00048     polyPatch
00049 );
00050 
00051 
00052 // * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
00053 
00054 void Foam::processorPointPatch::initGeometry()
00055 {
00056     // Algorithm:
00057     // Depending on whether the patch is a master or a slave, get the primitive
00058     // patch points and filter away the points from the global patch.
00059 
00060     if (isMaster())
00061     {
00062         meshPoints_ = procPolyPatch_.meshPoints();
00063     }
00064     else
00065     {
00066         // Slave side. Create the reversed patch and pick up its points
00067         // so that the order is correct
00068         const polyPatch& pp = patch();
00069 
00070         faceList masterFaces(pp.size());
00071 
00072         forAll (pp, faceI)
00073         {
00074             masterFaces[faceI] = pp[faceI].reverseFace();
00075         }
00076 
00077         meshPoints_ = primitiveFacePatch
00078         (
00079             masterFaces,
00080             pp.points()
00081         ).meshPoints();
00082     }
00083 
00084     if (Pstream::parRun())
00085     {
00086         initPatchPatchPoints();
00087     }
00088 }
00089 
00090 
00091 void Foam::processorPointPatch::calcGeometry()
00092 {
00093     if (Pstream::parRun())
00094     {
00095         calcPatchPatchPoints();
00096     }
00097 
00098     // If it is not runing parallel or there are no global points
00099     // create a 1->1 map
00100     if
00101     (
00102         !Pstream::parRun()
00103      || !boundaryMesh().mesh().globalData().nGlobalPoints()
00104     )
00105     {
00106         nonGlobalPatchPoints_.setSize(meshPoints_.size());
00107         forAll(nonGlobalPatchPoints_, i)
00108         {
00109             nonGlobalPatchPoints_[i] = i;
00110         }
00111     }
00112     else
00113     {
00114         // Get reference to shared points
00115         const labelList& sharedPoints =
00116             boundaryMesh().globalPatch().meshPoints();
00117 
00118         nonGlobalPatchPoints_.setSize(meshPoints_.size());
00119 
00120         label noFiltPoints = 0;
00121 
00122         forAll (meshPoints_, pointI)
00123         {
00124             label curP = meshPoints_[pointI];
00125 
00126             bool found = false;
00127 
00128             forAll (sharedPoints, sharedI)
00129             {
00130                 if (sharedPoints[sharedI] == curP)
00131                 {
00132                     found = true;
00133                     break;
00134                 }
00135             }
00136 
00137             if (!found)
00138             {
00139                 nonGlobalPatchPoints_[noFiltPoints] = pointI;
00140                 meshPoints_[noFiltPoints] = curP;
00141                 noFiltPoints++;
00142             }
00143         }
00144 
00145         nonGlobalPatchPoints_.setSize(noFiltPoints);
00146         meshPoints_.setSize(noFiltPoints);
00147     }
00148 }
00149 
00150 
00151 void processorPointPatch::initPatchPatchPoints()
00152 {
00153     if (debug)
00154     {
00155         Info<< "processorPointPatch::calcPatchPatchPoints() : "
00156             << "constructing patch-patch points"
00157             << endl;
00158     }
00159 
00160     const polyBoundaryMesh& bm = boundaryMesh().mesh()().boundaryMesh();
00161 
00162     // Get the mesh points for this patch corresponding to the faces
00163     const labelList& ppmp = meshPoints();
00164 
00165     // Create a HashSet of the point labels for this patch
00166     Map<label> patchPointSet(2*ppmp.size());
00167 
00168     forAll (ppmp, ppi)
00169     {
00170         patchPointSet.insert(ppmp[ppi], ppi);
00171     }
00172 
00173 
00174     // Create the lists of patch-patch points
00175     labelListList patchPatchPoints(bm.size());
00176 
00177     // Create the lists of patch-patch point normals
00178     List<List<vector> > patchPatchPointNormals(bm.size());
00179 
00180     // Loop over all patches looking for other patches that share points
00181     forAll(bm, patchi)
00182     {
00183         if
00184         (
00185             patchi != index()                 // Ignore self-self
00186          && !isA<emptyPolyPatch>(bm[patchi])  // Ignore empty
00187          && !bm[patchi].coupled()             // Ignore other couples
00188         )
00189         {
00190             // Get the meshPoints for the other patch
00191             const labelList& meshPoints = bm[patchi].meshPoints();
00192 
00193             // Get the normals for the other patch
00194             const vectorField& normals = bm[patchi].pointNormals();
00195 
00196             label pppi = 0;
00197             forAll(meshPoints, pointi)
00198             {
00199                 label ppp = meshPoints[pointi];
00200 
00201                 // Check to see if the point of the other patch is shared with
00202                 // this patch
00203                 Map<label>::iterator iter = patchPointSet.find(ppp);
00204 
00205                 if (iter != patchPointSet.end())
00206                 {
00207                     // If it is shared initialise the patchPatchPoints for this
00208                     // patch
00209                     if (!patchPatchPoints[patchi].size())
00210                     {
00211                         patchPatchPoints[patchi].setSize(ppmp.size());
00212                         patchPatchPointNormals[patchi].setSize(ppmp.size());
00213                     }
00214 
00215                     // and add the entry
00216                     patchPatchPoints[patchi][pppi] = iter();
00217                     patchPatchPointNormals[patchi][pppi] = normals[pointi];
00218                     pppi++;
00219                 }
00220             }
00221 
00222             // Resise the list of shared points and normals for the patch
00223             // being considerd
00224             patchPatchPoints[patchi].setSize(pppi);
00225             patchPatchPointNormals[patchi].setSize(pppi);
00226         }
00227     }
00228 
00229     // Send the patchPatchPoints to the neighbouring processor
00230 
00231     OPstream toNeighbProc
00232     (
00233         Pstream::blocking,
00234         neighbProcNo()
00235     );
00236 
00237     toNeighbProc
00238         << ppmp.size()              // number of points for checking
00239         << patchPatchPoints
00240         << patchPatchPointNormals;
00241 
00242     if (debug)
00243     {
00244         Info<< "processorPointPatch::calcPatchPatchPoints() : "
00245             << "constructed patch-patch points"
00246             << endl;
00247     }
00248 }
00249 
00250 
00251 void Foam::processorPointPatch::calcPatchPatchPoints()
00252 {
00253     // Get the patchPatchPoints from the neighbouring processor
00254     IPstream fromNeighbProc
00255     (
00256         Pstream::blocking,
00257         neighbProcNo()
00258     );
00259 
00260     label nbrNPoints(readLabel(fromNeighbProc));
00261     labelListList patchPatchPoints(fromNeighbProc);
00262     List<List<vector> > patchPatchPointNormals(fromNeighbProc);
00263 
00264     pointBoundaryMesh& pbm = const_cast<pointBoundaryMesh&>(boundaryMesh());
00265     const labelList& ppmp = meshPoints();
00266 
00267     // Simple check for the very rare situation when not the same number
00268     // of points on both sides. This can happen with decomposed cyclics.
00269     // If on one side the cyclic shares a point with proc faces coming from
00270     // internal faces it will have a different number of points from
00271     // the situation where the cyclic and the 'normal' proc faces are fully
00272     // separate.
00273     if (nbrNPoints != ppmp.size())
00274     {
00275         WarningIn("processorPointPatch::calcPatchPatchPoints()")
00276             << "Processor patch " << name()
00277             << " has " << ppmp.size() << " points; coupled patch has "
00278             << nbrNPoints << " points." << endl
00279             << "   (usually due to decomposed cyclics)."
00280             << " This might give problems" << endl
00281             << "    when using point fields (interpolation, mesh motion)."
00282             << endl;
00283     }
00284 
00285 
00286 
00287     // Loop over the patches looking for other patches that share points
00288     forAll(patchPatchPoints, patchi)
00289     {
00290         const labelList& patchPoints = patchPatchPoints[patchi];
00291         const List<vector>& patchPointNormals = patchPatchPointNormals[patchi];
00292 
00293         // If there are potentially shared points for the patch being considered
00294         if (patchPoints.size())
00295         {
00296             // Get the current meshPoints list for the patch
00297             facePointPatch& fpp = refCast<facePointPatch>(pbm[patchi]);
00298             const labelList& fmp = fpp.meshPoints();
00299             labelList& mp = fpp.meshPoints_;
00300 
00301             const vectorField& fnormals = fpp.pointNormals();
00302             vectorField& normals = fpp.pointNormals_;
00303 
00304             // Create a HashSet of the point labels for the patch
00305             Map<label> patchPointSet(2*fmp.size());
00306 
00307             forAll (fmp, ppi)
00308             {
00309                 patchPointSet.insert(fmp[ppi], ppi);
00310             }
00311 
00312             label nPoints = mp.size();
00313             label lpi = 0;
00314             bool resized = false;
00315 
00316             // For each potentially shared point...
00317             forAll(patchPoints, ppi)
00318             {
00319                 // Check if it is not already in the patch,
00320                 // i.e. not part of a face of the patch
00321                 if (!patchPointSet.found(ppmp[patchPoints[ppi]]))
00322                 {
00323                     // If it isn't already in the patch check if the local
00324                     // meshPoints is already set and if not initialise the
00325                     // meshPoints_ and pointNormals_
00326                     if (!resized)
00327                     {
00328                         if (!mp.size() && fmp.size())
00329                         {
00330                             mp = fmp;
00331                             normals = fnormals;
00332 
00333                             nPoints = mp.size();
00334                         }
00335 
00336                         mp.setSize(nPoints + patchPoints.size());
00337                         loneMeshPoints_.setSize(patchPoints.size());
00338                         normals.setSize(nPoints + patchPoints.size());
00339                         resized = true;
00340                     }
00341 
00342                     // Add the new point to the patch
00343                     mp[nPoints] = ppmp[patchPoints[ppi]];
00344                     loneMeshPoints_[lpi++] = ppmp[patchPoints[ppi]];
00345                     normals[nPoints++] = patchPointNormals[ppi];
00346                 }
00347             }
00348 
00349             // If the lists have been resized points have been added.
00350             // Shrink the lists to the current size.
00351             if (resized)
00352             {
00353                 mp.setSize(nPoints);
00354                 loneMeshPoints_.setSize(lpi);
00355                 normals.setSize(nPoints);
00356             }
00357         }
00358     }
00359 }
00360 
00361 
00362 void processorPointPatch::initMovePoints(const pointField&)
00363 {}
00364 
00365 
00366 void processorPointPatch::movePoints(const pointField&)
00367 {}
00368 
00369 
00370 void processorPointPatch::initUpdateMesh()
00371 {
00372     facePointPatch::initUpdateMesh();
00373     processorPointPatch::initGeometry();
00374 }
00375 
00376 
00377 void processorPointPatch::updateMesh()
00378 {
00379     facePointPatch::updateMesh();
00380     processorPointPatch::calcGeometry();
00381 }
00382 
00383 
00384 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00385 
00386 processorPointPatch::processorPointPatch
00387 (
00388     const polyPatch& patch,
00389     const pointBoundaryMesh& bm
00390 )
00391 :
00392     coupledFacePointPatch(patch, bm),
00393     procPolyPatch_(refCast<const processorPolyPatch>(patch))
00394 {}
00395 
00396 
00397 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00398 
00399 processorPointPatch::~processorPointPatch()
00400 {}
00401 
00402 
00403 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00404 
00405 } // End namespace Foam
00406 
00407 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines