1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
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
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/>.
26 \*---------------------------------------------------------------------------*/
28 #include "triSurfacePartitioner.H"
29 #include "demandDrivenData.H"
30 #include "labelLongList.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 void triSurfacePartitioner::calculatePatchAddressing()
46 calculateCornersAndAddressing();
48 calculatePatchPatches();
50 calculateEdgeGroups();
52 calculatePatchToEdgeGroups();
54 calculateEdgeGroupsToCorners();
57 void triSurfacePartitioner::calculateCornersAndAddressing()
59 const VRWGraph& pointFaces = surface_.pointFacets();
60 const edgeLongList& edges = surface_.edges();
61 const VRWGraph& edgeFaces = surface_.edgeFacets();
63 //- find the number of feature edges connected to each surface node
64 labelList nEdgesAtNode(surface_.points().size(), 0);
67 if( edgeFaces.sizeOfRow(eI) != 2 )
70 const label sPatch = surface_[edgeFaces(eI, 0)].region();
71 const label ePatch = surface_[edgeFaces(eI, 1)].region();
73 if( sPatch != ePatch )
75 const edge& e = edges[eI];
76 ++nEdgesAtNode[e.start()];
77 ++nEdgesAtNode[e.end()];
81 //- count the number of feature edges connected to each surface point
82 //- corners must have 3 or more edges attached to them
84 forAll(nEdgesAtNode, pI)
86 if( nEdgesAtNode[pI] < 3 )
92 corners_.setSize(nCorners);
93 cornerPatches_.setSize(nCorners);
97 DynList<label> patches;
98 forAll(pointFaces, pointI)
100 if( nEdgesAtNode[pointI] < 3 )
104 forAllRow(pointFaces, pointI, pfI)
105 patches.appendIfNotIn(surface_[pointFaces(pointI, pfI)].region());
107 corners_[nCorners] = pointI;
108 cornerPatches_[nCorners] = patches;
113 void triSurfacePartitioner::calculatePatchPatches()
115 const VRWGraph& edgeFaces = surface_.edgeFacets();
117 forAll(edgeFaces, eI)
119 if( edgeFaces.sizeOfRow(eI) != 2 )
121 Warning << "Surface is not a manifold!!" << endl;
125 const label sPatch = surface_[edgeFaces(eI, 0)].region();
126 const label ePatch = surface_[edgeFaces(eI, 1)].region();
128 if( sPatch != ePatch )
130 patchPatches_[sPatch].insert(ePatch);
131 patchPatches_[ePatch].insert(sPatch);
136 void triSurfacePartitioner::calculateEdgeGroups()
138 const edgeLongList& edges = surface_.edges();
139 const VRWGraph& edgeFaces = surface_.edgeFacets();
140 const VRWGraph& pointEdges = surface_.pointEdges();
143 //- make all feature edges
144 boolList featureEdge(edgeFaces.size(), false);
147 # pragma omp parallel for schedule(dynamic, 40)
149 forAll(edgeFaces, eI)
151 DynList<label> patches;
152 forAllRow(edgeFaces, eI, efI)
153 patches.appendIfNotIn(surface_[edgeFaces(eI, efI)].region());
155 if( patches.size() > 1 )
156 featureEdge[eI] = true;
159 //- create a set containing corners for fast searching
160 labelHashSet corners;
162 corners.insert(corners_[i]);
164 edgeGroups_.setSize(edgeFaces.size());
168 forAll(featureEdge, eI)
170 if( !featureEdge[eI] )
172 if( edgeGroups_[eI] != -1 )
177 edgeGroups_[eI] = nGroups;
178 featureEdge[eI] = false;
180 while( front.size() )
182 const label eLabel = front.removeLastElement();
183 const edge& e = edges[eLabel];
185 for(label pI=0;pI<2;++pI)
187 const label pointI = e[pI];
189 if( corners.found(pointI) )
192 forAllRow(pointEdges, pointI, peI)
194 const label eJ = pointEdges(pointI, peI);
196 if( featureEdge[eJ] && (edgeGroups_[eJ] == -1) )
198 edgeGroups_[eJ] = nGroups;
199 featureEdge[eJ] = false;
209 Info << nGroups << " edge groups found!" << endl;
211 edgeGroupEdgeGroups_.clear();
212 edgeGroupEdgeGroups_.setSize(nGroups);
215 void triSurfacePartitioner::calculatePatchToEdgeGroups()
217 const VRWGraph& edgeFaces = surface_.edgeFacets();
219 forAll(edgeFaces, eI)
221 if( edgeGroups_[eI] < 0 )
224 DynList<label> patches;
225 forAllRow(edgeFaces, eI, efI)
226 patches.appendIfNotIn(surface_[edgeFaces(eI, efI)].region());
230 const label patchI = patches[i];
232 for(label j=i+1;j<patches.size();++j)
234 const label patchJ = patches[j];
236 const std::pair<label, label> pp
238 Foam::min(patchI, patchJ),
239 Foam::max(patchI, patchJ)
242 patchesEdgeGroups_[pp].insert(edgeGroups_[eI]);
248 void triSurfacePartitioner::calculateEdgeGroupsToCorners()
250 const VRWGraph& pointEdges = surface_.pointEdges();
252 forAll(corners_, cornerI)
254 DynList<label> edgeGroupsAtCorner;
255 const label pointI = corners_[cornerI];
257 forAllRow(pointEdges, pointI, peI)
258 edgeGroupsAtCorner.appendIfNotIn
260 edgeGroups_[pointEdges(pointI, peI)]
263 forAll(edgeGroupsAtCorner, i)
265 const label epI = edgeGroupsAtCorner[i];
268 for(label j=i+1;j<edgeGroupsAtCorner.size();++j)
270 const label epJ = edgeGroupsAtCorner[j];
274 std::pair<label, label> ep
280 //- create edgepartition - edge partitions addressing
281 edgeGroupEdgeGroups_[ep.first].insert(ep.second);
282 edgeGroupEdgeGroups_[ep.second].insert(ep.first);
284 edgeGroupsCorners_[ep].insert(cornerI);
290 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
292 } // End namespace Foam
294 // ************************************************************************* //