PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/applications/utilities/mesh/manipulation/orientFaceZone/orientFaceZone.C

https://gitlab.com/johnvarv/OpenFOAM-3.0.x
C | 394 lines | 276 code | 70 blank | 48 comment | 34 complexity | 75d7f2dadc3a732f4d1f302f771dc035 MD5 | raw file
  1. /*---------------------------------------------------------------------------*\
  2. ========= |
  3. \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
  4. \\ / O peration |
  5. \\ / A nd | Copyright (C) 2013-2015 OpenFOAM Foundation
  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. Application
  21. orientFaceZone
  22. Description
  23. Corrects orientation of faceZone.
  24. - correct in parallel - excludes coupled faceZones from walk
  25. - correct for non-manifold faceZones - restarts walk
  26. \*---------------------------------------------------------------------------*/
  27. #include "argList.H"
  28. #include "Time.H"
  29. #include "syncTools.H"
  30. #include "patchFaceOrientation.H"
  31. #include "PatchEdgeFaceWave.H"
  32. #include "orientedSurface.H"
  33. #include "globalIndex.H"
  34. using namespace Foam;
  35. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  36. int main(int argc, char *argv[])
  37. {
  38. #include "addRegionOption.H"
  39. argList::validArgs.append("faceZone");
  40. argList::validArgs.append("outsidePoint");
  41. #include "setRootCase.H"
  42. #include "createTime.H"
  43. #include "createNamedPolyMesh.H"
  44. const word zoneName = args[1];
  45. const point outsidePoint = args.argRead<point>(2);
  46. Info<< "Orienting faceZone " << zoneName
  47. << " such that " << outsidePoint << " is outside"
  48. << nl << endl;
  49. const faceZone& fZone = mesh.faceZones()[zoneName];
  50. if (fZone.checkParallelSync())
  51. {
  52. FatalErrorIn(args.executable())
  53. << "Face zone " << fZone.name()
  54. << " is not parallel synchronised."
  55. << " Any coupled face also needs its coupled version to be included"
  56. << " and with opposite flipMap."
  57. << exit(FatalError);
  58. }
  59. const labelList& faceLabels = fZone;
  60. const indirectPrimitivePatch patch
  61. (
  62. IndirectList<face>(mesh.faces(), faceLabels),
  63. mesh.points()
  64. );
  65. const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
  66. // Data on all edges and faces
  67. List<patchFaceOrientation> allEdgeInfo(patch.nEdges());
  68. List<patchFaceOrientation> allFaceInfo(patch.size());
  69. // Make sure we don't walk through
  70. // - slaves of coupled faces
  71. // - non-manifold edges
  72. {
  73. const polyBoundaryMesh& bm = mesh.boundaryMesh();
  74. label nProtected = 0;
  75. forAll(faceLabels, faceI)
  76. {
  77. const label meshFaceI = faceLabels[faceI];
  78. const label patchI = bm.whichPatch(meshFaceI);
  79. if
  80. (
  81. patchI != -1
  82. && bm[patchI].coupled()
  83. && !isMasterFace[meshFaceI]
  84. )
  85. {
  86. // Slave side. Mark so doesn't get visited.
  87. allFaceInfo[faceI] = orientedSurface::NOFLIP;
  88. nProtected++;
  89. }
  90. }
  91. Info<< "Protected from visiting "
  92. << returnReduce(nProtected, sumOp<label>())
  93. << " slaves of coupled faces" << nl << endl;
  94. }
  95. {
  96. // Number of (master)faces per edge
  97. labelList nMasterFaces(patch.nEdges(), 0);
  98. forAll(faceLabels, faceI)
  99. {
  100. const label meshFaceI = faceLabels[faceI];
  101. if (isMasterFace[meshFaceI])
  102. {
  103. const labelList& fEdges = patch.faceEdges()[faceI];
  104. forAll(fEdges, fEdgeI)
  105. {
  106. nMasterFaces[fEdges[fEdgeI]]++;
  107. }
  108. }
  109. }
  110. syncTools::syncEdgeList
  111. (
  112. mesh,
  113. patch.meshEdges(mesh.edges(), mesh.pointEdges()),
  114. nMasterFaces,
  115. plusEqOp<label>(),
  116. label(0)
  117. );
  118. label nProtected = 0;
  119. forAll(nMasterFaces, edgeI)
  120. {
  121. if (nMasterFaces[edgeI] > 2)
  122. {
  123. allEdgeInfo[edgeI] = orientedSurface::NOFLIP;
  124. nProtected++;
  125. }
  126. }
  127. Info<< "Protected from visiting "
  128. << returnReduce(nProtected, sumOp<label>())
  129. << " non-manifold edges" << nl << endl;
  130. }
  131. DynamicList<label> changedEdges;
  132. DynamicList<patchFaceOrientation> changedInfo;
  133. const scalar tol = PatchEdgeFaceWave
  134. <
  135. indirectPrimitivePatch,
  136. patchFaceOrientation
  137. >::propagationTol();
  138. int dummyTrackData;
  139. globalIndex globalFaces(patch.size());
  140. while (true)
  141. {
  142. // Pick an unset face
  143. label unsetFaceI = labelMax;
  144. forAll(allFaceInfo, faceI)
  145. {
  146. if (allFaceInfo[faceI] == orientedSurface::UNVISITED)
  147. {
  148. unsetFaceI = globalFaces.toGlobal(faceI);
  149. break;
  150. }
  151. }
  152. reduce(unsetFaceI, minOp<label>());
  153. if (unsetFaceI == labelMax)
  154. {
  155. break;
  156. }
  157. label procI = globalFaces.whichProcID(unsetFaceI);
  158. label seedFaceI = globalFaces.toLocal(procI, unsetFaceI);
  159. Info<< "Seeding from processor " << procI << " face " << seedFaceI
  160. << endl;
  161. if (procI == Pstream::myProcNo())
  162. {
  163. // Determine orientation of seedFace
  164. vector d = outsidePoint-patch.faceCentres()[seedFaceI];
  165. const vector& fn = patch.faceNormals()[seedFaceI];
  166. // Set information to correct orientation
  167. patchFaceOrientation& faceInfo = allFaceInfo[seedFaceI];
  168. faceInfo = orientedSurface::NOFLIP;
  169. if ((fn&d) < 0)
  170. {
  171. faceInfo.flip();
  172. Pout<< "Face " << seedFaceI << " at "
  173. << patch.faceCentres()[seedFaceI]
  174. << " with normal " << fn
  175. << " needs to be flipped." << endl;
  176. }
  177. else
  178. {
  179. Pout<< "Face " << seedFaceI << " at "
  180. << patch.faceCentres()[seedFaceI]
  181. << " with normal " << fn
  182. << " points in positive direction (cos = " << (fn&d)/mag(d)
  183. << ")" << endl;
  184. }
  185. const labelList& fEdges = patch.faceEdges()[seedFaceI];
  186. forAll(fEdges, fEdgeI)
  187. {
  188. label edgeI = fEdges[fEdgeI];
  189. patchFaceOrientation& edgeInfo = allEdgeInfo[edgeI];
  190. if
  191. (
  192. edgeInfo.updateEdge<int>
  193. (
  194. mesh,
  195. patch,
  196. edgeI,
  197. seedFaceI,
  198. faceInfo,
  199. tol,
  200. dummyTrackData
  201. )
  202. )
  203. {
  204. changedEdges.append(edgeI);
  205. changedInfo.append(edgeInfo);
  206. }
  207. }
  208. }
  209. if (returnReduce(changedEdges.size(), sumOp<label>()) == 0)
  210. {
  211. break;
  212. }
  213. // Walk
  214. PatchEdgeFaceWave
  215. <
  216. indirectPrimitivePatch,
  217. patchFaceOrientation
  218. > calc
  219. (
  220. mesh,
  221. patch,
  222. changedEdges,
  223. changedInfo,
  224. allEdgeInfo,
  225. allFaceInfo,
  226. returnReduce(patch.nEdges(), sumOp<label>())
  227. );
  228. }
  229. // Push master zone info over to slave (since slave faces never visited)
  230. {
  231. const polyBoundaryMesh& bm = mesh.boundaryMesh();
  232. labelList neiStatus
  233. (
  234. mesh.nFaces()-mesh.nInternalFaces(),
  235. orientedSurface::UNVISITED
  236. );
  237. forAll(faceLabels, i)
  238. {
  239. const label meshFaceI = faceLabels[i];
  240. if (!mesh.isInternalFace(meshFaceI))
  241. {
  242. neiStatus[meshFaceI-mesh.nInternalFaces()] =
  243. allFaceInfo[i].flipStatus();
  244. }
  245. }
  246. syncTools::swapBoundaryFaceList(mesh, neiStatus);
  247. forAll(faceLabels, i)
  248. {
  249. const label meshFaceI = faceLabels[i];
  250. const label patchI = bm.whichPatch(meshFaceI);
  251. if
  252. (
  253. patchI != -1
  254. && bm[patchI].coupled()
  255. && !isMasterFace[meshFaceI]
  256. )
  257. {
  258. // Slave side. Take flipped from neighbour
  259. label bFaceI = meshFaceI-mesh.nInternalFaces();
  260. if (neiStatus[bFaceI] == orientedSurface::NOFLIP)
  261. {
  262. allFaceInfo[i] = orientedSurface::FLIP;
  263. }
  264. else if (neiStatus[bFaceI] == orientedSurface::FLIP)
  265. {
  266. allFaceInfo[i] = orientedSurface::NOFLIP;
  267. }
  268. else
  269. {
  270. FatalErrorIn(args.executable())
  271. << "Incorrect status for face " << meshFaceI
  272. << abort(FatalError);
  273. }
  274. }
  275. }
  276. }
  277. // Convert to flipmap and adapt faceZones
  278. boolList newFlipMap(allFaceInfo.size(), false);
  279. label nChanged = 0;
  280. forAll(allFaceInfo, faceI)
  281. {
  282. if (allFaceInfo[faceI] == orientedSurface::NOFLIP)
  283. {
  284. newFlipMap[faceI] = false;
  285. }
  286. else if (allFaceInfo[faceI] == orientedSurface::FLIP)
  287. {
  288. newFlipMap[faceI] = true;
  289. }
  290. else
  291. {
  292. FatalErrorIn(args.executable())
  293. << "Problem : unvisited face " << faceI
  294. << " centre:" << mesh.faceCentres()[faceLabels[faceI]]
  295. << abort(FatalError);
  296. }
  297. if (fZone.flipMap()[faceI] != newFlipMap[faceI])
  298. {
  299. nChanged++;
  300. }
  301. }
  302. reduce(nChanged, sumOp<label>());
  303. if (nChanged > 0)
  304. {
  305. Info<< "Flipping " << nChanged << " out of "
  306. << globalFaces.size() << " faces." << nl << endl;
  307. mesh.faceZones()[zoneName].resetAddressing(faceLabels, newFlipMap);
  308. if (!mesh.faceZones().write())
  309. {
  310. FatalErrorIn(args.executable())
  311. << "Failed writing faceZones" << exit(FatalError);
  312. }
  313. }
  314. Info<< "\nEnd\n" << endl;
  315. return 0;
  316. }
  317. // ************************************************************************* //