1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "meshTriangulation.H"
29 #include "faceTriangulation.H"
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 bool Foam::meshTriangulation::isInternalFace
35 const primitiveMesh& mesh,
36 const boolList& includedCell,
40 if (mesh.isInternalFace(faceI))
42 label own = mesh.faceOwner()[faceI];
43 label nei = mesh.faceNeighbour()[faceI];
45 if (includedCell[own] && includedCell[nei])
47 // Neighbouring cell will get included in subset
48 // as well so face is internal.
63 void Foam::meshTriangulation::getFaces
65 const primitiveMesh& mesh,
66 const boolList& includedCell,
72 // All faces to be triangulated.
73 faceIsCut.setSize(mesh.nFaces());
79 forAll(includedCell, cellI)
81 // Include faces of cut cells only.
82 if (includedCell[cellI])
84 const labelList& cFaces = mesh.cells()[cellI];
88 label faceI = cFaces[i];
90 if (!faceIsCut[faceI])
92 // First visit of face.
94 faceIsCut[faceI] = true;
96 // See if would become internal or external face
97 if (isInternalFace(mesh, includedCell, faceI))
106 Pout<< "Subset consists of " << nFaces << " faces out of " << mesh.nFaces()
107 << " of which " << nInternalFaces << " are internal" << endl;
111 void Foam::meshTriangulation::insertTriangles
113 const triFaceList& faceTris,
118 List<labelledTri>& triangles,
122 // Copy triangles. Optionally reverse them
125 const triFace& f = faceTris[i];
127 labelledTri& tri = triangles[triI];
142 tri.region() = regionI;
144 faceMap_[triI] = faceI;
151 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
154 Foam::meshTriangulation::meshTriangulation()
162 // Construct from faces of cells
163 Foam::meshTriangulation::meshTriangulation
165 const polyMesh& mesh,
166 const label internalFacesPatch,
167 const boolList& includedCell,
168 const bool faceCentreDecomposition
175 const faceList& faces = mesh.faces();
176 const pointField& points = mesh.points();
177 const polyBoundaryMesh& patches = mesh.boundaryMesh();
179 // All faces to be triangulated.
181 label nFaces, nInternalFaces;
193 // Find upper limit for number of triangles
194 // (can be less if triangulation fails)
197 if (faceCentreDecomposition)
199 forAll(faceIsCut, faceI)
201 if (faceIsCut[faceI])
203 nTotTri += faces[faceI].size();
209 forAll(faceIsCut, faceI)
211 if (faceIsCut[faceI])
213 nTotTri += faces[faceI].nTriangles(points);
217 Pout<< "nTotTri : " << nTotTri << endl;
220 // Storage for new and old points (only for faceCentre decomposition;
221 // for triangulation uses only existing points)
222 pointField newPoints;
224 if (faceCentreDecomposition)
226 newPoints.setSize(mesh.nPoints() + faces.size());
227 forAll(mesh.points(), pointI)
229 newPoints[pointI] = mesh.points()[pointI];
234 newPoints[mesh.nPoints() + faceI] = mesh.faceCentres()[faceI];
238 // Storage for all triangles
239 List<labelledTri> triangles(nTotTri);
240 faceMap_.setSize(nTotTri);
244 if (faceCentreDecomposition)
246 // Decomposition around face centre
247 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
249 // Triangulate internal faces
250 forAll(faceIsCut, faceI)
252 if (faceIsCut[faceI] && isInternalFace(mesh, includedCell, faceI))
254 // Face was internal to the mesh and will be 'internal' to
258 const face& f = faces[faceI];
262 faceMap_[triI] = faceI;
269 mesh.nPoints() + faceI, // face centre
275 nInternalFaces_ = triI;
278 // Triangulate external faces
279 forAll(faceIsCut, faceI)
281 if (faceIsCut[faceI] && !isInternalFace(mesh, includedCell, faceI))
283 // Face will become outside of the surface.
286 bool reverse = false;
288 if (mesh.isInternalFace(faceI))
290 patchI = internalFacesPatch;
292 // Check orientation. Check which side of the face gets
293 // included (note: only one side is).
294 if (includedCell[mesh.faceOwner()[faceI]])
305 // Face was already outside so orientation ok.
307 patchI = patches.whichPatch(faceI);
314 const face& f = faces[faceI];
320 faceMap_[triI] = faceI;
327 mesh.nPoints() + faceI, // face centre
336 faceMap_[triI] = faceI;
343 mesh.nPoints() + faceI, // face centre
353 // Triangulation using existing vertices
354 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
356 // Triangulate internal faces
357 forAll(faceIsCut, faceI)
359 if (faceIsCut[faceI] && isInternalFace(mesh, includedCell, faceI))
361 // Face was internal to the mesh and will be 'internal' to
364 // Triangulate face. Fall back to naive triangulation if failed.
365 faceTriangulation faceTris(points, faces[faceI], true);
367 if (faceTris.empty())
369 WarningIn("meshTriangulation::meshTriangulation")
370 << "Could not find triangulation for face " << faceI
371 << " vertices " << faces[faceI] << " coords "
372 << IndirectList<point>(points, faces[faceI])() << endl;
376 // Copy triangles. Make them internalFacesPatch
390 nInternalFaces_ = triI;
393 // Triangulate external faces
394 forAll(faceIsCut, faceI)
396 if (faceIsCut[faceI] && !isInternalFace(mesh, includedCell, faceI))
398 // Face will become outside of the surface.
401 bool reverse = false;
403 if (mesh.isInternalFace(faceI))
405 patchI = internalFacesPatch;
407 // Check orientation. Check which side of the face gets
408 // included (note: only one side is).
409 if (includedCell[mesh.faceOwner()[faceI]])
420 // Face was already outside so orientation ok.
422 patchI = patches.whichPatch(faceI);
428 faceTriangulation faceTris(points, faces[faceI], true);
430 if (faceTris.empty())
432 WarningIn("meshTriangulation::meshTriangulation")
433 << "Could not find triangulation for face " << faceI
434 << " vertices " << faces[faceI] << " coords "
435 << IndirectList<point>(points, faces[faceI])() << endl;
439 // Copy triangles. Optionally reverse them
445 reverse, // whether to reverse
455 // Shrink if nessecary (because of invalid triangulations)
456 triangles.setSize(triI);
457 faceMap_.setSize(triI);
459 Pout<< "nInternalFaces_:" << nInternalFaces_ << endl;
460 Pout<< "triangles:" << triangles.size() << endl;
463 geometricSurfacePatchList surfPatches(patches.size());
465 forAll(patches, patchI)
467 surfPatches[patchI] =
468 geometricSurfacePatch
470 patches[patchI].physicalType(),
471 patches[patchI].name(),
476 // Create globally numbered tri surface
477 if (faceCentreDecomposition)
479 // Use newPoints (mesh points + face centres)
480 triSurface globalSurf(triangles, surfPatches, newPoints);
482 // Create locally numbered tri surface
483 triSurface::operator=
487 globalSurf.localFaces(),
489 globalSurf.localPoints()
496 triSurface globalSurf(triangles, surfPatches, mesh.points());
498 // Create locally numbered tri surface
499 triSurface::operator=
503 globalSurf.localFaces(),
505 globalSurf.localPoints()
512 // ************************************************************************* //