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

syncTools.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 "syncTools.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 
00029 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00030 
00031 // Does anyone have couples? Since meshes might have 0 cells and 0 proc
00032 // boundaries need to reduce this info.
00033 bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches)
00034 {
00035     bool hasAnyCouples = false;
00036 
00037     forAll(patches, patchI)
00038     {
00039         if (patches[patchI].coupled())
00040         {
00041             hasAnyCouples = true;
00042             break;
00043         }
00044     }
00045     return returnReduce(hasAnyCouples, orOp<bool>());
00046 }
00047 
00048 
00049 void Foam::syncTools::checkTransform
00050 (
00051     const coupledPolyPatch& pp,
00052     const bool applySeparation
00053 )
00054 {
00055     if (!pp.parallel() && pp.forwardT().size() > 1)
00056     {
00057         FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
00058             << "Non-uniform transformation not supported for point or edge"
00059             << " fields." << endl
00060             << "Patch:" << pp.name()
00061             << abort(FatalError);
00062     }
00063     if (applySeparation && pp.separated() && pp.separation().size() > 1)
00064     {
00065         FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
00066             << "Non-uniform separation vector not supported for point or edge"
00067             << " fields." << endl
00068             << "Patch:" << pp.name()
00069             << abort(FatalError);
00070     }
00071 }
00072 
00073 
00074 // Determines for every point whether it is coupled and if so sets only one.
00075 Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
00076 {
00077     PackedBoolList isMasterPoint(mesh.nPoints(), 0);
00078     PackedBoolList donePoint(mesh.nPoints(), 0);
00079 
00080 
00081     // Do multiple shared points. Min. proc is master
00082     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00083 
00084     const labelList& sharedPointAddr =
00085         mesh.globalData().sharedPointAddr();
00086 
00087     labelList minProc(mesh.globalData().nGlobalPoints(), labelMax);
00088 
00089     UIndirectList<label>(minProc, sharedPointAddr) = Pstream::myProcNo();
00090 
00091     Pstream::listCombineGather(minProc, minEqOp<label>());
00092     Pstream::listCombineScatter(minProc);
00093 
00094     const labelList& sharedPointLabels =
00095         mesh.globalData().sharedPointLabels();
00096 
00097     forAll(sharedPointAddr, i)
00098     {
00099         if (minProc[sharedPointAddr[i]] == Pstream::myProcNo())
00100         {
00101             isMasterPoint.set(sharedPointLabels[i], 1u);
00102         }
00103         donePoint.set(sharedPointLabels[i], 1u);
00104     }
00105 
00106 
00107     // Do other points on coupled patches
00108     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00109 
00110     const polyBoundaryMesh& patches = mesh.boundaryMesh();
00111 
00112     forAll(patches, patchI)
00113     {
00114         if (patches[patchI].coupled())
00115         {
00116             if
00117             (
00118                 Pstream::parRun()
00119              && isA<processorPolyPatch>(patches[patchI])
00120             )
00121             {
00122                 const processorPolyPatch& pp =
00123                     refCast<const processorPolyPatch>(patches[patchI]);
00124 
00125                 const labelList& meshPoints = pp.meshPoints();
00126 
00127                 forAll(meshPoints, i)
00128                 {
00129                     label pointI = meshPoints[i];
00130 
00131                     if (donePoint.get(pointI) == 0u)
00132                     {
00133                         donePoint.set(pointI, 1u);
00134 
00135                         if (pp.owner())
00136                         {
00137                             isMasterPoint.set(pointI, 1u);
00138                         }
00139                     }
00140                 }
00141             }
00142             else if (isA<cyclicPolyPatch>(patches[patchI]))
00143             {
00144                 const cyclicPolyPatch& pp =
00145                     refCast<const cyclicPolyPatch>(patches[patchI]);
00146 
00147                 const edgeList& coupledPoints = pp.coupledPoints();
00148                 const labelList& meshPoints = pp.meshPoints();
00149 
00150                 forAll(coupledPoints, i)
00151                 {
00152                     // First one of couple points is master
00153 
00154                     const edge& pointPair = coupledPoints[i];
00155                     label p0 = meshPoints[pointPair[0]];
00156                     label p1 = meshPoints[pointPair[1]];
00157 
00158                     if (donePoint.get(p0) == 0u)
00159                     {
00160                         donePoint.set(p0, 1u);
00161                         isMasterPoint.set(p0, 1u);
00162                         donePoint.set(p1, 1u);
00163                     }
00164                 }
00165             }
00166             else
00167             {
00168                 FatalErrorIn("syncTools::getMasterPoints(const polyMesh&)")
00169                     << "Cannot handle coupled patch " << patches[patchI].name()
00170                     << " of type " <<  patches[patchI].type()
00171                     << abort(FatalError);
00172             }
00173         }
00174     }
00175 
00176 
00177     // Do all other points
00178     // ~~~~~~~~~~~~~~~~~~~
00179 
00180     forAll(donePoint, pointI)
00181     {
00182         if (donePoint.get(pointI) == 0u)
00183         {
00184             donePoint.set(pointI, 1u);
00185             isMasterPoint.set(pointI, 1u);
00186         }
00187     }
00188 
00189     return isMasterPoint;
00190 }
00191 
00192 
00193 // Determines for every edge whether it is coupled and if so sets only one.
00194 Foam::PackedBoolList Foam::syncTools::getMasterEdges(const polyMesh& mesh)
00195 {
00196     PackedBoolList isMasterEdge(mesh.nEdges(), 0);
00197     PackedBoolList doneEdge(mesh.nEdges(), 0);
00198 
00199 
00200     // Do multiple shared edges. Min. proc is master
00201     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00202 
00203     const labelList& sharedEdgeAddr =
00204         mesh.globalData().sharedEdgeAddr();
00205 
00206     labelList minProc(mesh.globalData().nGlobalEdges(), labelMax);
00207 
00208     UIndirectList<label>(minProc, sharedEdgeAddr) = Pstream::myProcNo();
00209 
00210     Pstream::listCombineGather(minProc, minEqOp<label>());
00211     Pstream::listCombineScatter(minProc);
00212 
00213     const labelList& sharedEdgeLabels =
00214         mesh.globalData().sharedEdgeLabels();
00215 
00216     forAll(sharedEdgeAddr, i)
00217     {
00218         if (minProc[sharedEdgeAddr[i]] == Pstream::myProcNo())
00219         {
00220             isMasterEdge.set(sharedEdgeLabels[i], 1u);
00221         }
00222         doneEdge.set(sharedEdgeLabels[i], 1u);
00223     }
00224 
00225 
00226     // Do other edges on coupled patches
00227     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00228 
00229     const polyBoundaryMesh& patches = mesh.boundaryMesh();
00230 
00231     forAll(patches, patchI)
00232     {
00233         if (patches[patchI].coupled())
00234         {
00235             if
00236             (
00237                 Pstream::parRun()
00238              && isA<processorPolyPatch>(patches[patchI])
00239             )
00240             {
00241                 const processorPolyPatch& pp =
00242                     refCast<const processorPolyPatch>(patches[patchI]);
00243 
00244                 const labelList& meshEdges = pp.meshEdges();
00245 
00246                 forAll(meshEdges, i)
00247                 {
00248                     label edgeI = meshEdges[i];
00249 
00250                     if (doneEdge.get(edgeI) == 0u)
00251                     {
00252                         doneEdge.set(edgeI, 1u);
00253 
00254                         if (pp.owner())
00255                         {
00256                             isMasterEdge.set(edgeI, 1u);
00257                         }
00258                     }
00259                 }
00260             }
00261             else if (isA<cyclicPolyPatch>(patches[patchI]))
00262             {
00263                 const cyclicPolyPatch& pp =
00264                     refCast<const cyclicPolyPatch>(patches[patchI]);
00265 
00266                 const edgeList& coupledEdges = pp.coupledEdges();
00267                 const labelList& meshEdges = pp.meshEdges();
00268 
00269                 forAll(coupledEdges, i)
00270                 {
00271                     // First one of couple edges is master
00272 
00273                     const edge& edgePair = coupledEdges[i];
00274                     label e0 = meshEdges[edgePair[0]];
00275                     label e1 = meshEdges[edgePair[1]];
00276 
00277                     if (doneEdge.get(e0) == 0u)
00278                     {
00279                         doneEdge.set(e0, 1u);
00280                         isMasterEdge.set(e0, 1u);
00281                         doneEdge.set(e1, 1u);
00282                     }
00283                 }
00284             }
00285             else
00286             {
00287                 FatalErrorIn("syncTools::getMasterEdges(const polyMesh&)")
00288                     << "Cannot handle coupled patch " << patches[patchI].name()
00289                     << " of type " <<  patches[patchI].type()
00290                     << abort(FatalError);
00291             }
00292         }
00293     }
00294 
00295 
00296     // Do all other edges
00297     // ~~~~~~~~~~~~~~~~~~
00298 
00299     forAll(doneEdge, edgeI)
00300     {
00301         if (doneEdge.get(edgeI) == 0u)
00302         {
00303             doneEdge.set(edgeI, 1u);
00304             isMasterEdge.set(edgeI, 1u);
00305         }
00306     }
00307 
00308     return isMasterEdge;
00309 }
00310 
00311 
00312 // Determines for every face whether it is coupled and if so sets only one.
00313 Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
00314 {
00315     PackedBoolList isMasterFace(mesh.nFaces(), 1);
00316 
00317     const polyBoundaryMesh& patches = mesh.boundaryMesh();
00318 
00319     forAll(patches, patchI)
00320     {
00321         if (patches[patchI].coupled())
00322         {
00323             if (Pstream::parRun() && isA<processorPolyPatch>(patches[patchI]))
00324             {
00325                 const processorPolyPatch& pp =
00326                     refCast<const processorPolyPatch>(patches[patchI]);
00327 
00328                 if (!pp.owner())
00329                 {
00330                     forAll(pp, i)
00331                     {
00332                         isMasterFace.set(pp.start()+i, 0);
00333                     }
00334                 }
00335             }
00336             else if (isA<cyclicPolyPatch>(patches[patchI]))
00337             {
00338                 const cyclicPolyPatch& pp =
00339                     refCast<const cyclicPolyPatch>(patches[patchI]);
00340 
00341                 for (label i = pp.size()/2; i < pp.size(); i++)
00342                 {
00343                     isMasterFace.set(pp.start()+i, 0);
00344                 }
00345             }
00346             else
00347             {
00348                 FatalErrorIn("syncTools::getMasterFaces(const polyMesh&)")
00349                     << "Cannot handle coupled patch " << patches[patchI].name()
00350                     << " of type " <<  patches[patchI].type()
00351                     << abort(FatalError);
00352             }
00353         }
00354     }
00355 
00356     return isMasterFace;
00357 }
00358 
00359 
00360 template <>
00361 void Foam::syncTools::separateList
00362 (
00363     const vectorField& separation,
00364     UList<vector>& field
00365 )
00366 {
00367     if (separation.size() == 1)
00368     {
00369         // Single value for all.
00370 
00371         forAll(field, i)
00372         {
00373             field[i] += separation[0];
00374         }
00375     }
00376     else if (separation.size() == field.size())
00377     {
00378         forAll(field, i)
00379         {
00380             field[i] += separation[i];
00381         }
00382     }
00383     else
00384     {
00385         FatalErrorIn
00386         (
00387             "syncTools::separateList(const vectorField&, UList<vector>&)"
00388         )   << "Sizes of field and transformation not equal. field:"
00389             << field.size() << " transformation:" << separation.size()
00390             << abort(FatalError);
00391     }
00392 }
00393 
00394 
00395 template <>
00396 void Foam::syncTools::separateList
00397 (
00398     const vectorField& separation,
00399     Map<vector>& field
00400 )
00401 {
00402     if (separation.size() == 1)
00403     {
00404         // Single value for all.
00405         forAllIter(Map<vector>, field, iter)
00406         {
00407             iter() += separation[0];
00408         }
00409     }
00410     else if (separation.size() == field.size())
00411     {
00412         forAllIter(Map<vector>, field, iter)
00413         {
00414             iter() += separation[iter.key()];
00415         }
00416     }
00417     else
00418     {
00419         FatalErrorIn
00420         (
00421             "syncTools::separateList(const vectorField&, Map<vector>&)"
00422         )   << "Sizes of field and transformation not equal. field:"
00423             << field.size() << " transformation:" << separation.size()
00424             << abort(FatalError);
00425     }
00426 }
00427 
00428 
00429 template <>
00430 void Foam::syncTools::separateList
00431 (
00432     const vectorField& separation,
00433     EdgeMap<vector>& field
00434 )
00435 {
00436     if (separation.size() == 1)
00437     {
00438         // Single value for all.
00439         forAllIter(EdgeMap<vector>, field, iter)
00440         {
00441             iter() += separation[0];
00442         }
00443     }
00444     else
00445     {
00446         FatalErrorIn
00447         (
00448             "syncTools::separateList(const vectorField&, EdgeMap<vector>&)"
00449         )   << "Multiple separation vectors not supported. field:"
00450             << field.size() << " transformation:" << separation.size()
00451             << abort(FatalError);
00452     }
00453 }
00454 
00455 
00456 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines