Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / mesh / cfMesh / utilities / surfaceTools / meshSurfacePartitioner / meshSurfacePartitionerFunctions.C
blobd15295ebea76394ec76903b5ba450dec8035bcf8
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 "meshSurfacePartitioner.H"
29 #include "helperFunctionsPar.H"
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 namespace Foam
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 void meshSurfacePartitioner::calculateCornersEdgesAndAddressing()
40     const labelList& bPoints = meshSurface_.boundaryPoints();
41     const labelList& bp = meshSurface_.bp();
42     const edgeList& edges = meshSurface_.edges();
43     const VRWGraph& edgeFaces = meshSurface_.edgeFaces();
44     const VRWGraph& pointFaces = meshSurface_.pointFaces();
46     corners_.clear();
47     edgePoints_.clear();
49     //- count the number of patches
50     label nPatches(0);
51     # ifdef USE_OMP
52     # pragma omp parallel
53     {
54         label localMax(0);
56         forAll(facePatch_, bfI)
57             localMax = Foam::max(localMax, facePatch_[bfI]);
59         # pragma omp critical
60         nPatches = Foam::max(localMax, nPatches);
61     }
62     # else
63     forAll(facePatch_, bfI)
64         nPatches = Foam::max(nPatches, facePatch_[bfI]);
65     # endif
66     ++nPatches;
68     //- set the size and starting creating addressing
69     patchPatches_.setSize(nPatches);
71     nEdgesAtPoint_.clear();
72     nEdgesAtPoint_.setSize(bPoints.size());
73     nEdgesAtPoint_ = 0;
75     featureEdges_.clear();
77     forAll(edgeFaces, edgeI)
78     {
79         if( edgeFaces.sizeOfRow(edgeI) != 2 )
80             continue;
82         const label patch0 = facePatch_[edgeFaces(edgeI, 0)];
83         const label patch1 = facePatch_[edgeFaces(edgeI, 1)];
85         if( patch0 != patch1 )
86         {
87             const edge& e = edges[edgeI];
88             ++nEdgesAtPoint_[bp[e.start()]];
89             ++nEdgesAtPoint_[bp[e.end()]];
91             patchPatches_[patch0].insert(patch1);
92             patchPatches_[patch1].insert(patch0);
94             featureEdges_.insert(edgeI);
95         }
96     }
98     if( Pstream::parRun() )
99     {
100         const Map<label>& otherFaceAtProc = meshSurface_.otherEdgeFaceAtProc();
102         //- find patches on other procs sharing surface edges
103         Map<label> otherFacePatch;
105         const DynList<label>& beNeiProcs = meshSurface_.beNeiProcs();
106         const Map<label>& globalToLocalEdges =
107             meshSurface_.globalToLocalBndEdgeAddressing();
109         std::map<label, labelLongList> exchangeData;
110         forAll(beNeiProcs, i)
111             exchangeData.insert(std::make_pair(beNeiProcs[i], labelLongList()));
113         forAllConstIter(Map<label>, globalToLocalEdges, it)
114         {
115             const label beI = it();
117             if( edgeFaces.sizeOfRow(beI) == 1 )
118             {
119                 labelLongList& data = exchangeData[otherFaceAtProc[beI]];
121                 data.append(it.key());
122                 data.append(facePatch_[edgeFaces(beI, 0)]);
123             }
124         }
126         labelLongList receivedData;
127         help::exchangeMap(exchangeData, receivedData);
129         for(label i=0;i<receivedData.size();)
130         {
131             const label geI = receivedData[i++];
132             const label patchI = receivedData[i++];
134             otherFacePatch.insert(globalToLocalEdges[geI], patchI);
135         }
137         //- take into account feature edges at processor boundaries
138         forAllConstIter(Map<label>, otherFaceAtProc, it)
139         {
140             const label beI = it.key();
142             if( it() <= Pstream::myProcNo() )
143                 continue;
144             if( otherFacePatch[beI] != facePatch_[edgeFaces(beI, 0)] )
145             {
146                 const edge& e = edges[beI];
147                 ++nEdgesAtPoint_[bp[e.start()]];
148                 ++nEdgesAtPoint_[bp[e.end()]];
149             }
150         }
152         //- gather data on all processors
153         exchangeData.clear();
154         const DynList<label>& bpNeiProcs = meshSurface_.bpNeiProcs();
155         forAll(bpNeiProcs, i)
156             exchangeData.insert(std::make_pair(bpNeiProcs[i], labelLongList()));
158         const Map<label>& globalToLocal =
159             meshSurface_.globalToLocalBndPointAddressing();
160         const VRWGraph& bpAtProcs = meshSurface_.bpAtProcs();
161         forAllConstIter(Map<label>, globalToLocal, it)
162         {
163             const label bpI = it();
165             forAllRow(bpAtProcs, bpI, i)
166             {
167                 const label procI = bpAtProcs(bpI, i);
169                 if( procI == Pstream::myProcNo() )
170                     continue;
172                 labelLongList& dts = exchangeData[procI];
174                 //- exchange data as follows:
175                 //- 1. global point label
176                 //- 2. number of feature edges connected to the vertex
177                 dts.append(it.key());
178                 dts.append(nEdgesAtPoint_[bpI]);
179             }
180         }
182         //- exchange information
183         receivedData.clear();
184         help::exchangeMap(exchangeData, receivedData);
186         //- add the edges from other processors to the points
187         label counter(0);
188         while( counter < receivedData.size() )
189         {
190             const label bpI = globalToLocal[receivedData[counter++]];
191             const label nEdges = receivedData[counter++];
193             nEdgesAtPoint_[bpI] += nEdges;
194         }
195     }
197     //- mark edges and corners
198     forAll(nEdgesAtPoint_, bpI)
199     {
200         if( nEdgesAtPoint_[bpI] > 2 )
201         {
202             corners_.insert(bpI);
203         }
204         else if( nEdgesAtPoint_[bpI] == 2 )
205         {
206             edgePoints_.insert(bpI);
207         }
208     }
210     //- find patches at a surface points
211     pointPatches_.setSize(pointFaces.size());
212     forAll(pointFaces, bpI)
213     {
214         forAllRow(pointFaces, bpI, pfI)
215             pointPatches_.appendIfNotIn(bpI, facePatch_[pointFaces(bpI, pfI)]);
216     }
218     if( Pstream::parRun() )
219     {
220         const Map<label>& globalToLocal =
221             meshSurface_.globalToLocalBndPointAddressing();
222         const DynList<label>& bpNeiProcs = meshSurface_.bpNeiProcs();
223         const VRWGraph& bpAtProcs = meshSurface_.bpAtProcs();
225         std::map<label, labelLongList> exchangeData;
226         forAll(bpNeiProcs, i)
227             exchangeData[bpNeiProcs[i]].clear();
229         forAllConstIter(Map<label>, globalToLocal, it)
230         {
231             const label bpI = it();
233             forAllRow(bpAtProcs, bpI, i)
234             {
235                 const label neiProc = bpAtProcs(bpI, i);
237                 if( neiProc == Pstream::myProcNo() )
238                     continue;
240                 labelLongList& data = exchangeData[neiProc];
242                 data.append(it.key());
243                 data.append(pointPatches_.sizeOfRow(bpI));
244                 forAllRow(pointPatches_, bpI, i)
245                     data.append(pointPatches_(bpI, i));
246             }
247         }
249         //- exchange data with other prcessors
250         labelLongList receivedData;
251         help::exchangeMap(exchangeData, receivedData);
253         label counter(0);
254         while( counter < receivedData.size() )
255         {
256             const label bpI = globalToLocal[receivedData[counter++]];
257             const label size = receivedData[counter++];
259             for(label i=0;i<size;++i)
260                 pointPatches_.appendIfNotIn(bpI, receivedData[counter++]);
261         }
262     }
264     label counter = corners_.size();
265     reduce(counter, sumOp<label>());
266     Info << "Found " << counter
267         << " corners at the surface of the volume mesh" << endl;
268     counter = edgePoints_.size();
269     reduce(counter, sumOp<label>());
270     Info << "Found " << counter
271         << " edge points at the surface of the volume mesh" << endl;
274 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
276 } // End namespace Foam
278 // ************************************************************************* //