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 / octrees / meshOctree / meshOctreeAddressing / meshOctreeAddressingIrregularConnections.C
blob346b6b00086b69c86fc0900aff50a99a29ca8f56
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 "meshOctreeAddressing.H"
29 #include "meshOctree.H"
30 #include "demandDrivenData.H"
31 #include "helperFunctionsPar.H"
33 #include <map>
35 //#define DEBUGAutoRef
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 namespace Foam
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 void meshOctreeAddressing::checkAndFixIrregularConnections()
46     Info << "Checking the surface of the selected boxes" << endl;
48     const labelLongList& owner = this->octreeFaceOwner();
49     const labelLongList& neighbour = this->octreeFaceNeighbour();
50     const VRWGraph& faceEdges = this->faceEdges();
51     const VRWGraph& edgeFaces = this->edgeFaces();
52     const VRWGraph& edgeLeaves = this->edgeLeaves();
53     const VRWGraph& pointFaces = this->nodeFaces();
55     List<direction>& boxType = *boxTypePtr_;
57     boolList boundaryFace(owner.size());
59     label nIrregular;
60     DynList<label> front;
62     do
63     {
64         nIrregular = 0;
66         labelHashSet changedBoxType(100);
68         //- find boundary faces
69         boundaryFace = false;
71         forAll(owner, faceI)
72         {
73             const label own = owner[faceI];
74             const label nei = neighbour[faceI];
76             if( nei < 0 )
77             {
78                 continue;
79             }
80             else
81             {
83                 if(
84                     ((boxType[nei] & BOUNDARY) && (boxType[own] & MESHCELL))
85                 ||  ((boxType[own] & BOUNDARY) && (boxType[nei] & MESHCELL))
86                 )
87                     boundaryFace[faceI] = true;
88             }
89         }
91         //- remove irregular connections over edges
92         forAll(edgeFaces, edgeI)
93         {
94             label nBoundaryFaces(0);
95             forAllRow(edgeFaces, edgeI, efI)
96             {
97                 const label faceI = edgeFaces(edgeI, efI);
99                 if( boundaryFace[faceI] )
100                     ++nBoundaryFaces;
101             }
103             if( nBoundaryFaces > 2 )
104             {
105                 ++nIrregular;
106                 forAllRow(edgeLeaves, edgeI, elI)
107                 {
108                     const label leafI = edgeLeaves(edgeI, elI);
109                     boxType[leafI] = BOUNDARY;
110                     changedBoxType.insert(leafI);
111                 }
112             }
113         }
115         //- check if there exist two or more boundary face groups
116         //- connected to a vertex
117         forAll(pointFaces, pI)
118         {
119             //- find boundary faces connected to the vertex
120             labelHashSet bndFacesAtNode(pointFaces.sizeOfRow(pI));
121             forAllRow(pointFaces, pI, pfI)
122             {
123                 const label faceI = pointFaces(pI, pfI);
124                 if( boundaryFace[faceI] )
125                     bndFacesAtNode.insert(faceI);
126             }
128             //- find the number of face groups at a given vertex
129             label nGroups(0);
130             bool watertightSurface(true);
131             while( bndFacesAtNode.size() != 0 )
132             {
133                 front.clear();
134                 front.append(bndFacesAtNode.begin().key());
135                 bndFacesAtNode.erase(front[0]);
137                 while( front.size() != 0 )
138                 {
139                     const label fLabel = front.removeLastElement();
141                     forAllRow(faceEdges, fLabel, feI)
142                     {
143                         const label eI = faceEdges(fLabel, feI);
145                         bool found(false);
146                         forAllRow(edgeFaces, eI, efI)
147                         {
148                             const label fJ = edgeFaces(eI, efI);
150                             if( bndFacesAtNode.found(fJ) )
151                             {
152                                 found = true;
153                                 front.append(fJ);
154                                 bndFacesAtNode.erase(fJ);
155                             }
156                         }
158                         if( !found )
159                         {
160                             watertightSurface = false;
161                             break;
162                         }
163                     }
164                 }
166                 ++nGroups;
167             }
169             if( watertightSurface && (nGroups > 1) )
170             {
171                 ++nIrregular;
173                 //- this vertex has two groups of faces connected to it
174                 forAllRow(pointFaces, pI, pfI)
175                 {
176                     const label faceI = pointFaces(pI, pfI);
177                     if( boundaryFace[faceI] )
178                     {
179                         //- set BOUNDARY flag to all boxes connected to it
180                         if( boxType[owner[faceI]] & MESHCELL )
181                         {
182                             changedBoxType.insert(owner[faceI]);
183                             boxType[owner[faceI]] = BOUNDARY;
184                         }
186                         if( neighbour[faceI] == -1 )
187                             continue;
189                         if( boxType[neighbour[faceI]] & MESHCELL )
190                         {
191                             changedBoxType.insert(neighbour[faceI]);
192                             boxType[neighbour[faceI]] = BOUNDARY;
193                         }
194                     }
195                 }
196             }
197         }
199         reduce(nIrregular, sumOp<label>());
200         Info << nIrregular << " surface connections found!" << endl;
202         if( Pstream::parRun() && (nIrregular != 0) )
203         {
204             LongList<meshOctreeCubeCoordinates> exchangeData;
205             forAllConstIter(labelHashSet, changedBoxType, it)
206                 exchangeData.append(octree_.returnLeaf(it.key()).coordinates());
208             LongList<meshOctreeCubeCoordinates> receivedData;
209             octree_.exchangeRequestsWithNeighbourProcessors
210             (
211                 exchangeData,
212                 receivedData
213             );
215             forAll(receivedData, i)
216             {
217                 const label leafI =
218                     octree_.findLeafLabelForPosition(receivedData[i]);
219                 if( leafI < 0 )
220                     continue;
222                 boxType[leafI] = BOUNDARY;
223             }
224         }
226     } while( nIrregular != 0 );
228     clearNodeAddressing();
229     clearOctreeFaces();
230     clearAddressing();
232     Info << "Finished checking the surface of the selected boxes" << endl;
235 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
237 } // End namespace Foam
239 // ************************************************************************* //