Moving cfMesh into place. Updated contibutors list
[foam-extend-3.2.git] / src / mesh / cfMesh / meshLibrary / utilities / smoothers / topology / checkCellConnectionsOverFaces / checkCellConnectionsOverFaces.C
bloba67d16d3d68fa24757027df8951dc011359eb593
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | cfMesh: A library for mesh generation
4    \\    /   O peration     |
5     \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6      \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9     This file is part of cfMesh.
11     cfMesh is free software; you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation; either version 3 of the License, or (at your
14     option) any later version.
16     cfMesh is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with cfMesh.  If not, see <http://www.gnu.org/licenses/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "checkCellConnectionsOverFaces.H"
29 #include "labelLongList.H"
30 #include "labelledPair.H"
32 # ifdef USE_OMP
33 #include <omp.h>
34 # endif
36 #include <set>
37 #include <map>
39 #include "helperFunctions.H"
41 //#define DEBUGCheck
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 namespace Foam
48 // * * * * * * * * * * Private member functions * * * * * * * * * * * * * * * //
50 namespace meshConnectionsHelper
53 class meshConnectionsNeighbourOperator
55     const polyMeshGen& mesh_;
57 public:
59     meshConnectionsNeighbourOperator(const polyMeshGen& mesh)
60     :
61         mesh_(mesh)
62     {}
64     label size() const
65     {
66         return mesh_.cells().size();
67     }
69     void operator()(const label cellI, DynList<label>& neighbourCells) const
70     {
71         neighbourCells.clear();
73         const labelList& owner = mesh_.owner();
74         const labelList& neighbour = mesh_.neighbour();
76         const cell& c = mesh_.cells()[cellI];
78         forAll(c, fI)
79         {
80             label nei = owner[c[fI]];
82             if( nei == cellI )
83                 nei = neighbour[c[fI]];
85             if( nei >= 0 )
86                 neighbourCells.append(nei);
87         }
88     }
90     template<class labelListType>
91     void collectGroups
92     (
93         std::map<label, DynList<label> >& neiGroups,
94         const labelListType& elementInGroup,
95         const DynList<label>& localGroupLabel
96     ) const
97     {
98         const PtrList<processorBoundaryPatch>& procBoundaries =
99             mesh_.procBoundaries();
100         const labelList& owner = mesh_.owner();
102         //- send the data to other processors
103         forAll(procBoundaries, patchI)
104         {
105             const label start = procBoundaries[patchI].patchStart();
106             const label size = procBoundaries[patchI].patchSize();
108             labelList groupOwner(procBoundaries[patchI].patchSize());
109             for(label faceI=0;faceI<size;++faceI)
110             {
111                 const label groupI = elementInGroup[owner[start+faceI]];
113                 if( groupI < 0 )
114                 {
115                     groupOwner[faceI] = -1;
116                     continue;
117                 }
119                 groupOwner[faceI] = localGroupLabel[groupI];
120             }
122             OPstream toOtherProc
123             (
124                 Pstream::blocking,
125                 procBoundaries[patchI].neiProcNo(),
126                 groupOwner.byteSize()
127             );
129             toOtherProc << groupOwner;
130         }
132         //- receive data from other processors
133         forAll(procBoundaries, patchI)
134         {
135             const label start = procBoundaries[patchI].patchStart();
137             labelList receivedData;
139             IPstream fromOtherProc
140             (
141                 Pstream::blocking,
142                 procBoundaries[patchI].neiProcNo()
143             );
145             fromOtherProc >> receivedData;
147             forAll(receivedData, faceI)
148             {
149                 if( receivedData[faceI] < 0 )
150                     continue;
152                 const label groupI = elementInGroup[owner[start+faceI]];
154                 if( groupI < 0 )
155                     continue;
157                 DynList<label>& ng = neiGroups[localGroupLabel[groupI]];
159                 //- store the connection over the inter-processor boundary
160                 ng.appendIfNotIn(receivedData[faceI]);
161             }
162         }
163     }
166 class meshConnectionsSelectorOperator
169 public:
171     meshConnectionsSelectorOperator()
172     {}
174     bool operator()(const label cellI) const
175     {
176         return true;
177     }
180 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
182 } // End namespace meshConnectionsHelper
184 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
186 void checkCellConnectionsOverFaces::findCellGroups()
188     Info << "Checking cell connections" << endl;
190     mesh_.owner();
191     nGroups_ =
192         help::groupMarking
193         (
194             cellGroup_,
195             meshConnectionsHelper::meshConnectionsNeighbourOperator(mesh_),
196             meshConnectionsHelper::meshConnectionsSelectorOperator()
197         );
199     Info << "Finished checking cell connections" << endl;
202 // * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * * * //
203 // Constructors
205 checkCellConnectionsOverFaces::checkCellConnectionsOverFaces(polyMeshGen& mesh)
207     mesh_(mesh),
208     cellGroup_(mesh.cells().size(), -1),
209     nGroups_(0)
211     findCellGroups();
214 // * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * * * * * //
216 checkCellConnectionsOverFaces::~checkCellConnectionsOverFaces()
219 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
221 bool checkCellConnectionsOverFaces::checkCellGroups()
223     if( nGroups_ == 1 )
224         return false;
226     Warning << "Mesh has " << nGroups_ << " unconnected regions" << endl;
228     labelList nCellsInGroup(nGroups_, 0);
230     forAll(cellGroup_, cI)
231         ++nCellsInGroup[cellGroup_[cI]];
233     if( Pstream::parRun() )
234     {
235         forAll(nCellsInGroup, groupI)
236             reduce(nCellsInGroup[groupI], sumOp<label>());
237     }
239     //- find groups which has most cells this group will be kept
240     label maxGroup(-1);
241     forAll(nCellsInGroup, groupI)
242         if( nCellsInGroup[groupI] > maxGroup )
243         {
244             maxGroup = nCellsInGroup[groupI];
245             nGroups_ = groupI;
246         }
248     //- remove cells which are not in the group which has max num of cells
249     boolList removeCell(mesh_.cells().size(), false);
250     forAll(cellGroup_, cellI)
251         if( cellGroup_[cellI] != nGroups_ )
252             removeCell[cellI] = true;
254     polyMeshGenModifier(mesh_).removeCells(removeCell);
256     return true;
259 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
261 } // End namespace Foam
263 // ************************************************************************* //