navier-stokes.js_c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. var performance = performance || {};
  2. performance.now = function() {
  3. return performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow || Date.now
  4. }();
  5. function Benchmark(a, c, b, d, e, f, g, h, l) {
  6. this.name = a;
  7. this.doWarmup = c;
  8. this.doDeterministic = b;
  9. this.deterministicIterations = d;
  10. this.run = e;
  11. this.Setup = f ? f : function() {};
  12. this.TearDown = g ? g : function() {};
  13. this.rmsResult = h ? h : null;
  14. this.minIterations = l ? l : 32
  15. }
  16. function BenchmarkResult(a, c, b) {
  17. this.benchmark = a;
  18. this.time = c;
  19. this.latency = b
  20. }
  21. BenchmarkResult.prototype.valueOf = function() {
  22. return this.time
  23. };
  24. function BenchmarkSuite(a, c, b) {
  25. this.name = a;
  26. this.reference = c;
  27. this.benchmarks = b;
  28. BenchmarkSuite.suites.push(this)
  29. }
  30. BenchmarkSuite.suites = [];
  31. BenchmarkSuite.version = "9";
  32. BenchmarkSuite.config = {
  33. doWarmup: void 0,
  34. doDeterministic: void 0
  35. };
  36. alert = function(a) {
  37. throw "Alert called with argument: " + a;
  38. };
  39. BenchmarkSuite.ResetRNG = function() {
  40. Math.random = function() {
  41. var a = 49734321;
  42. return function() {
  43. a = a + 2127912214 + (a << 12) & 4294967295;
  44. a = (a ^ 3345072700 ^ a >>> 19) & 4294967295;
  45. a = a + 374761393 + (a << 5) & 4294967295;
  46. a = (a + 3550635116 ^ a << 9) & 4294967295;
  47. a = a + 4251993797 + (a << 3) & 4294967295;
  48. a = (a ^ 3042594569 ^ a >>> 16) & 4294967295;
  49. return (a & 268435455) / 268435456
  50. }
  51. }()
  52. };
  53. BenchmarkSuite.RunSuites = function(a, c) {
  54. function b() {
  55. for (; d || g < f;) {
  56. if (d) d = d();
  57. else {
  58. var h = e[g++];
  59. a.NotifyStart && a.NotifyStart(h.name); - 1 < c.indexOf(h.name) ? h.NotifySkipped(a) : d = h.RunStep(a)
  60. }
  61. if (d && "undefined" != typeof window && window.setTimeout) {
  62. window.setTimeout(b, 25);
  63. return
  64. }
  65. }
  66. a.NotifyScore && (h = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores), h = BenchmarkSuite.FormatScore(100 * h), a.NotifyScore(h))
  67. }
  68. c = "undefined" === typeof c ? [] : c;
  69. var d = null,
  70. e = BenchmarkSuite.suites,
  71. f = e.length;
  72. BenchmarkSuite.scores = [];
  73. var g =
  74. 0;
  75. b()
  76. };
  77. BenchmarkSuite.CountBenchmarks = function() {
  78. for (var a = 0, c = BenchmarkSuite.suites, b = 0; b < c.length; b++) a += c[b].benchmarks.length;
  79. return a
  80. };
  81. BenchmarkSuite.GeometricMean = function(a) {
  82. for (var c = 0, b = 0; b < a.length; b++) c += Math.log(a[b]);
  83. return Math.pow(Math.E, c / a.length)
  84. };
  85. BenchmarkSuite.GeometricMeanTime = function(a) {
  86. for (var c = 0, b = 0; b < a.length; b++) c += Math.log(a[b].time);
  87. return Math.pow(Math.E, c / a.length)
  88. };
  89. BenchmarkSuite.GeometricMeanLatency = function(a) {
  90. for (var c = 0, b = !1, d = 0; d < a.length; d++) 0 != a[d].latency && (c += Math.log(a[d].latency), b = !0);
  91. return b ? Math.pow(Math.E, c / a.length) : 0
  92. };
  93. BenchmarkSuite.FormatScore = function(a) {
  94. return 100 < a ? a.toFixed(0) : a.toPrecision(3)
  95. };
  96. BenchmarkSuite.prototype.NotifyStep = function(a) {
  97. this.results.push(a);
  98. this.runner.NotifyStep && this.runner.NotifyStep(a.benchmark.name)
  99. };
  100. BenchmarkSuite.prototype.NotifyResult = function() {
  101. var a = BenchmarkSuite.GeometricMeanTime(this.results),
  102. a = this.reference[0] / a;
  103. BenchmarkSuite.scores.push(a);
  104. this.runner.NotifyResult && (a = BenchmarkSuite.FormatScore(100 * a), this.runner.NotifyResult(this.name, a));
  105. 2 == this.reference.length && (a = BenchmarkSuite.GeometricMeanLatency(this.results), 0 != a && (a = this.reference[1] / a, BenchmarkSuite.scores.push(a), this.runner.NotifyResult && (a = BenchmarkSuite.FormatScore(100 * a), this.runner.NotifyResult(this.name + "Latency",
  106. a))))
  107. };
  108. BenchmarkSuite.prototype.NotifySkipped = function(a) {
  109. BenchmarkSuite.scores.push(1);
  110. a.NotifyResult && a.NotifyResult(this.name, "Skipped")
  111. };
  112. BenchmarkSuite.prototype.NotifyError = function(a) {
  113. this.runner.NotifyError && this.runner.NotifyError(this.name, a);
  114. this.runner.NotifyStep && this.runner.NotifyStep(this.name)
  115. };
  116. BenchmarkSuite.prototype.RunSingleBenchmark = function(a, c) {
  117. function b(b) {
  118. for (var c = 0, d = new Date, f = 0; e ? f < a.deterministicIterations : 1E3 > c; f++) a.run(), c = new Date - d;
  119. null != b && (b.runs += f, b.elapsed += c)
  120. }
  121. var d = BenchmarkSuite.config,
  122. e = void 0 !== d.doDeterministic ? d.doDeterministic : a.doDeterministic;
  123. (void 0 !== d.doWarmup ? d.doWarmup : a.doWarmup) || null != c || (c = {
  124. runs: 0,
  125. elapsed: 0
  126. });
  127. if (null == c) return b(null), {
  128. runs: 0,
  129. elapsed: 0
  130. };
  131. b(c);
  132. if (c.runs < a.minIterations) return c;
  133. var d = 1E3 * c.elapsed / c.runs,
  134. f = null != a.rmsResult ? a.rmsResult() :
  135. 0;
  136. this.NotifyStep(new BenchmarkResult(a, d, f));
  137. return null
  138. };
  139. BenchmarkSuite.prototype.RunStep = function(a) {
  140. function c() {
  141. if (f < e) {
  142. try {
  143. g.benchmarks[f].Setup()
  144. } catch (a) {
  145. return g.NotifyError(a), null
  146. }
  147. return b
  148. }
  149. g.NotifyResult();
  150. return null
  151. }
  152. function b() {
  153. try {
  154. h = g.RunSingleBenchmark(g.benchmarks[f], h)
  155. } catch (a) {
  156. return g.NotifyError(a), null
  157. }
  158. return null == h ? d : b()
  159. }
  160. function d() {
  161. try {
  162. g.benchmarks[f++].TearDown()
  163. } catch (a) {
  164. return g.NotifyError(a), null
  165. }
  166. return c
  167. }
  168. BenchmarkSuite.ResetRNG();
  169. this.results = [];
  170. this.runner = a;
  171. var e = this.benchmarks.length,
  172. f = 0,
  173. g = this,
  174. h;
  175. return c()
  176. };
  177. var NavierStokes = new BenchmarkSuite("NavierStokes", [1484E3, 2E3], [new Benchmark("NavierStokes", !0, !0, 180, runNavierStokes, setupNavierStokes, tearDownNavierStokes, null, 16)]),
  178. solver = null,
  179. nsFrameCounter = 0;
  180. function runNavierStokes() {
  181. solver.update();
  182. nsFrameCounter++;
  183. 15 == nsFrameCounter && checkResult(solver.getDens())
  184. }
  185. function checkResult(a) {
  186. this.result = 0;
  187. for (var c = 7E3; 7100 > c; c++) this.result += ~~(10 * a[c]);
  188. if (77 != this.result) throw Error("checksum failed");
  189. }
  190. function setupNavierStokes() {
  191. solver = new FluidField(null);
  192. solver.setResolution(128, 128);
  193. solver.setIterations(20);
  194. solver.setDisplayFunction(function() {});
  195. solver.setUICallback(prepareFrame);
  196. solver.reset()
  197. }
  198. function tearDownNavierStokes() {
  199. solver = null
  200. }
  201. function addPoints(a) {
  202. for (var c = 1; 64 >= c; c++) a.setVelocity(c, c, 64, 64), a.setDensity(c, c, 5), a.setVelocity(c, 64 - c, -64, -64), a.setDensity(c, 64 - c, 20), a.setVelocity(128 - c, 64 + c, -64, -64), a.setDensity(128 - c, 64 + c, 30)
  203. }
  204. var framesTillAddingPoints = 0,
  205. framesBetweenAddingPoints = 5;
  206. function prepareFrame(a) {
  207. 0 == framesTillAddingPoints ? (addPoints(a), framesTillAddingPoints = framesBetweenAddingPoints, framesBetweenAddingPoints++) : framesTillAddingPoints--
  208. }
  209. function FluidField(a) {
  210. function c(a, b, c) { //addFields
  211. for (var d = 0; d < Zb; d++) a[d] += c * b[d]
  212. }
  213. function b(a, b) { //set_bnd
  214. if (1 === a) {
  215. for (var c = 1; c <= E; c++) b[c] = b[c + Xb], b[c + (M + 1) * Xb] = b[c + M * Xb];
  216. for (c = 1; c <= M; c++) b[c * Xb] = -b[1 + c * Xb], b[E + 1 + c * Xb] = -b[E + c * Xb]
  217. } else {
  218. if (2 === a)
  219. for (c = 1; c <= E; c++) b[c] = -b[c + Xb], b[c + (M + 1) * Xb] = -b[c + M * Xb];
  220. else
  221. for (c = 1; c <= E; c++) b[c] = b[c + Xb], b[c + (M + 1) * Xb] = b[c + M * Xb];
  222. for (c = 1; c <= M; c++) b[c * Xb] = b[1 + c * Xb], b[E + 1 + c * Xb] = b[E + c * Xb]
  223. }
  224. c = (M + 1) * Xb;
  225. b[0] = .5 * (b[1] + b[Xb]);
  226. b[c] = .5 * (b[1 + c] + b[M * Xb]);
  227. b[E + 1] = .5 * (b[E] + b[E + 1 + Xb]);
  228. b[E + 1 + c] = .5 * (b[E + c] + b[E + 1 + M * Xb])
  229. }
  230. function d(a, c, d, e, f) { //lin_solve
  231. if (0 === e && 1 === f) {
  232. for (f = 1; f <= M; f++) {
  233. var g = f * Xb;
  234. ++g;
  235. for (var h = 0; h < E; h++) c[g] = d[g], ++g
  236. }
  237. b(a, c)
  238. } else
  239. for (var l = 1 / f, p = 0; p < m; p++) {
  240. for (f = 1; f <= M; f++) {
  241. var q = (f - 1) * Xb,
  242. g = f * Xb,
  243. y = (f + 1) * Xb,
  244. A = c[g];
  245. ++g;
  246. for (h = 1; h <= E; h++) A = c[g] = (d[g] + e * (A + c[++g] + c[++q] + c[++y])) * l
  247. }
  248. b(a, c)
  249. }
  250. }
  251. function e(a, c, d, e, f, g) { // advect
  252. var h = g * E;
  253. g *= M;
  254. for (var l = E + .5, m = M + .5, p = 1; p <= M; p++)
  255. for (var q = p * Xb, y = 1; y <= E; y++) {
  256. var A = y - h * e[++q],
  257. B = p - g * f[q];
  258. .5 > A ? A = .5 : A > l && (A = l);
  259. var H = A | 0,
  260. K = H + 1;
  261. .5 > B ? B = .5 : B > m && (B = m);
  262. var aa = B | 0,
  263. A = A - H,
  264. B = B - aa,
  265. Zb = 1 - B,
  266. rc = aa * Xb,
  267. aa = (aa + 1) * Xb;
  268. c[q] = (1 - A) * (Zb * d[H + rc] + B * d[H + aa]) + A * (Zb * d[K + rc] + B * d[K + aa])
  269. }
  270. b(a, c)
  271. }
  272. function f(a, c, e, f) { // project
  273. for (var g = -.5 / Math.sqrt(E * M), h = 1; h <= M; h++)
  274. for (var l = h * Xb,
  275. m = (h - 1) * Xb,
  276. p = l - 1,
  277. q = l,
  278. y = l + 1,
  279. l = (h + 1) * Xb,
  280. A = 1; A <= E; A++) {
  281. f[++q] = g * (a[++y] - a[++p] + c[++l] - c[++m]);
  282. e[q] = 0;
  283. }
  284. b(0, f);
  285. b(0, e);
  286. d(0, e, f, 1, 4);
  287. f = .5 * E;
  288. g = .5 * M;
  289. for (h = 1; h <= M; h++)
  290. for (m = h * Xb - 1,
  291. p = h * Xb,
  292. q = h * Xb + 1,
  293. y = (h - 1) * Xb,
  294. l = (h + 1) * Xb,
  295. A = 1; A <= E; A++) {
  296. a[++p] -= f * (e[++q] - e[++m]);
  297. c[p] -= g * (e[++l] - e[++y]);
  298. }
  299. b(1, a);
  300. b(2, c)
  301. }
  302. function g(a, b, c) {
  303. this.setDensity = function(b,
  304. c, d) {
  305. a[b + 1 + (c + 1) * Xb] = d
  306. };
  307. this.getDensity = function(b, c) {
  308. return a[b + 1 + (c + 1) * Xb]
  309. };
  310. this.setVelocity = function(a, d, e, f) {
  311. b[a + 1 + (d + 1) * Xb] = e;
  312. c[a + 1 + (d + 1) * Xb] = f
  313. };
  314. this.getXVelocity = function(a, c) {
  315. return b[a + 1 + (c + 1) * Xb]
  316. };
  317. this.getYVelocity = function(a, b) {
  318. return c[a + 1 + (b + 1) * Xb]
  319. };
  320. this.width = function() {
  321. return E
  322. };
  323. this.height = function() {
  324. return M
  325. }
  326. }
  327. function h() {
  328. Xb = E + 2;
  329. Zb = (E + 2) * (M + 2);
  330. p = Array(Zb);
  331. y = Array(Zb);
  332. A = Array(Zb);
  333. B = Array(Zb);
  334. K = Array(Zb);
  335. H = Array(Zb);
  336. for (var a = 0; a < Zb; a++) y[a] = B[a] = H[a] = p[a] = A[a] = K[a] = 0
  337. }
  338. var l = function(a,
  339. b, c) {};
  340. this.update = function() {
  341. // queryUI inline
  342. for (var a = y, h = B, m = H, bc = 0; bc < Zb; bc++) h[bc] = m[bc] = a[bc] = 0;
  343. l(new g(a, h, m)); // uiCallback(new Field(d, u, v))
  344. // end queryUI inline
  345. // vel_step inline
  346. var a = A,
  347. h = K,
  348. m = B,
  349. bc = H,
  350. ec = q;
  351. c(a, m, ec); // addFields(u, u0, dt)
  352. c(h, bc, ec); // addFields(v, v0, dt)
  353. // diffuse2 inline
  354. // lin_solve2 inline
  355. // note that it also figures out that a===0 and c===1 statically, so it only inlines the first half of lin_solve2
  356. for (var jc = m, m = a, a = jc, jc = bc, bc = h, h = jc, jc = a, cc = m, dc = h, gc = bc, hc = 1; hc <= M; hc++) {
  357. var fc = hc * Xb;
  358. ++fc;
  359. for (var kc = 0; kc < E; kc++) jc[fc] = cc[fc], dc[fc] = gc[fc], ++fc
  360. }
  361. b(1, jc);
  362. b(2, dc);
  363. // end lin_solve2 inline
  364. // end diffuse2 inline
  365. f(a, h, m, bc); // project(u, v, u0, v0)
  366. jc = m;
  367. m = a;
  368. a = jc;
  369. jc = bc;
  370. bc = h;
  371. h = jc;
  372. e(1, a, m, m, bc, ec); // advect(1, u, u0, u0, v0, dt)
  373. e(2, h, bc, m, bc, ec); // advect(2, v, v0, u0, v0, dt)
  374. f(a, h, m, bc); // project(u, v, u0, v0)
  375. // end vel_step inline
  376. // dens_step inline
  377. a = p;
  378. h = y;
  379. m = A;
  380. bc = K;
  381. ec = q;
  382. c(a, h, ec); // addFields(x, x0, dt)
  383. // begin diffuse inline
  384. d(0, h, a, 0, 1); // lin_solve(b, x, x0, a, 1 + 4*a)
  385. // end diffuse inline
  386. e(0, a, h, m, bc, ec); // advect(0, x, x0, u, v, dt)
  387. // end dens_step inline
  388. aa(new g(p, A, K)) // displayFunc(new Field(dens, u, v))
  389. };
  390. this.setDisplayFunction =
  391. function(a) {
  392. aa = a
  393. };
  394. this.iterations = function() {
  395. return m
  396. };
  397. this.setIterations = function(a) {
  398. 0 < a && 100 >= a && (m = a)
  399. };
  400. this.setUICallback = function(a) {
  401. l = a
  402. };
  403. var m = 10,
  404. q = .1,
  405. p, y, A, B, K, H, E, M, Xb, Zb, aa;
  406. this.reset = h;
  407. this.getDens = function() {
  408. return p
  409. };
  410. this.setResolution = function(a, b) {
  411. var c = b * a;
  412. return 0 < c && 1E6 > c && (b != E || a != M) ? (E = b, M = a, h(), !0) : !1
  413. };
  414. this.setResolution(64, 64)
  415. };
  416. ////////////////////////////////////////////////////////////////////////////////
  417. // Runner
  418. ////////////////////////////////////////////////////////////////////////////////
  419. var success = true;
  420. function NotifyStart(name) {}
  421. function NotifyError(name, error) {
  422. WScript.Echo(name + " : ERROR : " + error.stack);
  423. success = false;
  424. }
  425. function NotifyResult(name, score) {
  426. if (success) {
  427. WScript.Echo("### SCORE:", score);
  428. }
  429. }
  430. function NotifyScore(score) {}
  431. BenchmarkSuite.RunSuites({
  432. NotifyStart: NotifyStart,
  433. NotifyError: NotifyError,
  434. NotifyResult: NotifyResult,
  435. NotifyScore: NotifyScore
  436. });