/src/triSurface/meshTriangulation/meshTriangulation.C

https://github.com/xyuan/OpenFOAM-1.7.x · C · 511 lines · 360 code · 76 blank · 75 comment · 28 complexity · 6b36f999482418498b8c845d9b51c846 MD5 · raw file

  1. /*---------------------------------------------------------------------------*\
  2. ========= |
  3. \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
  4. \\ / O peration |
  5. \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
  6. \\/ M anipulation |
  7. -------------------------------------------------------------------------------
  8. License
  9. This file is part of OpenFOAM.
  10. OpenFOAM is free software: you can redistribute it and/or modify it
  11. under the terms of the GNU General Public License as published by
  12. the Free Software Foundation, either version 3 of the License, or
  13. (at your option) any later version.
  14. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
  15. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  17. for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
  20. \*---------------------------------------------------------------------------*/
  21. #include "meshTriangulation.H"
  22. #include "polyMesh.H"
  23. #include "faceTriangulation.H"
  24. // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
  25. bool Foam::meshTriangulation::isInternalFace
  26. (
  27. const primitiveMesh& mesh,
  28. const boolList& includedCell,
  29. const label faceI
  30. )
  31. {
  32. if (mesh.isInternalFace(faceI))
  33. {
  34. label own = mesh.faceOwner()[faceI];
  35. label nei = mesh.faceNeighbour()[faceI];
  36. if (includedCell[own] && includedCell[nei])
  37. {
  38. // Neighbouring cell will get included in subset
  39. // as well so face is internal.
  40. return true;
  41. }
  42. else
  43. {
  44. return false;
  45. }
  46. }
  47. else
  48. {
  49. return false;
  50. }
  51. }
  52. void Foam::meshTriangulation::getFaces
  53. (
  54. const primitiveMesh& mesh,
  55. const boolList& includedCell,
  56. boolList& faceIsCut,
  57. label& nFaces,
  58. label& nInternalFaces
  59. )
  60. {
  61. // All faces to be triangulated.
  62. faceIsCut.setSize(mesh.nFaces());
  63. faceIsCut = false;
  64. nFaces = 0;
  65. nInternalFaces = 0;
  66. forAll(includedCell, cellI)
  67. {
  68. // Include faces of cut cells only.
  69. if (includedCell[cellI])
  70. {
  71. const labelList& cFaces = mesh.cells()[cellI];
  72. forAll(cFaces, i)
  73. {
  74. label faceI = cFaces[i];
  75. if (!faceIsCut[faceI])
  76. {
  77. // First visit of face.
  78. nFaces++;
  79. faceIsCut[faceI] = true;
  80. // See if would become internal or external face
  81. if (isInternalFace(mesh, includedCell, faceI))
  82. {
  83. nInternalFaces++;
  84. }
  85. }
  86. }
  87. }
  88. }
  89. Pout<< "Subset consists of " << nFaces << " faces out of " << mesh.nFaces()
  90. << " of which " << nInternalFaces << " are internal" << endl;
  91. }
  92. void Foam::meshTriangulation::insertTriangles
  93. (
  94. const triFaceList& faceTris,
  95. const label faceI,
  96. const label regionI,
  97. const bool reverse,
  98. List<labelledTri>& triangles,
  99. label& triI
  100. )
  101. {
  102. // Copy triangles. Optionally reverse them
  103. forAll(faceTris, i)
  104. {
  105. const triFace& f = faceTris[i];
  106. labelledTri& tri = triangles[triI];
  107. if (reverse)
  108. {
  109. tri[0] = f[0];
  110. tri[2] = f[1];
  111. tri[1] = f[2];
  112. }
  113. else
  114. {
  115. tri[0] = f[0];
  116. tri[1] = f[1];
  117. tri[2] = f[2];
  118. }
  119. tri.region() = regionI;
  120. faceMap_[triI] = faceI;
  121. triI++;
  122. }
  123. }
  124. // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
  125. // Null constructor
  126. Foam::meshTriangulation::meshTriangulation()
  127. :
  128. triSurface(),
  129. nInternalFaces_(0),
  130. faceMap_()
  131. {}
  132. // Construct from faces of cells
  133. Foam::meshTriangulation::meshTriangulation
  134. (
  135. const polyMesh& mesh,
  136. const label internalFacesPatch,
  137. const boolList& includedCell,
  138. const bool faceCentreDecomposition
  139. )
  140. :
  141. triSurface(),
  142. nInternalFaces_(0),
  143. faceMap_()
  144. {
  145. const faceList& faces = mesh.faces();
  146. const pointField& points = mesh.points();
  147. const polyBoundaryMesh& patches = mesh.boundaryMesh();
  148. // All faces to be triangulated.
  149. boolList faceIsCut;
  150. label nFaces, nInternalFaces;
  151. getFaces
  152. (
  153. mesh,
  154. includedCell,
  155. faceIsCut,
  156. nFaces,
  157. nInternalFaces
  158. );
  159. // Find upper limit for number of triangles
  160. // (can be less if triangulation fails)
  161. label nTotTri = 0;
  162. if (faceCentreDecomposition)
  163. {
  164. forAll(faceIsCut, faceI)
  165. {
  166. if (faceIsCut[faceI])
  167. {
  168. nTotTri += faces[faceI].size();
  169. }
  170. }
  171. }
  172. else
  173. {
  174. forAll(faceIsCut, faceI)
  175. {
  176. if (faceIsCut[faceI])
  177. {
  178. nTotTri += faces[faceI].nTriangles(points);
  179. }
  180. }
  181. }
  182. Pout<< "nTotTri : " << nTotTri << endl;
  183. // Storage for new and old points (only for faceCentre decomposition;
  184. // for triangulation uses only existing points)
  185. pointField newPoints;
  186. if (faceCentreDecomposition)
  187. {
  188. newPoints.setSize(mesh.nPoints() + faces.size());
  189. forAll(mesh.points(), pointI)
  190. {
  191. newPoints[pointI] = mesh.points()[pointI];
  192. }
  193. // Face centres
  194. forAll(faces, faceI)
  195. {
  196. newPoints[mesh.nPoints() + faceI] = mesh.faceCentres()[faceI];
  197. }
  198. }
  199. // Storage for all triangles
  200. List<labelledTri> triangles(nTotTri);
  201. faceMap_.setSize(nTotTri);
  202. label triI = 0;
  203. if (faceCentreDecomposition)
  204. {
  205. // Decomposition around face centre
  206. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  207. // Triangulate internal faces
  208. forAll(faceIsCut, faceI)
  209. {
  210. if (faceIsCut[faceI] && isInternalFace(mesh, includedCell, faceI))
  211. {
  212. // Face was internal to the mesh and will be 'internal' to
  213. // the surface.
  214. // Triangulate face
  215. const face& f = faces[faceI];
  216. forAll(f, fp)
  217. {
  218. faceMap_[triI] = faceI;
  219. triangles[triI++] =
  220. labelledTri
  221. (
  222. f[fp],
  223. f.nextLabel(fp),
  224. mesh.nPoints() + faceI, // face centre
  225. internalFacesPatch
  226. );
  227. }
  228. }
  229. }
  230. nInternalFaces_ = triI;
  231. // Triangulate external faces
  232. forAll(faceIsCut, faceI)
  233. {
  234. if (faceIsCut[faceI] && !isInternalFace(mesh, includedCell, faceI))
  235. {
  236. // Face will become outside of the surface.
  237. label patchI = -1;
  238. bool reverse = false;
  239. if (mesh.isInternalFace(faceI))
  240. {
  241. patchI = internalFacesPatch;
  242. // Check orientation. Check which side of the face gets
  243. // included (note: only one side is).
  244. if (includedCell[mesh.faceOwner()[faceI]])
  245. {
  246. reverse = false;
  247. }
  248. else
  249. {
  250. reverse = true;
  251. }
  252. }
  253. else
  254. {
  255. // Face was already outside so orientation ok.
  256. patchI = patches.whichPatch(faceI);
  257. reverse = false;
  258. }
  259. // Triangulate face
  260. const face& f = faces[faceI];
  261. if (reverse)
  262. {
  263. forAll(f, fp)
  264. {
  265. faceMap_[triI] = faceI;
  266. triangles[triI++] =
  267. labelledTri
  268. (
  269. f.nextLabel(fp),
  270. f[fp],
  271. mesh.nPoints() + faceI, // face centre
  272. patchI
  273. );
  274. }
  275. }
  276. else
  277. {
  278. forAll(f, fp)
  279. {
  280. faceMap_[triI] = faceI;
  281. triangles[triI++] =
  282. labelledTri
  283. (
  284. f[fp],
  285. f.nextLabel(fp),
  286. mesh.nPoints() + faceI, // face centre
  287. patchI
  288. );
  289. }
  290. }
  291. }
  292. }
  293. }
  294. else
  295. {
  296. // Triangulation using existing vertices
  297. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  298. // Triangulate internal faces
  299. forAll(faceIsCut, faceI)
  300. {
  301. if (faceIsCut[faceI] && isInternalFace(mesh, includedCell, faceI))
  302. {
  303. // Face was internal to the mesh and will be 'internal' to
  304. // the surface.
  305. // Triangulate face. Fall back to naive triangulation if failed.
  306. faceTriangulation faceTris(points, faces[faceI], true);
  307. if (faceTris.empty())
  308. {
  309. WarningIn("meshTriangulation::meshTriangulation")
  310. << "Could not find triangulation for face " << faceI
  311. << " vertices " << faces[faceI] << " coords "
  312. << IndirectList<point>(points, faces[faceI])() << endl;
  313. }
  314. else
  315. {
  316. // Copy triangles. Make them internalFacesPatch
  317. insertTriangles
  318. (
  319. faceTris,
  320. faceI,
  321. internalFacesPatch,
  322. false, // no reverse
  323. triangles,
  324. triI
  325. );
  326. }
  327. }
  328. }
  329. nInternalFaces_ = triI;
  330. // Triangulate external faces
  331. forAll(faceIsCut, faceI)
  332. {
  333. if (faceIsCut[faceI] && !isInternalFace(mesh, includedCell, faceI))
  334. {
  335. // Face will become outside of the surface.
  336. label patchI = -1;
  337. bool reverse = false;
  338. if (mesh.isInternalFace(faceI))
  339. {
  340. patchI = internalFacesPatch;
  341. // Check orientation. Check which side of the face gets
  342. // included (note: only one side is).
  343. if (includedCell[mesh.faceOwner()[faceI]])
  344. {
  345. reverse = false;
  346. }
  347. else
  348. {
  349. reverse = true;
  350. }
  351. }
  352. else
  353. {
  354. // Face was already outside so orientation ok.
  355. patchI = patches.whichPatch(faceI);
  356. reverse = false;
  357. }
  358. // Triangulate face
  359. faceTriangulation faceTris(points, faces[faceI], true);
  360. if (faceTris.empty())
  361. {
  362. WarningIn("meshTriangulation::meshTriangulation")
  363. << "Could not find triangulation for face " << faceI
  364. << " vertices " << faces[faceI] << " coords "
  365. << IndirectList<point>(points, faces[faceI])() << endl;
  366. }
  367. else
  368. {
  369. // Copy triangles. Optionally reverse them
  370. insertTriangles
  371. (
  372. faceTris,
  373. faceI,
  374. patchI,
  375. reverse, // whether to reverse
  376. triangles,
  377. triI
  378. );
  379. }
  380. }
  381. }
  382. }
  383. // Shrink if nessecary (because of invalid triangulations)
  384. triangles.setSize(triI);
  385. faceMap_.setSize(triI);
  386. Pout<< "nInternalFaces_:" << nInternalFaces_ << endl;
  387. Pout<< "triangles:" << triangles.size() << endl;
  388. geometricSurfacePatchList surfPatches(patches.size());
  389. forAll(patches, patchI)
  390. {
  391. surfPatches[patchI] =
  392. geometricSurfacePatch
  393. (
  394. patches[patchI].physicalType(),
  395. patches[patchI].name(),
  396. patchI
  397. );
  398. }
  399. // Create globally numbered tri surface
  400. if (faceCentreDecomposition)
  401. {
  402. // Use newPoints (mesh points + face centres)
  403. triSurface globalSurf(triangles, surfPatches, newPoints);
  404. // Create locally numbered tri surface
  405. triSurface::operator=
  406. (
  407. triSurface
  408. (
  409. globalSurf.localFaces(),
  410. surfPatches,
  411. globalSurf.localPoints()
  412. )
  413. );
  414. }
  415. else
  416. {
  417. // Use mesh points
  418. triSurface globalSurf(triangles, surfPatches, mesh.points());
  419. // Create locally numbered tri surface
  420. triSurface::operator=
  421. (
  422. triSurface
  423. (
  424. globalSurf.localFaces(),
  425. surfPatches,
  426. globalSurf.localPoints()
  427. )
  428. );
  429. }
  430. }
  431. // ************************************************************************* //