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 "boundaryLayers.H"
29 #include "meshSurfaceEngine.H"
30 #include "decomposeCells.H"
31 #include "helperFunctions.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 void boundaryLayers::checkTopologyOfBoundaryFaces(const labelList& patchLabels)
47 if( !patchWiseLayers_ )
50 Info << "Checking topology of boundary faces" << endl;
52 labelHashSet usedPatches;
53 forAll(patchLabels, i)
54 usedPatches.insert(patchLabels[i]);
56 //- create a set of patch pairs. These are pairs at which the layers
57 //- shall be terminated
58 std::set<std::pair<label, label> > terminatedPairs;
59 forAll(treatPatchesWithPatch_, patchI)
61 const DynList<label>& otherPatches = treatPatchesWithPatch_[patchI];
63 forAll(otherPatches, patchJ)
65 if( patchI == otherPatches[patchJ] )
68 terminatedPairs.insert
72 Foam::min(patchI, otherPatches[patchJ]),
73 Foam::max(patchI, otherPatches[patchJ])
81 boolList decomposeCell(mesh_.cells().size(), false);
87 const meshSurfaceEngine& mse = this->surfaceEngine();
88 const faceList::subList& bFaces = mse.boundaryFaces();
89 const labelList& faceOwner = mse.faceOwners();
90 const labelList& facePatches = mse.boundaryFacePatches();
91 const VRWGraph& faceEdges = mse.faceEdges();
92 const VRWGraph& edgeFaces = mse.edgeFaces();
94 const Map<label>& otherProcPatch = mse.otherEdgeFacePatch();
96 VRWGraph newBoundaryFaces;
97 labelLongList newBoundaryOwners;
98 labelLongList newBoundaryPatches;
102 const face& bf = bFaces[bfI];
103 const label fPatch = facePatches[bfI];
105 if( !usedPatches.found(fPatch) )
108 //- find patches of neighbour faces
109 labelList neiPatches(bf.size());
112 const label beI = faceEdges(bfI, eI);
114 if( edgeFaces.sizeOfRow(beI) == 2 )
116 label neiFace = edgeFaces(beI, 0);
118 neiFace = edgeFaces(beI, 1);
120 neiPatches[eI] = facePatches[neiFace];
122 else if( edgeFaces.sizeOfRow(beI) == 1 )
124 //- edge is at a parallel boundary
125 neiPatches[eI] = otherProcPatch[beI];
129 //- find feature edges and check if the patches meeting there
130 //- shall be treated together.
131 bool storedFace(false);
132 forAll(neiPatches, eI)
134 if( neiPatches[eI] == fPatch )
137 std::pair<label, label> pp
139 Foam::min(fPatch, neiPatches[eI]),
140 Foam::max(fPatch, neiPatches[eI])
143 if( terminatedPairs.find(pp) == terminatedPairs.end() )
146 //- create a new face from this edge and the neighbouring edges
147 bool usePrev(false), useNext(false);
148 if( neiPatches[neiPatches.rcIndex(eI)] == fPatch )
154 std::pair<label, label> ppPrev
156 Foam::min(fPatch, neiPatches[neiPatches.rcIndex(eI)]),
157 Foam::max(fPatch, neiPatches[neiPatches.rcIndex(eI)])
160 if( terminatedPairs.find(ppPrev) == terminatedPairs.end() )
164 if( neiPatches[neiPatches.fcIndex(eI)] == fPatch )
170 std::pair<label, label> ppNext
172 Foam::min(fPatch, neiPatches[neiPatches.fcIndex(eI)]),
173 Foam::max(fPatch, neiPatches[neiPatches.fcIndex(eI)])
176 if( terminatedPairs.find(ppNext) == terminatedPairs.end() )
180 DynList<edge> removeEdges;
181 if( useNext && usePrev )
183 removeEdges.setSize(3);
184 removeEdges[0] = bf.faceEdge(neiPatches.rcIndex(eI));
185 removeEdges[1] = bf.faceEdge(eI);
186 removeEdges[2] = bf.faceEdge(neiPatches.fcIndex(eI));
190 removeEdges.setSize(2);
191 removeEdges[0] = bf.faceEdge(neiPatches.fcIndex(eI));
192 removeEdges[1] = bf.faceEdge(eI);
196 removeEdges.setSize(2);
197 removeEdges[0] = bf.faceEdge(neiPatches.rcIndex(eI));
198 removeEdges[1] = bf.faceEdge(eI);
201 const face cutFace = help::removeEdgesFromFace(bf, removeEdges);
202 if( cutFace.size() > 2 )
204 newBoundaryFaces.appendList(cutFace);
205 newBoundaryOwners.append(faceOwner[bfI]);
206 newBoundaryPatches.append(fPatch);
208 const face rFace = help::createFaceFromRemovedPart(bf, cutFace);
209 if( rFace.size() > 2 )
211 newBoundaryFaces.appendList(rFace);
212 newBoundaryOwners.append(faceOwner[bfI]);
213 newBoundaryPatches.append(fPatch);
216 if( (cutFace.size() > 2) && (rFace.size() > 2) )
218 decomposeCell[faceOwner[bfI]] = true;
230 newBoundaryFaces.appendList(bf);
231 newBoundaryOwners.append(faceOwner[bfI]);
232 newBoundaryPatches.append(fPatch);
236 //- Finally, replace the boundary faces
237 reduce(changed, maxOp<bool>());
241 polyMeshGenModifier(mesh_).replaceBoundary
254 //- decompose owner cells adjacent to the decomposed faces
255 reduce(nDecomposed, sumOp<label>());
257 if( nDecomposed != 0 )
259 FatalError << "Critical. Not tested" << exit(FatalError);
260 decomposeCells dc(mesh_);
261 dc.decomposeMesh(decomposeCell);
267 Info << "Finished checking topology" << endl;
270 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
272 } // End namespace Foam
274 // ************************************************************************* //