PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/Libraries/swak4FoamParsers/patchedDistroFiles/patchedInterpolation2DTable.C

https://bitbucket.org/bgschaid/swak4foam-temporary-replacement-for-original-repo-on
C | 519 lines | 412 code | 62 blank | 45 comment | 36 complexity | 1d0e254143f5576f25fad9374ae6cf5b MD5 | raw file
Possible License(s): GPL-2.0
  1. /*---------------------------------------------------------------------------*\
  2. ========= |
  3. \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
  4. \\ / O peration |
  5. \\ / A nd | Copyright (C) 2011-2013 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 "IFstream.H"
  22. #include "openFoamTableReader.H"
  23. // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
  24. template<class Type>
  25. void Foam::interpolation2DTable<Type>::readTable()
  26. {
  27. fileName fName(fileName_);
  28. fName.expand();
  29. // Read data from file
  30. reader_()(fName, *this);
  31. if (this->empty())
  32. {
  33. FatalErrorIn
  34. (
  35. "Foam::interpolation2DTable<Type>::readTable()"
  36. ) << "table read from " << fName << " is empty" << nl
  37. << exit(FatalError);
  38. }
  39. // Check that the data are in ascending order
  40. checkOrder();
  41. }
  42. // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
  43. template<class Type>
  44. Foam::interpolation2DTable<Type>::interpolation2DTable()
  45. :
  46. List<Tuple2<scalar, List<Tuple2<scalar, Type> > > >(),
  47. boundsHandling_(interpolation2DTable::WARN),
  48. fileName_("fileNameIsUndefined"),
  49. reader_(NULL)
  50. {}
  51. template<class Type>
  52. Foam::interpolation2DTable<Type>::interpolation2DTable
  53. (
  54. const List<Tuple2<scalar, List<Tuple2<scalar, Type> > > >& values,
  55. const boundsHandling bounds,
  56. const fileName& fName
  57. )
  58. :
  59. List<Tuple2<scalar, List<Tuple2<scalar, Type> > > >(values),
  60. boundsHandling_(bounds),
  61. fileName_(fName),
  62. reader_(NULL)
  63. {}
  64. template<class Type>
  65. Foam::interpolation2DTable<Type>::interpolation2DTable(const fileName& fName)
  66. :
  67. List<Tuple2<scalar, List<Tuple2<scalar, Type> > > >(),
  68. boundsHandling_(interpolation2DTable::WARN),
  69. fileName_(fName),
  70. reader_(new openFoamTableReader<Type>(dictionary()))
  71. {
  72. readTable();
  73. }
  74. template<class Type>
  75. Foam::interpolation2DTable<Type>::interpolation2DTable(const dictionary& dict)
  76. :
  77. List<Tuple2<scalar, List<Tuple2<scalar, Type> > > >(),
  78. boundsHandling_(wordToBoundsHandling(dict.lookup("outOfBounds"))),
  79. fileName_(dict.lookup("fileName")),
  80. reader_(tableReader<Type>::New(dict))
  81. {
  82. readTable();
  83. }
  84. template<class Type>
  85. Foam::interpolation2DTable<Type>::interpolation2DTable
  86. (
  87. const interpolation2DTable& interpTable
  88. )
  89. :
  90. List<Tuple2<scalar, List<Tuple2<scalar, Type> > > >(interpTable),
  91. boundsHandling_(interpTable.boundsHandling_),
  92. fileName_(interpTable.fileName_),
  93. reader_(interpTable.reader_) // note: steals reader. Used in write().
  94. {}
  95. // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
  96. template<class Type>
  97. Type Foam::interpolation2DTable<Type>::interpolateValue
  98. (
  99. const List<Tuple2<scalar, Type> >& data,
  100. const scalar lookupValue
  101. ) const
  102. {
  103. label n = data.size();
  104. scalar minLimit = data.first().first();
  105. scalar maxLimit = data.last().first();
  106. if (lookupValue < minLimit)
  107. {
  108. switch (boundsHandling_)
  109. {
  110. case interpolation2DTable::ERROR:
  111. {
  112. FatalErrorIn
  113. (
  114. "Foam::interpolation2DTable<Type>::interpolateValue"
  115. "("
  116. "List<Tuple2<scalar, Type> >&, "
  117. "const scalar"
  118. ")"
  119. ) << "value (" << lookupValue << ") less than lower "
  120. << "bound (" << minLimit << ")" << nl
  121. << exit(FatalError);
  122. break;
  123. }
  124. case interpolation2DTable::WARN:
  125. {
  126. WarningIn
  127. (
  128. "Foam::interpolation2DTable<Type>::interpolateValue"
  129. "("
  130. "List<Tuple2<scalar, Type> >&, "
  131. "const scalar"
  132. ")"
  133. ) << "value (" << lookupValue << ") less than lower "
  134. << "bound (" << minLimit << ")" << nl
  135. << " Continuing with the first entry"
  136. << endl;
  137. // fall-through to 'CLAMP'
  138. }
  139. case interpolation2DTable::CLAMP:
  140. {
  141. return data.first().second();
  142. break;
  143. }
  144. }
  145. }
  146. else if (lookupValue >= maxLimit)
  147. {
  148. switch (boundsHandling_)
  149. {
  150. case interpolation2DTable::ERROR:
  151. {
  152. FatalErrorIn
  153. (
  154. "Foam::interpolation2DTable<Type>::interpolateValue"
  155. "("
  156. "List<Tuple2<scalar, Type> >&, "
  157. "const scalar"
  158. ")"
  159. ) << "value (" << lookupValue << ") greater than upper "
  160. << "bound (" << maxLimit << ")" << nl
  161. << exit(FatalError);
  162. break;
  163. }
  164. case interpolation2DTable::WARN:
  165. {
  166. WarningIn
  167. (
  168. "Foam::interpolation2DTable<Type>::interpolateValue"
  169. "("
  170. "List<Tuple2<scalar, Type> >&, "
  171. "const scalar"
  172. ")"
  173. ) << "value (" << lookupValue << ") greater than upper "
  174. << "bound (" << maxLimit << ")" << nl
  175. << " Continuing with the last entry"
  176. << endl;
  177. // fall-through to 'CLAMP'
  178. }
  179. case interpolation2DTable::CLAMP:
  180. {
  181. return data.last().second();
  182. break;
  183. }
  184. }
  185. }
  186. // look for the correct range in X
  187. label lo = 0;
  188. label hi = 0;
  189. for (label i = 0; i < n; ++i)
  190. {
  191. if (lookupValue >= data[i].first())
  192. {
  193. lo = hi = i;
  194. }
  195. else
  196. {
  197. hi = i;
  198. break;
  199. }
  200. }
  201. if (lo == hi)
  202. {
  203. return data[lo].second();
  204. }
  205. else
  206. {
  207. Type m =
  208. (data[hi].second() - data[lo].second())
  209. /(data[hi].first() - data[lo].first());
  210. // normal interpolation
  211. return data[lo].second() + m*(lookupValue - data[lo].first());
  212. }
  213. }
  214. template<class Type>
  215. template<class BinaryOp>
  216. Foam::label Foam::interpolation2DTable<Type>::Xi
  217. (
  218. const BinaryOp& bop,
  219. const scalar valueX,
  220. const bool reverse
  221. ) const
  222. {
  223. const table& t = *this;
  224. label limitI = 0;
  225. if (reverse)
  226. {
  227. limitI = t.size() - 1;
  228. }
  229. if (bop(valueX, t[limitI].first()))
  230. {
  231. switch (boundsHandling_)
  232. {
  233. case interpolation2DTable::ERROR:
  234. {
  235. FatalErrorIn
  236. (
  237. "Foam::label Foam::interpolation2DTable<Type>::Xi"
  238. "("
  239. "const BinaryOp&, "
  240. "const scalar, "
  241. "const bool"
  242. ") const"
  243. ) << "value (" << valueX << ") out of bounds"
  244. << exit(FatalError);
  245. break;
  246. }
  247. case interpolation2DTable::WARN:
  248. {
  249. WarningIn
  250. (
  251. "Foam::label Foam::interpolation2DTable<Type>::Xi"
  252. "("
  253. "const BinaryOp&, "
  254. "const scalar, "
  255. "const bool"
  256. ) << "value (" << valueX << ") out of bounds"
  257. << endl;
  258. // fall-through to 'CLAMP'
  259. }
  260. case interpolation2DTable::CLAMP:
  261. {
  262. return limitI;
  263. }
  264. default:
  265. {
  266. FatalErrorIn
  267. (
  268. "Foam::label Foam::interpolation2DTable<Type>::Xi"
  269. "("
  270. "const BinaryOp&, "
  271. "const scalar, "
  272. "const bool"
  273. ") const"
  274. )
  275. << "Un-handled enumeration " << boundsHandling_
  276. << abort(FatalError);
  277. }
  278. }
  279. }
  280. label i = 0;
  281. if (reverse)
  282. {
  283. label nX = t.size();
  284. i = 0;
  285. while ((i < nX) && (valueX > t[i].first()))
  286. {
  287. i++;
  288. }
  289. }
  290. else
  291. {
  292. i = t.size() - 1;
  293. while ((i > 0) && (valueX < t[i].first()))
  294. {
  295. i--;
  296. }
  297. }
  298. return i;
  299. }
  300. // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
  301. template<class Type>
  302. Type Foam::interpolation2DTable<Type>::operator()
  303. (
  304. const scalar valueX,
  305. const scalar valueY
  306. ) const
  307. {
  308. // Considers all of the list in Y being equal
  309. label nX = this->size();
  310. const table& t = *this;
  311. if (nX == 0)
  312. {
  313. WarningIn
  314. (
  315. "Type Foam::interpolation2DTable<Type>::operator()"
  316. "("
  317. "const scalar, "
  318. "const scalar"
  319. ") const"
  320. )
  321. << "cannot interpolate a zero-sized table - returning zero" << endl;
  322. return pTraits<Type>::zero;
  323. }
  324. else if (nX == 1)
  325. {
  326. // only 1 column (in X) - interpolate to find Y value
  327. return interpolateValue(t.first().second(), valueY);
  328. }
  329. else
  330. {
  331. // have 2-D data, interpolate
  332. // find low and high indices in the X range that bound valueX
  333. label x0i = Xi(lessOp<scalar>(), valueX, false);
  334. label x1i = Xi(greaterOp<scalar>(), valueX, true);
  335. if (x0i == x1i)
  336. {
  337. return interpolateValue(t[x0i].second(), valueY);
  338. }
  339. else
  340. {
  341. Type y0(interpolateValue(t[x0i].second(), valueY));
  342. Type y1(interpolateValue(t[x1i].second(), valueY));
  343. // gradient in X
  344. scalar x0 = t[x0i].first();
  345. scalar x1 = t[x1i].first();
  346. Type mX = (y1 - y0)/(x1 - x0);
  347. // interpolate
  348. return y0 + mX*(valueX - x0);
  349. }
  350. }
  351. }
  352. template<class Type>
  353. Foam::word Foam::interpolation2DTable<Type>::boundsHandlingToWord
  354. (
  355. const boundsHandling& bound
  356. ) const
  357. {
  358. word enumName("warn");
  359. switch (bound)
  360. {
  361. case interpolation2DTable::ERROR:
  362. {
  363. enumName = "error";
  364. break;
  365. }
  366. case interpolation2DTable::WARN:
  367. {
  368. enumName = "warn";
  369. break;
  370. }
  371. case interpolation2DTable::CLAMP:
  372. {
  373. enumName = "clamp";
  374. break;
  375. }
  376. }
  377. return enumName;
  378. }
  379. template<class Type>
  380. typename Foam::interpolation2DTable<Type>::boundsHandling
  381. Foam::interpolation2DTable<Type>::wordToBoundsHandling
  382. (
  383. const word& bound
  384. ) const
  385. {
  386. if (bound == "error")
  387. {
  388. return interpolation2DTable::ERROR;
  389. }
  390. else if (bound == "warn")
  391. {
  392. return interpolation2DTable::WARN;
  393. }
  394. else if (bound == "clamp")
  395. {
  396. return interpolation2DTable::CLAMP;
  397. }
  398. else
  399. {
  400. WarningIn
  401. (
  402. "Foam::interpolation2DTable<Type>::wordToBoundsHandling"
  403. "("
  404. " const word&"
  405. ")"
  406. ) << "bad outOfBounds specifier " << bound << " using 'warn'" << endl;
  407. return interpolation2DTable::WARN;
  408. }
  409. }
  410. template<class Type>
  411. typename Foam::interpolation2DTable<Type>::boundsHandling
  412. Foam::interpolation2DTable<Type>::outOfBounds
  413. (
  414. const boundsHandling& bound
  415. )
  416. {
  417. boundsHandling prev = boundsHandling_;
  418. boundsHandling_ = bound;
  419. return prev;
  420. }
  421. template<class Type>
  422. void Foam::interpolation2DTable<Type>::checkOrder() const
  423. {
  424. label n = this->size();
  425. const table& t = *this;
  426. scalar prevValue = t[0].first();
  427. for (label i=1; i<n; ++i)
  428. {
  429. const scalar currValue = t[i].first();
  430. // avoid duplicate values (divide-by-zero error)
  431. if (currValue <= prevValue)
  432. {
  433. FatalErrorIn
  434. (
  435. "Foam::interpolation2DTable<Type>::checkOrder() const"
  436. ) << "out-of-order value: "
  437. << currValue << " at index " << i << nl
  438. << exit(FatalError);
  439. }
  440. prevValue = currValue;
  441. }
  442. }
  443. template<class Type>
  444. void Foam::interpolation2DTable<Type>::write(Ostream& os) const
  445. {
  446. os.writeKeyword("fileName")
  447. << fileName_ << token::END_STATEMENT << nl;
  448. os.writeKeyword("outOfBounds")
  449. << boundsHandlingToWord(boundsHandling_) << token::END_STATEMENT << nl;
  450. // patched:
  451. // *this >> os;
  452. }
  453. // ************************************************************************* //