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

/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/cellSizeAndAlignmentControl/searchableSurfaceControl/searchableSurfaceControl.C

https://gitlab.com/johnvarv/OpenFOAM-3.0.x
C | 586 lines | 337 code | 93 blank | 156 comment | 23 complexity | 97a69d1fd8e0064cee316301998988c2 MD5 | raw file
  1. /*---------------------------------------------------------------------------*\
  2. ========= |
  3. \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
  4. \\ / O peration |
  5. \\ / A nd | Copyright (C) 2012-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. \*---------------------------------------------------------------------------*/
  21. #include "searchableSurfaceControl.H"
  22. #include "addToRunTimeSelectionTable.H"
  23. #include "cellSizeFunction.H"
  24. #include "triSurfaceMesh.H"
  25. #include "searchableBox.H"
  26. #include "tetrahedron.H"
  27. #include "vectorTools.H"
  28. #include "quaternion.H"
  29. // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
  30. namespace Foam
  31. {
  32. defineTypeNameAndDebug(searchableSurfaceControl, 0);
  33. addToRunTimeSelectionTable
  34. (
  35. cellSizeAndAlignmentControl,
  36. searchableSurfaceControl,
  37. dictionary
  38. );
  39. }
  40. // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
  41. //Foam::tensor Foam::surfaceControl::requiredAlignment
  42. //(
  43. // const Foam::point& pt,
  44. // const vectorField& ptNormals
  45. //) const
  46. //{
  47. //// pointIndexHit surfHit;
  48. //// label hitSurface;
  49. ////
  50. //// geometryToConformTo_.findSurfaceNearest
  51. //// (
  52. //// pt,
  53. //// sqr(GREAT),
  54. //// surfHit,
  55. //// hitSurface
  56. //// );
  57. ////
  58. //// if (!surfHit.hit())
  59. //// {
  60. //// FatalErrorIn
  61. //// (
  62. //// "Foam::tensor Foam::conformalVoronoiMesh::requiredAlignment"
  63. //// )
  64. //// << "findSurfaceNearest did not find a hit across the surfaces."
  65. //// << exit(FatalError) << endl;
  66. //// }
  67. ////
  68. ////// Primary alignment
  69. ////
  70. //// vectorField norm(1);
  71. ////
  72. //// allGeometry_[hitSurface].getNormal
  73. //// (
  74. //// List<pointIndexHit>(1, surfHit),
  75. //// norm
  76. //// );
  77. ////
  78. //// const vector np = norm[0];
  79. ////
  80. //// const tensor Rp = rotationTensor(vector(0,0,1), np);
  81. ////
  82. //// return (Rp);
  83. //
  84. //// Info<< "Point : " << pt << endl;
  85. //// forAll(ptNormals, pnI)
  86. //// {
  87. //// Info<< " normal " << pnI << " : " << ptNormals[pnI] << endl;
  88. //// }
  89. //
  90. // vector np = ptNormals[0];
  91. //
  92. // const tensor Rp = rotationTensor(vector(0,0,1), np);
  93. //
  94. // vector na = vector::zero;
  95. //
  96. // scalar smallestAngle = GREAT;
  97. //
  98. // for (label pnI = 1; pnI < ptNormals.size(); ++pnI)
  99. // {
  100. // const vector& nextNormal = ptNormals[pnI];
  101. //
  102. // const scalar cosPhi = vectorTools::cosPhi(np, nextNormal);
  103. //
  104. // if (mag(cosPhi) < smallestAngle)
  105. // {
  106. // na = nextNormal;
  107. // smallestAngle = cosPhi;
  108. // }
  109. // }
  110. //
  111. // // Secondary alignment
  112. // vector ns = np ^ na;
  113. //
  114. // if (mag(ns) < SMALL)
  115. // {
  116. // WarningIn("conformalVoronoiMesh::requiredAlignment")
  117. // << "Parallel normals detected in spoke search." << nl
  118. // << "point: " << pt << nl
  119. // << "np : " << np << nl
  120. // << "na : " << na << nl
  121. // << "ns : " << ns << nl
  122. // << endl;
  123. //
  124. // ns = np;
  125. // }
  126. //
  127. // ns /= mag(ns);
  128. //
  129. // tensor Rs = rotationTensor((Rp & vector(0,1,0)), ns);
  130. //
  131. //// Info<< "Point " << pt << nl
  132. //// << " np : " << np << nl
  133. //// << " ns : " << ns << nl
  134. //// << " Rp : " << Rp << nl
  135. //// << " Rs : " << Rs << nl
  136. //// << " Rs&Rp: " << (Rs & Rp) << endl;
  137. //
  138. // return (Rs & Rp);
  139. //}
  140. // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
  141. Foam::searchableSurfaceControl::searchableSurfaceControl
  142. (
  143. const Time& runTime,
  144. const word& name,
  145. const dictionary& controlFunctionDict,
  146. const conformationSurfaces& geometryToConformTo,
  147. const scalar& defaultCellSize
  148. )
  149. :
  150. cellSizeAndAlignmentControl
  151. (
  152. runTime,
  153. name,
  154. controlFunctionDict,
  155. geometryToConformTo,
  156. defaultCellSize
  157. ),
  158. surfaceName_(controlFunctionDict.lookupOrDefault<word>("surface", name)),
  159. searchableSurface_(geometryToConformTo.geometry()[surfaceName_]),
  160. geometryToConformTo_(geometryToConformTo),
  161. cellSizeFunctions_(1),
  162. regionToCellSizeFunctions_(searchableSurface_.regions().size(), -1),
  163. maxPriority_(-1)
  164. {
  165. Info<< indent << "Master settings:" << endl;
  166. Info<< incrIndent;
  167. cellSizeFunctions_.set
  168. (
  169. 0,
  170. cellSizeFunction::New
  171. (
  172. controlFunctionDict,
  173. searchableSurface_,
  174. defaultCellSize_,
  175. labelList()
  176. )
  177. );
  178. Info<< decrIndent;
  179. PtrList<cellSizeFunction> regionCellSizeFunctions;
  180. DynamicList<label> defaultCellSizeRegions;
  181. label nRegionCellSizeFunctions = 0;
  182. // Loop over regions - if any entry is not specified they should
  183. // inherit values from the parent surface.
  184. if (controlFunctionDict.found("regions"))
  185. {
  186. const dictionary& regionsDict = controlFunctionDict.subDict("regions");
  187. const wordList& regionNames = searchableSurface_.regions();
  188. label nRegions = regionsDict.size();
  189. regionCellSizeFunctions.setSize(nRegions);
  190. defaultCellSizeRegions.setCapacity(nRegions);
  191. forAll(regionNames, regionI)
  192. {
  193. const word& regionName = regionNames[regionI];
  194. label regionID = geometryToConformTo_.geometry().findSurfaceRegionID
  195. (
  196. this->name(),
  197. regionName
  198. );
  199. if (regionsDict.found(regionName))
  200. {
  201. // Get the dictionary for region
  202. const dictionary& regionDict = regionsDict.subDict(regionName);
  203. Info<< indent << "Region " << regionName
  204. << " (ID = " << regionID << ")" << " settings:"
  205. << endl;
  206. Info<< incrIndent;
  207. regionCellSizeFunctions.set
  208. (
  209. nRegionCellSizeFunctions,
  210. cellSizeFunction::New
  211. (
  212. regionDict,
  213. searchableSurface_,
  214. defaultCellSize_,
  215. labelList(1, regionID)
  216. )
  217. );
  218. Info<< decrIndent;
  219. regionToCellSizeFunctions_[regionID] = nRegionCellSizeFunctions;
  220. nRegionCellSizeFunctions++;
  221. }
  222. else
  223. {
  224. // Add to default list
  225. defaultCellSizeRegions.append(regionID);
  226. }
  227. }
  228. }
  229. if (defaultCellSizeRegions.empty() && !regionCellSizeFunctions.empty())
  230. {
  231. cellSizeFunctions_.transfer(regionCellSizeFunctions);
  232. }
  233. else if (nRegionCellSizeFunctions > 0)
  234. {
  235. regionCellSizeFunctions.setSize(nRegionCellSizeFunctions + 1);
  236. regionCellSizeFunctions.set
  237. (
  238. nRegionCellSizeFunctions,
  239. cellSizeFunction::New
  240. (
  241. controlFunctionDict,
  242. searchableSurface_,
  243. defaultCellSize_,
  244. labelList()
  245. )
  246. );
  247. const wordList& regionNames = searchableSurface_.regions();
  248. forAll(regionNames, regionI)
  249. {
  250. if (regionToCellSizeFunctions_[regionI] == -1)
  251. {
  252. regionToCellSizeFunctions_[regionI] = nRegionCellSizeFunctions;
  253. }
  254. }
  255. cellSizeFunctions_.transfer(regionCellSizeFunctions);
  256. }
  257. else
  258. {
  259. const wordList& regionNames = searchableSurface_.regions();
  260. forAll(regionNames, regionI)
  261. {
  262. if (regionToCellSizeFunctions_[regionI] == -1)
  263. {
  264. regionToCellSizeFunctions_[regionI] = 0;
  265. }
  266. }
  267. }
  268. forAll(cellSizeFunctions_, funcI)
  269. {
  270. const label funcPriority = cellSizeFunctions_[funcI].priority();
  271. if (funcPriority > maxPriority_)
  272. {
  273. maxPriority_ = funcPriority;
  274. }
  275. }
  276. // Sort controlFunctions_ by maxPriority
  277. SortableList<label> functionPriorities(cellSizeFunctions_.size());
  278. forAll(cellSizeFunctions_, funcI)
  279. {
  280. functionPriorities[funcI] = cellSizeFunctions_[funcI].priority();
  281. }
  282. functionPriorities.reverseSort();
  283. labelList invertedFunctionPriorities =
  284. invert(functionPriorities.size(), functionPriorities.indices());
  285. cellSizeFunctions_.reorder(invertedFunctionPriorities);
  286. Info<< nl << indent << "There are " << cellSizeFunctions_.size()
  287. << " region control functions" << endl;
  288. }
  289. // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
  290. Foam::searchableSurfaceControl::~searchableSurfaceControl()
  291. {}
  292. // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
  293. void Foam::searchableSurfaceControl::initialVertices
  294. (
  295. pointField& pts,
  296. scalarField& sizes,
  297. triadField& alignments
  298. ) const
  299. {
  300. pts = searchableSurface_.points();
  301. sizes.setSize(pts.size());
  302. alignments.setSize(pts.size());
  303. const scalar nearFeatDistSqrCoeff = 1e-8;
  304. forAll(pts, pI)
  305. {
  306. // Is the point in the extendedFeatureEdgeMesh? If so get the
  307. // point normal, otherwise get the surface normal from
  308. // searchableSurface
  309. pointIndexHit info;
  310. label infoFeature;
  311. geometryToConformTo_.findFeaturePointNearest
  312. (
  313. pts[pI],
  314. nearFeatDistSqrCoeff,
  315. info,
  316. infoFeature
  317. );
  318. scalar limitedCellSize = GREAT;
  319. autoPtr<triad> pointAlignment;
  320. if (info.hit())
  321. {
  322. const extendedFeatureEdgeMesh& features =
  323. geometryToConformTo_.features()[infoFeature];
  324. vectorField norms = features.featurePointNormals(info.index());
  325. // Create a triad from these norms.
  326. pointAlignment.set(new triad());
  327. forAll(norms, nI)
  328. {
  329. pointAlignment() += norms[nI];
  330. }
  331. pointAlignment().normalize();
  332. pointAlignment().orthogonalize();
  333. }
  334. else
  335. {
  336. geometryToConformTo_.findEdgeNearest
  337. (
  338. pts[pI],
  339. nearFeatDistSqrCoeff,
  340. info,
  341. infoFeature
  342. );
  343. if (info.hit())
  344. {
  345. const extendedFeatureEdgeMesh& features =
  346. geometryToConformTo_.features()[infoFeature];
  347. vectorField norms = features.edgeNormals(info.index());
  348. // Create a triad from these norms.
  349. pointAlignment.set(new triad());
  350. forAll(norms, nI)
  351. {
  352. pointAlignment() += norms[nI];
  353. }
  354. pointAlignment().normalize();
  355. pointAlignment().orthogonalize();
  356. }
  357. else
  358. {
  359. pointField ptField(1, pts[pI]);
  360. scalarField distField(1, nearFeatDistSqrCoeff);
  361. List<pointIndexHit> infoList(1, pointIndexHit());
  362. searchableSurface_.findNearest(ptField, distField, infoList);
  363. vectorField normals(1);
  364. searchableSurface_.getNormal(infoList, normals);
  365. if (mag(normals[0]) < SMALL)
  366. {
  367. normals[0] = vector(1, 1, 1);
  368. }
  369. pointAlignment.set(new triad(normals[0]));
  370. if (infoList[0].hit())
  371. {
  372. // Limit cell size
  373. const vector vN =
  374. infoList[0].hitPoint()
  375. - 2.0*normals[0]*defaultCellSize_;
  376. List<pointIndexHit> intersectionList;
  377. searchableSurface_.findLineAny
  378. (
  379. ptField,
  380. pointField(1, vN),
  381. intersectionList
  382. );
  383. }
  384. // if (intersectionList[0].hit())
  385. // {
  386. // scalar dist =
  387. // mag(intersectionList[0].hitPoint() - pts[pI]);
  388. //
  389. // limitedCellSize = dist/2.0;
  390. // }
  391. }
  392. }
  393. label priority = -1;
  394. if (!cellSize(pts[pI], sizes[pI], priority))
  395. {
  396. sizes[pI] = defaultCellSize_;
  397. // FatalErrorIn
  398. // (
  399. // "Foam::searchableSurfaceControl::initialVertices"
  400. // "(pointField&, scalarField&, tensorField&)"
  401. // ) << "Could not calculate cell size"
  402. // << abort(FatalError);
  403. }
  404. sizes[pI] = min(limitedCellSize, sizes[pI]);
  405. alignments[pI] = pointAlignment();
  406. }
  407. }
  408. void Foam::searchableSurfaceControl::cellSizeFunctionVertices
  409. (
  410. DynamicList<Foam::point>& pts,
  411. DynamicList<scalar>& sizes
  412. ) const
  413. {
  414. const tmp<pointField> tmpPoints = searchableSurface_.points();
  415. const pointField& points = tmpPoints();
  416. const scalar nearFeatDistSqrCoeff = 1e-8;
  417. pointField ptField(1, vector::min);
  418. scalarField distField(1, nearFeatDistSqrCoeff);
  419. List<pointIndexHit> infoList(1, pointIndexHit());
  420. vectorField normals(1);
  421. labelList region(1, label(-1));
  422. forAll(points, pI)
  423. {
  424. // Is the point in the extendedFeatureEdgeMesh? If so get the
  425. // point normal, otherwise get the surface normal from
  426. // searchableSurface
  427. ptField[0] = points[pI];
  428. searchableSurface_.findNearest(ptField, distField, infoList);
  429. if (infoList[0].hit())
  430. {
  431. searchableSurface_.getNormal(infoList, normals);
  432. searchableSurface_.getRegion(infoList, region);
  433. const cellSizeFunction& sizeFunc =
  434. sizeFunctions()[regionToCellSizeFunctions_[region[0]]];
  435. pointField extraPts;
  436. scalarField extraSizes;
  437. sizeFunc.sizeLocations
  438. (
  439. infoList[0],
  440. normals[0],
  441. extraPts,
  442. extraSizes
  443. );
  444. pts.append(extraPts);
  445. sizes.append(extraSizes);
  446. }
  447. }
  448. }
  449. bool Foam::searchableSurfaceControl::cellSize
  450. (
  451. const Foam::point& pt,
  452. scalar& cellSize,
  453. label& priority
  454. ) const
  455. {
  456. bool anyFunctionFound = false;
  457. forAll(sizeFunctions(), funcI)
  458. {
  459. const cellSizeFunction& sizeFunc = sizeFunctions()[funcI];
  460. if (sizeFunc.priority() < priority)
  461. {
  462. continue;
  463. }
  464. scalar sizeI = -1;
  465. if (sizeFunc.cellSize(pt, sizeI))
  466. {
  467. anyFunctionFound = true;
  468. if (sizeFunc.priority() == priority)
  469. {
  470. if (sizeI < cellSize)
  471. {
  472. cellSize = sizeI;
  473. }
  474. }
  475. else
  476. {
  477. cellSize = sizeI;
  478. priority = sizeFunc.priority();
  479. }
  480. if (debug)
  481. {
  482. Info<< " sizeI " << sizeI
  483. <<" minSize " << cellSize << endl;
  484. }
  485. }
  486. }
  487. return anyFunctionFound;
  488. }
  489. // ************************************************************************* //