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 \*---------------------------------------------------------------------------*/
29 #include "decomposeFaces.H"
39 #include "polyMeshGenAddressing.H"
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 decomposeFaces::decomposeFaces(polyMeshGen& mesh)
57 decomposeFaces::~decomposeFaces()
60 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
62 void decomposeFaces::decomposeMeshFaces(const boolList& decomposeFace)
66 newFacesForFace_.setSize(mesh_.faces().size());
67 forAll(newFacesForFace_, fI)
68 newFacesForFace_.setRowSize(fI, 0);
70 const label nIntFaces = mesh_.nInternalFaces();
71 label nFaces(0), nPoints = mesh_.points().size();
74 pointFieldPMG& points = mesh_.points();
75 forAll(decomposeFace, fI)
76 if( decomposeFace[fI] )
79 points.setSize(nPoints + nFaces);
81 polyMeshGenModifier meshModifier(mesh_);
82 faceListPMG& faces = meshModifier.facesAccess();
84 if( decomposeFace.size() != faces.size() )
87 "void decomposeFaces::decomposeMeshFaces(const boolList&)"
88 ) << "Incorrect size of the decomposeFace list!" << abort(FatalError);
93 //- decompose internal faces
94 for(label faceI=0;faceI<nIntFaces;++faceI)
96 const face& f = faces[faceI];
98 if( decomposeFace[faceI] )
101 Info << "Decomposing internal face " << faceI << " with nodes "
105 FixedList<label, 3> newF;
110 newF[1] = f.nextLabel(pI);
114 Info << "Storing face " << newF << " with label "
118 newFaces.appendList(newF);
119 newFacesForFace_.append(faceI, nFaces++);
122 p = f.centre(points);
129 Info << "Storing internal face " << faceI << " with nodes "
130 << f << " as new face " << faceI << endl;
133 newFaces.appendList(f);
134 newFacesForFace_.append(faceI, nFaces++);
138 //- decompose boundary faces
139 PtrList<boundaryPatch>& boundaries = meshModifier.boundariesAccess();
140 forAll(boundaries, patchI)
142 const label start = boundaries[patchI].patchStart();
143 const label end = start + boundaries[patchI].patchSize();
145 boundaries[patchI].patchStart() = nFaces;
147 for(label bfI=start;bfI<end;++bfI)
149 const face& f = faces[bfI];
150 if( decomposeFace[bfI] )
153 Info << "Decomposing boundary face " << bfI
154 << " with nodes " << f << endl;
157 FixedList<label, 3> newF;
162 newF[1] = f.nextLabel(pI);
166 Info << "Storing face " << newF << " with label "
170 newFaces.appendList(newF);
171 newFacesForFace_.append(bfI, nFaces++);
174 p = f.centre(points);
175 points[nPoints++] = p;
180 Info << "Storing boundary face " << bfI << " in patch"
181 << patchI << " as new face " << bfI << endl;
184 newFaces.appendList(f);
185 newFacesForFace_.append(bfI, nFaces++);
189 boundaries[patchI].patchSize() =
190 nFaces - boundaries[patchI].patchStart();
193 //- decompose processor faces
194 if( Pstream::parRun() )
196 PtrList<processorBoundaryPatch>& procBoundaries =
197 meshModifier.procBoundariesAccess();
199 forAll(procBoundaries, patchI)
201 const label start = procBoundaries[patchI].patchStart();
202 const label end = start + procBoundaries[patchI].patchSize();
204 const bool own = procBoundaries[patchI].owner();
206 procBoundaries[patchI].patchStart() = nFaces;
208 for(label bfI=start;bfI<end;++bfI)
217 f = faces[bfI].reverseFace();
220 if( decomposeFace[bfI] )
223 Info << "Decomposing processor boundary face " << bfI
224 << " with nodes " << f << endl;
232 newF[1] = f.nextLabel(pI);
236 Info << "Storing face " << newF << " with label "
242 newFaces.appendList(newF);
246 newFaces.appendList(newF.reverseFace());
248 newFacesForFace_.append(bfI, nFaces++);
251 p = f.centre(points);
252 points[nPoints++] = p;
257 Info << "Storing boundary face " << bfI << " in patch"
258 << patchI << " as new face " << bfI << endl;
263 newFaces.appendList(f);
267 newFaces.appendList(f.reverseFace());
269 newFacesForFace_.append(bfI, nFaces++);
273 procBoundaries[patchI].patchSize() =
274 nFaces - procBoundaries[patchI].patchStart();
278 //- store the faces back into their list
279 faces.setSize(nFaces);
282 face& f = faces[faceI];
283 f.setSize(newFaces.sizeOfRow(faceI));
286 f[pI] = newFaces(faceI, pI);
291 mesh_.updateFaceSubsets(newFacesForFace_);
294 cellListPMG& cells = meshModifier.cellsAccess();
297 # pragma omp parallel for schedule(dynamic, 40)
301 cell& c = cells[cellI];
307 const label faceI = c[fJ];
308 forAllRow(newFacesForFace_, faceI, nfI)
309 newC.append(newFacesForFace_(faceI, nfI));
313 Info << "Cell " << cellI << " with faces " << c
314 << " is changed into " << newC << endl;
317 c.setSize(newC.size());
322 meshModifier.clearAll();
327 Info << "New cells are " << cells << endl;
332 void decomposeFaces::decomposeConcaveInternalFaces
334 const boolList& concaveVertex
337 if( Pstream::parRun() )
341 "void decomposeFaces::decomposeConcaveInternalFaces"
342 "(const boolList& concaveVertex)"
343 ) << "This procedure is not parallelised!" << exit(FatalError);
348 newFacesForFace_.setSize(mesh_.faces().size());
349 forAll(newFacesForFace_, fI)
350 newFacesForFace_.setRowSize(fI, 0);
352 const label nIntFaces = mesh_.nInternalFaces();
354 polyMeshGenModifier meshModifier(mesh_);
355 pointFieldPMG& points = meshModifier.pointsAccess();
356 faceListPMG& faces = meshModifier.facesAccess();
358 if( concaveVertex.size() != mesh_.points().size() )
361 "void decomposeFaces::decomposeMeshFaces(const boolList&)"
362 ) << "Incorrect size of the concaveVertex list!" << abort(FatalError);
369 const label id = mesh_.addFaceSubset("decomposedFaces");
372 //- decompose internal faces
373 for(register label faceI=0;faceI<nIntFaces;++faceI)
375 const face& f = faces[faceI];
377 DynList<label> concavePos;
379 if( concaveVertex[f[pI]] )
381 concavePos.append(pI);
384 if( concavePos.size() == 1 )
387 Info << "1. Decomposing internal face " << faceI << " with nodes "
389 mesh_.addFaceToSubset(id, faceI);
392 newF[0] = f[concavePos[0]];
394 for(label pI=1;pI<(f.size()-1);++pI)
396 const label pJ = (concavePos[0] + pI) % f.size();
398 newF[2] = f.nextLabel(pJ);
401 Info << "Storing face " << newF << " with label "
402 << newFaces.size() << endl;
405 newFacesForFace_.append(faceI, newFaces.size());
406 newFaces.appendList(newF);
409 else if( concavePos.size() > 1 )
412 Info << "2. Decomposing internal face " << faceI << " with nodes "
414 mesh_.addFaceToSubset(id, faceI);
417 newF[0] = points.size();
421 newF[2] = f.nextLabel(pI);
424 Info << "2. Storing face " << newF << " with label "
425 << newFaces.size() << endl;
428 newFacesForFace_.append(faceI, newFaces.size());
429 newFaces.appendList(newF);
432 const point fCent = f.centre(points);
433 points.append(fCent);
438 Info << "Storing internal face " << faceI << " with nodes "
439 << f << " as new face " << newFaces.size() << endl;
442 newFacesForFace_.append(faceI, newFaces.size());
443 newFaces.appendList(f);
447 PtrList<boundaryPatch>& boundaries = meshModifier.boundariesAccess();
448 forAll(boundaries, patchI)
450 const label start = boundaries[patchI].patchStart();
451 const label end = start + boundaries[patchI].patchSize();
453 //- set new patch start
454 boundaries[patchI].patchStart() = newFaces.size();
456 //- store faces into newFaces
457 for(label bfI=start;bfI<end;++bfI)
459 newFacesForFace_.append(bfI, newFaces.size());
460 newFaces.appendList(faces[bfI]);
464 //- copy new faces into the faceListPMG
465 faces.setSize(newFaces.size());
466 forAll(newFaces, faceI)
468 faces[faceI].setSize(newFaces.sizeOfRow(faceI));
470 forAllRow(newFaces, faceI, pI)
471 faces[faceI][pI] = newFaces(faceI, pI);
477 cellListPMG& cells = meshModifier.cellsAccess();
480 # pragma omp parallel for schedule(dynamic, 40)
484 cell& c = cells[cellI];
486 DynList<label, 24> newC;
490 const label faceI = c[fJ];
491 forAllRow(newFacesForFace_, faceI, nfI)
492 newC.append(newFacesForFace_(faceI, nfI));
496 Info << "Cell " << cellI << " with faces " << c
497 << " is changed into " << newC << endl;
500 c.setSize(newC.size());
505 meshModifier.clearAll();
508 mesh_.updateFaceSubsets(newFacesForFace_);
511 Info << "New cells are " << cells << endl;
516 meshModifier.removeUnusedVertices();
521 const VRWGraph& decomposeFaces::newFacesForFace() const
526 "const VRWGraph& decomposeFaces::newFacesForFace() const"
527 ) << "Decomposition is not yet performed!" << endl;
529 return newFacesForFace_;
532 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
534 } // End namespace Foam
536 // ************************************************************************* //