PageRenderTime 27ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/libraries/core/interpolation/interpolation/interpolationCellPointFace/interpolationCellPointFace.hpp

https://bitbucket.org/gsoxley/caelus-contributors
C++ Header | 450 lines | 301 code | 70 blank | 79 comment | 28 complexity | 4db7f705f795ab66cc59315c10164928 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, GPL-3.0
  1. /*---------------------------------------------------------------------------*\
  2. Copyright (C) 2011 OpenFOAM Foundation
  3. -------------------------------------------------------------------------------
  4. License
  5. This file is part of CAELUS.
  6. CAELUS is free software: you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. CAELUS is distributed in the hope that it will be useful, but WITHOUT
  11. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with CAELUS. If not, see <http://www.gnu.org/licenses/>.
  16. Class
  17. CML::interpolationCellPointFace
  18. Description
  19. CML::interpolationCellPointFace
  20. \*---------------------------------------------------------------------------*/
  21. #ifndef interpolationCellPointFace_H
  22. #define interpolationCellPointFace_H
  23. #include "interpolation.hpp"
  24. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  25. namespace CML
  26. {
  27. /*---------------------------------------------------------------------------*\
  28. Class interpolationCellPointFace Declaration
  29. \*---------------------------------------------------------------------------*/
  30. template<class Type>
  31. class interpolationCellPointFace
  32. :
  33. public interpolation<Type>
  34. {
  35. // Private data
  36. //- Interpolated volfield
  37. const GeometricField<Type, pointPatchField, pointMesh> psip_;
  38. //- Linearly interpolated volfield
  39. const GeometricField<Type, fvsPatchField, surfaceMesh> psis_;
  40. bool findTet
  41. (
  42. const vector& position,
  43. const label nFace,
  44. vector tetPoints[],
  45. label tetLabelCandidate[],
  46. label tetPointLabels[],
  47. scalar phi[],
  48. scalar phiCandidate[],
  49. label& closestFace,
  50. scalar& minDistance
  51. ) const;
  52. bool findTriangle
  53. (
  54. const vector& position,
  55. const label nFace,
  56. label tetPointLabels[],
  57. scalar phi[]
  58. ) const;
  59. public:
  60. //- Runtime type information
  61. TypeName("cellPointFace");
  62. // Constructors
  63. //- Construct from components
  64. interpolationCellPointFace
  65. (
  66. const GeometricField<Type, fvPatchField, volMesh>& psi
  67. );
  68. // Member Functions
  69. //- Interpolate field to the given point in the given cell
  70. Type interpolate
  71. (
  72. const vector& position,
  73. const label cellI,
  74. const label faceI = -1
  75. ) const;
  76. };
  77. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  78. } // End namespace CML
  79. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  80. #include "volFields.hpp"
  81. #include "polyMesh.hpp"
  82. #include "volPointInterpolation.hpp"
  83. #include "linear.hpp"
  84. #include "findCellPointFaceTet.hpp"
  85. #include "findCellPointFaceTriangle.hpp"
  86. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  87. namespace CML
  88. {
  89. // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
  90. template<class Type>
  91. interpolationCellPointFace<Type>::interpolationCellPointFace
  92. (
  93. const GeometricField<Type, fvPatchField, volMesh>& psi
  94. )
  95. :
  96. interpolation<Type>(psi),
  97. psip_(volPointInterpolation::New(psi.mesh()).interpolate(psi)),
  98. psis_(linearInterpolate(psi))
  99. {}
  100. // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
  101. template<class Type>
  102. Type interpolationCellPointFace<Type>::interpolate
  103. (
  104. const vector& position,
  105. const label cellI,
  106. const label faceI
  107. ) const
  108. {
  109. Type ts[4];
  110. vector tetPoints[4];
  111. scalar phi[4], phiCandidate[4];
  112. label tetLabelCandidate[2], tetPointLabels[2];
  113. Type t = pTraits<Type>::zero;
  114. // only use face information when the position is on a face
  115. if (faceI < 0)
  116. {
  117. const vector& cellCentre = this->pMesh_.cellCentres()[cellI];
  118. const labelList& cellFaces = this->pMesh_.cells()[cellI];
  119. vector projection = position - cellCentre;
  120. tetPoints[3] = cellCentre;
  121. // *********************************************************************
  122. // project the cell-center through the point onto the face
  123. // and get the closest face, ...
  124. // *********************************************************************
  125. bool foundTet = false;
  126. label closestFace = -1;
  127. scalar minDistance = GREAT;
  128. forAll(cellFaces, faceI)
  129. {
  130. label nFace = cellFaces[faceI];
  131. vector normal = this->pMeshFaceAreas_[nFace];
  132. normal /= mag(normal);
  133. const vector& faceCentreTmp = this->pMeshFaceCentres_[nFace];
  134. scalar multiplierNumerator = (faceCentreTmp - cellCentre) & normal;
  135. scalar multiplierDenominator = projection & normal;
  136. // if normal and projection are not orthogonal this could
  137. // be the one...
  138. if (mag(multiplierDenominator) > SMALL)
  139. {
  140. scalar multiplier = multiplierNumerator/multiplierDenominator;
  141. vector iPoint = cellCentre + multiplier*projection;
  142. scalar dist = mag(position - iPoint);
  143. if (dist < minDistance)
  144. {
  145. closestFace = nFace;
  146. minDistance = dist;
  147. }
  148. }
  149. }
  150. // *********************************************************************
  151. // find the tetrahedron containing 'position'
  152. // from the cell center, face center and
  153. // two other points on the face
  154. // *********************************************************************
  155. minDistance = GREAT;
  156. if (closestFace != -1)
  157. {
  158. label nFace = closestFace;
  159. foundTet = findTet
  160. (
  161. position,
  162. nFace,
  163. tetPoints,
  164. tetLabelCandidate,
  165. tetPointLabels,
  166. phi,
  167. phiCandidate,
  168. closestFace,
  169. minDistance
  170. );
  171. }
  172. if (!foundTet)
  173. {
  174. // check if the position is 'just' outside a tet
  175. if (minDistance < 1.0e-5)
  176. {
  177. foundTet = true;
  178. for (label i=0; i<4; i++)
  179. {
  180. phi[i] = phiCandidate[i];
  181. }
  182. tetPointLabels[0] = tetLabelCandidate[0];
  183. tetPointLabels[1] = tetLabelCandidate[1];
  184. }
  185. }
  186. // *********************************************************************
  187. // if the search failed check all the cell-faces
  188. // *********************************************************************
  189. if (!foundTet)
  190. {
  191. minDistance = GREAT;
  192. label faceI = 0;
  193. while (faceI < cellFaces.size() && !foundTet)
  194. {
  195. label nFace = cellFaces[faceI];
  196. if (nFace < this->pMeshFaceAreas_.size())
  197. {
  198. foundTet = findTet
  199. (
  200. position,
  201. nFace,
  202. tetPoints,
  203. tetLabelCandidate,
  204. tetPointLabels,
  205. phi,
  206. phiCandidate,
  207. closestFace,
  208. minDistance
  209. );
  210. }
  211. faceI++;
  212. }
  213. }
  214. if (!foundTet)
  215. {
  216. // check if the position is 'just' outside a tet
  217. // this time with a more tolerant limit
  218. if (minDistance < 1.0e-3)
  219. {
  220. foundTet = true;
  221. for (label i=0; i<4; i++)
  222. {
  223. phi[i] = phiCandidate[i];
  224. }
  225. tetPointLabels[0] = tetLabelCandidate[0];
  226. tetPointLabels[1] = tetLabelCandidate[1];
  227. }
  228. }
  229. // *********************************************************************
  230. // if the tet was found do the interpolation,
  231. // otherwise use the closest face value
  232. // *********************************************************************
  233. if (foundTet)
  234. {
  235. for (label i=0; i<2; i++)
  236. {
  237. ts[i] = psip_[tetPointLabels[i]];
  238. }
  239. if (closestFace < psis_.size())
  240. {
  241. ts[2] = psis_[closestFace];
  242. }
  243. else
  244. {
  245. label patchI =
  246. this->pMesh_.boundaryMesh().whichPatch(closestFace);
  247. // If the boundary patch is not empty use the face value
  248. // else use the cell value
  249. if (this->psi_.boundaryField()[patchI].size())
  250. {
  251. ts[2] = this->psi_.boundaryField()[patchI]
  252. [
  253. this->pMesh_.boundaryMesh()[patchI].whichFace
  254. (
  255. closestFace
  256. )
  257. ];
  258. }
  259. else
  260. {
  261. ts[2] = this->psi_[cellI];
  262. }
  263. }
  264. ts[3] = this->psi_[cellI];
  265. for (label n=0; n<4; n++)
  266. {
  267. phi[n] = min(1.0, phi[n]);
  268. phi[n] = max(0.0, phi[n]);
  269. t += phi[n]*ts[n];
  270. }
  271. }
  272. else
  273. {
  274. Info<< "interpolationCellPointFace<Type>::interpolate"
  275. << "(const vector&, const label cellI) const : "
  276. << "search failed; using closest cellFace value" << endl
  277. << "cell number " << cellI << tab
  278. << "position " << position << endl;
  279. if (closestFace < psis_.size())
  280. {
  281. t = psis_[closestFace];
  282. }
  283. else
  284. {
  285. label patchI =
  286. this->pMesh_.boundaryMesh().whichPatch(closestFace);
  287. // If the boundary patch is not empty use the face value
  288. // else use the cell value
  289. if (this->psi_.boundaryField()[patchI].size())
  290. {
  291. t = this->psi_.boundaryField()[patchI]
  292. [
  293. this->pMesh_.boundaryMesh()[patchI].whichFace
  294. (
  295. closestFace
  296. )
  297. ];
  298. }
  299. else
  300. {
  301. t = this->psi_[cellI];
  302. }
  303. }
  304. }
  305. }
  306. else
  307. {
  308. bool foundTriangle = findTriangle
  309. (
  310. position,
  311. faceI,
  312. tetPointLabels,
  313. phi
  314. );
  315. if (foundTriangle)
  316. {
  317. // add up the point values ...
  318. for (label i=0; i<2; i++)
  319. {
  320. Type vel = psip_[tetPointLabels[i]];
  321. t += phi[i]*vel;
  322. }
  323. // ... and the face value
  324. if (faceI < psis_.size())
  325. {
  326. t += phi[2]*psis_[faceI];
  327. }
  328. else
  329. {
  330. label patchI = this->pMesh_.boundaryMesh().whichPatch(faceI);
  331. // If the boundary patch is not empty use the face value
  332. // else use the cell value
  333. if (this->psi_.boundaryField()[patchI].size())
  334. {
  335. t += phi[2]*this->psi_.boundaryField()[patchI]
  336. [this->pMesh_.boundaryMesh()[patchI].whichFace(faceI)];
  337. }
  338. else
  339. {
  340. t += phi[2]*this->psi_[cellI];
  341. }
  342. }
  343. }
  344. else
  345. {
  346. // use face value only
  347. if (faceI < psis_.size())
  348. {
  349. t = psis_[faceI];
  350. }
  351. else
  352. {
  353. label patchI = this->pMesh_.boundaryMesh().whichPatch(faceI);
  354. // If the boundary patch is not empty use the face value
  355. // else use the cell value
  356. if (this->psi_.boundaryField()[patchI].size())
  357. {
  358. t = this->psi_.boundaryField()[patchI]
  359. [this->pMesh_.boundaryMesh()[patchI].whichFace(faceI)];
  360. }
  361. else
  362. {
  363. t = this->psi_[cellI];
  364. }
  365. }
  366. }
  367. }
  368. return t;
  369. }
  370. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  371. } // End namespace CML
  372. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  373. #endif
  374. // ************************************************************************* //