1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "meshTriangulation.H"
28 #include "faceTriangulation.H"
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 bool Foam::meshTriangulation::isInternalFace
34 const primitiveMesh& mesh,
35 const boolList& includedCell,
39 if (mesh.isInternalFace(faceI))
41 label own = mesh.faceOwner()[faceI];
42 label nei = mesh.faceNeighbour()[faceI];
44 if (includedCell[own] && includedCell[nei])
46 // Neighbouring cell will get included in subset
47 // as well so face is internal.
62 void Foam::meshTriangulation::getFaces
64 const primitiveMesh& mesh,
65 const boolList& includedCell,
71 // All faces to be triangulated.
72 faceIsCut.setSize(mesh.nFaces());
78 forAll(includedCell, cellI)
80 // Include faces of cut cells only.
81 if (includedCell[cellI])
83 const labelList& cFaces = mesh.cells()[cellI];
87 label faceI = cFaces[i];
89 if (!faceIsCut[faceI])
91 // First visit of face.
93 faceIsCut[faceI] = true;
95 // See if would become internal or external face
96 if (isInternalFace(mesh, includedCell, faceI))
105 Pout<< "Subset consists of " << nFaces << " faces out of " << mesh.nFaces()
106 << " of which " << nInternalFaces << " are internal" << endl;
110 void Foam::meshTriangulation::insertTriangles
112 const triFaceList& faceTris,
117 List<labelledTri>& triangles,
121 // Copy triangles. Optionally reverse them
124 const triFace& f = faceTris[i];
126 labelledTri& tri = triangles[triI];
141 tri.region() = regionI;
143 faceMap_[triI] = faceI;
150 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
153 Foam::meshTriangulation::meshTriangulation()
161 // Construct from faces of cells
162 Foam::meshTriangulation::meshTriangulation
164 const polyMesh& mesh,
165 const label internalFacesPatch,
166 const boolList& includedCell,
167 const bool faceCentreDecomposition
174 const faceList& faces = mesh.faces();
175 const pointField& points = mesh.points();
176 const polyBoundaryMesh& patches = mesh.boundaryMesh();
178 // All faces to be triangulated.
180 label nFaces, nInternalFaces;
192 // Find upper limit for number of triangles
193 // (can be less if triangulation fails)
196 if (faceCentreDecomposition)
198 forAll(faceIsCut, faceI)
200 if (faceIsCut[faceI])
202 nTotTri += faces[faceI].size();
208 forAll(faceIsCut, faceI)
210 if (faceIsCut[faceI])
212 nTotTri += faces[faceI].nTriangles(points);
216 Pout<< "nTotTri : " << nTotTri << endl;
219 // Storage for new and old points (only for faceCentre decomposition;
220 // for triangulation uses only existing points)
221 pointField newPoints;
223 if (faceCentreDecomposition)
225 newPoints.setSize(mesh.nPoints() + faces.size());
226 forAll(mesh.points(), pointI)
228 newPoints[pointI] = mesh.points()[pointI];
233 newPoints[mesh.nPoints() + faceI] = mesh.faceCentres()[faceI];
237 // Storage for all triangles
238 List<labelledTri> triangles(nTotTri);
239 faceMap_.setSize(nTotTri);
243 if (faceCentreDecomposition)
245 // Decomposition around face centre
246 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
248 // Triangulate internal faces
249 forAll(faceIsCut, faceI)
251 if (faceIsCut[faceI] && isInternalFace(mesh, includedCell, faceI))
253 // Face was internal to the mesh and will be 'internal' to
257 const face& f = faces[faceI];
261 faceMap_[triI] = faceI;
268 mesh.nPoints() + faceI, // face centre
274 nInternalFaces_ = triI;
277 // Triangulate external faces
278 forAll(faceIsCut, faceI)
280 if (faceIsCut[faceI] && !isInternalFace(mesh, includedCell, faceI))
282 // Face will become outside of the surface.
285 bool reverse = false;
287 if (mesh.isInternalFace(faceI))
289 patchI = internalFacesPatch;
291 // Check orientation. Check which side of the face gets
292 // included (note: only one side is).
293 if (includedCell[mesh.faceOwner()[faceI]])
304 // Face was already outside so orientation ok.
306 patchI = patches.whichPatch(faceI);
313 const face& f = faces[faceI];
319 faceMap_[triI] = faceI;
326 mesh.nPoints() + faceI, // face centre
335 faceMap_[triI] = faceI;
342 mesh.nPoints() + faceI, // face centre
352 // Triangulation using existing vertices
353 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
355 // Triangulate internal faces
356 forAll(faceIsCut, faceI)
358 if (faceIsCut[faceI] && isInternalFace(mesh, includedCell, faceI))
360 // Face was internal to the mesh and will be 'internal' to
363 // Triangulate face. Fall back to naive triangulation if failed.
364 faceTriangulation faceTris(points, faces[faceI], true);
366 if (faceTris.empty())
368 WarningIn("meshTriangulation::meshTriangulation")
369 << "Could not find triangulation for face " << faceI
370 << " vertices " << faces[faceI] << " coords "
371 << IndirectList<point>(points, faces[faceI])() << endl;
375 // Copy triangles. Make them internalFacesPatch
389 nInternalFaces_ = triI;
392 // Triangulate external faces
393 forAll(faceIsCut, faceI)
395 if (faceIsCut[faceI] && !isInternalFace(mesh, includedCell, faceI))
397 // Face will become outside of the surface.
400 bool reverse = false;
402 if (mesh.isInternalFace(faceI))
404 patchI = internalFacesPatch;
406 // Check orientation. Check which side of the face gets
407 // included (note: only one side is).
408 if (includedCell[mesh.faceOwner()[faceI]])
419 // Face was already outside so orientation ok.
421 patchI = patches.whichPatch(faceI);
427 faceTriangulation faceTris(points, faces[faceI], true);
429 if (faceTris.empty())
431 WarningIn("meshTriangulation::meshTriangulation")
432 << "Could not find triangulation for face " << faceI
433 << " vertices " << faces[faceI] << " coords "
434 << IndirectList<point>(points, faces[faceI])() << endl;
438 // Copy triangles. Optionally reverse them
444 reverse, // whether to reverse
454 // Shrink if nessecary (because of invalid triangulations)
455 triangles.setSize(triI);
456 faceMap_.setSize(triI);
458 Pout<< "nInternalFaces_:" << nInternalFaces_ << endl;
459 Pout<< "triangles:" << triangles.size() << endl;
462 geometricSurfacePatchList surfPatches(patches.size());
464 forAll(patches, patchI)
466 surfPatches[patchI] =
467 geometricSurfacePatch
469 patches[patchI].physicalType(),
470 patches[patchI].name(),
475 // Create globally numbered tri surface
476 if (faceCentreDecomposition)
478 // Use newPoints (mesh points + face centres)
479 triSurface globalSurf(triangles, surfPatches, newPoints);
481 // Create locally numbered tri surface
482 triSurface::operator=
486 globalSurf.localFaces(),
488 globalSurf.localPoints()
495 triSurface globalSurf(triangles, surfPatches, mesh.points());
497 // Create locally numbered tri surface
498 triSurface::operator=
502 globalSurf.localFaces(),
504 globalSurf.localPoints()
511 // ************************************************************************* //