Guest User

Untitled

a guest
Mar 22nd, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.36 KB | None | 0 0
  1. NX = 200;
  2. NY = 100;
  3.  
  4. // result is 2D array with bounary value (size is [NY + 2][NX + 2])
  5. var result;
  6. result = solveLaplaceEquationByJacobiMethod(NX, NY, 1.0 / NX, 1.0 / NY, makeExampleBoundaryFunc2(NX, NY), {eps: 0.01});
  7. result = solveLaplaceEquationByGaussSeidelMethod(NX, NY, 1.0 / NX, 1.0 / NY, makeExampleBoundaryFunc2(NX, NY), {eps: 0.01});
  8. result = solvePoissonEquationByJacobiMethod(NX, NY, 1.0 / NX, 1.0 / NY, makeExamplePoissonFunc(NX, NY), makeExampleBoundaryFunc2(NX, NY), {eps: 0.01});
  9. result = solvePoissonEquationByGaussSeidelMethod(NX, NY, 1.0 / NX, 1.0 / NY, makeExamplePoissonFunc(NX, NY), makeExampleBoundaryFunc2(NX, NY), {eps: 0.01
  10.  
  11. // example of boundary codition
  12. function makeExampleBoundaryFunc1(nx, ny) {
  13. return function(g, x, y) {
  14. if (x === 0) {
  15. return -1.0 + 2.0 * y / (ny + 1.0);
  16. } else if (x === nx + 1) {
  17. return 1.0 - 2.0 * y / (ny + 1.0);
  18. } else if (y === 0) {
  19. return -1.0 + 2.0 * x / (nx + 1.0);
  20. } else if (y === ny + 1) {
  21. return 1.0 - 2.0 * x / (nx + 1.0);
  22. }
  23. }
  24. }
  25.  
  26. // example of boundary condition
  27. function makeExampleBoundaryFunc2(nx, ny) {
  28. return function(g, x, y) {
  29. if (y === 0) {
  30. return Math.sin(x * 0.1);
  31. } else if (y === ny + 1) {
  32. return Math.cos(x * 0.1);
  33. } else {
  34. return 0.0;
  35. }
  36. }
  37. }
  38.  
  39. // example of poisson function
  40. function makeExamplePoissonFunc(nx, ny) {
  41. return function(x, y) {
  42. var d = Math.sqrt(Math.pow(x / nx - 0.5, 2.0) + Math.pow(y / ny - 0.5, 2.0));
  43. var s = 0.2;
  44. return 5.0 * exp(- d * d / (2.0 * s * s)) / sqrt(2.0 * Math.PI * s * s);
  45. }
  46. }
  47.  
  48. /**
  49. * Creates 2D array
  50. * @param {number} nx - number of rows
  51. * @param {number} ny - number of columns
  52. * @param {function} defaultFunc - function to get value
  53. * @return {array} - 2d array
  54. */
  55. function createArray2D(nx, ny, defaultFunc) {
  56. var defaultFunc = defaultFunc !== undefined ? defaultFunc : function(x, y) {return 0.0;};
  57. var array = new Array(ny);
  58. for (var y = 0; y < ny; y++) {
  59. array[y] = new Array(nx);
  60. for (var x = 0; x < nx; x++) {
  61. array[y][x] = defaultFunc(x, y);
  62. }
  63. }
  64. return array;
  65. }
  66.  
  67. /**
  68. * Solves 2D Laplace equation with boundary condition by Gauess SeidelMethod
  69. * @param {number} nx - number of rows
  70. * @param {number} ny - number of columns
  71. * @param {number} dx - size of x grid
  72. * @param {number} dy - size of y grid
  73. * @param {function} boundaryFunc - function to set boundary
  74. * @param {Object} opts - options
  75. * @param {number} opts.nr - number of repetiation
  76. * @param {number} opts.eps - minimum error to stop repetiation
  77. * @return {array} - 2D array with boundary (size = array[ny + 2][nx + 2])
  78. */
  79. function solveLaplaceEquationByJacobiMethod(nx, ny, dx, dy, boundaryFunc, opts) {
  80. var dx2 = dx * dx;
  81. var dy2 = dy * dy;
  82. var func = function(f, x, y) {
  83. return (dy2 * (f[y][x - 1] + f[y][x + 1]) + dx2 * (f[y - 1][x] + f[y + 1][x])) / (2.0 * (dx2 + dy2));
  84. }
  85.  
  86. return solveByJacobiMethodFor2D(nx, ny, func, boundaryFunc, opts);
  87. }
  88.  
  89. /**
  90. * Solves 2D Laplace equation with boundary condition by Gauess SeidelMethod
  91. * @param {number} nx - number of rows
  92. * @param {number} ny - number of columns
  93. * @param {number} dx - size of x grid
  94. * @param {number} dy - size of y grid
  95. * @param {function} boundaryFunc - function to set boundary
  96. * @param {Object} opts - options
  97. * @param {number} opts.nr - number of repetiation
  98. * @param {number} opts.eps - minimum error to stop repetiation
  99. * @return {array} - 2D array with boundary (size = array[ny + 2][nx + 2])
  100. */
  101. function solveLaplaceEquationByGaussSeidelMethod(nx, ny, dx, dy, boundaryFunc, opts) {
  102. var dx2 = dx * dx;
  103. var dy2 = dy * dy;
  104. var func = function(f, x, y) {
  105. return (dy2 * (f[y][x - 1] + f[y][x + 1]) + dx2 * (f[y - 1][x] + f[y + 1][x])) / (2.0 * (dx2 + dy2));
  106. }
  107.  
  108. return solveByGaussSeidelMethodFor2D(nx, ny, func, boundaryFunc, opts);
  109. }
  110.  
  111. /**
  112. * Solves 2D Poisson equation with boundary condition by Jacobi method
  113. * @param {number} nx - number of rows
  114. * @param {number} ny - number of columns
  115. * @param {number} dx - size of x grid
  116. * @param {number} dy - size of y grid
  117. * @apram {function} poissonFunc - function for poisson equation
  118. * @param {function} boundaryFunc - function to set boundary
  119. * @param {Object} opts - options
  120. * @param {number} opts.nr - number of repetiation
  121. * @param {number} opts.eps - minimum error to stop repetiation
  122. * @return {array} - 2D array with boundary (size = array[ny + 2][nx + 2])
  123. */
  124. function solvePoissonEquationByJacobiMethod(nx, ny, dx, dy, poissonFunc, boundaryFunc, opts) {
  125. var dx2 = dx * dx;
  126. var dy2 = dy * dy;
  127. var func = function(f, x, y) {
  128. return (dy2 * (f[y][x - 1] + f[y][x + 1]) + dx2 * (f[y - 1][x] + f[y + 1][x]) - dx2 * dy2 * poissonFunc(x, y)) / (2.0 * (dx2 + dy2));
  129. }
  130.  
  131. return solveByJacobiMethodFor2D(nx, ny, func, boundaryFunc, opts);
  132. }
  133.  
  134.  
  135. /**
  136. * Solves 2D Poisson equation with boundary condition by Gauess Seidel method
  137. * @param {number} nx - number of rows
  138. * @param {number} ny - number of columns
  139. * @param {number} dx - size of x grid
  140. * @param {number} dy - size of y grid
  141. * @apram {function} poissonFunc - function for poisson equation
  142. * @param {function} boundaryFunc - function to set boundary
  143. * @param {Object} opts - options
  144. * @param {number} opts.nr - number of repetiation
  145. * @param {number} opts.eps - minimum error to stop repetiation
  146. * @return {array} - 2D array with boundary (size = array[ny + 2][nx + 2])
  147. */
  148. function solvePoissonEquationByGaussSeidelMethod(nx, ny, dx, dy, poissonFunc, boundaryFunc, opts) {
  149. var dx2 = dx * dx;
  150. var dy2 = dy * dy;
  151. var func = function(f, x, y) {
  152. return (dy2 * (f[y][x - 1] + f[y][x + 1]) + dx2 * (f[y - 1][x] + f[y + 1][x]) - dx2 * dy2 * poissonFunc(x, y)) / (2.0 * (dx2 + dy2));
  153. }
  154.  
  155. return solveByGaussSeidelMethodFor2D(nx, ny, func, boundaryFunc, opts);
  156. }
  157.  
  158. /**
  159. * Solves 2D equation with boundary condition by Jacobi method
  160. * @param {number} nr - number of repetiation
  161. * @param {number} nx - number of rows
  162. * @param {number} ny - number of columns
  163. * @param {function} func - function which represents equation
  164. * @param {function} boundaryFunc - function to set boundary
  165. * @param {Object} opts - options
  166. * @param {number} opts.nr - number of repetiation
  167. * @param {number} opts.eps - minimum error to stop repetiation
  168. * @return {array} - 2D array with boundary (size = array[ny + 2][nx + 2])
  169. */
  170. function solveByJacobiMethodFor2D(nx, ny, func, boundaryFunc, opts) {
  171. var nr = opts && opts.nr !== undefined ? opts.nr : null;
  172. var eps = opts && opts.eps !== undefined ? opts.eps : null;
  173. if (nr === null && eps === null) {
  174. nr = 100;
  175. eps = 0.01;
  176. }
  177.  
  178. var pg = createArray2D(nx + 2, ny + 2);
  179. var ng = createArray2D(nx + 2, ny + 2);
  180.  
  181. var setBoundary = function(g) {
  182. for (var x = 1; x < nx + 1; x++) {
  183. g[0][x] = boundaryFunc(g, x, 0);
  184. g[ny + 1][x] = boundaryFunc(g, x, ny + 1);
  185. }
  186. for (var y = 1; y < ny + 1; y++) {
  187. g[y][0] = boundaryFunc(g, 0, y);
  188. g[y][nx + 1] = boundaryFunc(g, nx + 1, y);
  189. }
  190. g[0][0] = boundaryFunc(g, 0, 0);
  191. g[0][nx + 1] = boundaryFunc(g, nx + 1, 0);
  192. g[ny + 1][0] = boundaryFunc(g, 0, ny + 1);
  193. g[ny + 1][nx + 1] = boundaryFunc(g, nx + 1, ny + 1);
  194. }
  195. setBoundary(pg);
  196. setBoundary(ng);
  197.  
  198. var step = function() {
  199. var error = 0.0;
  200. var temp = pg;
  201. pg = ng;
  202. ng = temp;
  203. for (var y = 1; y < ny + 1; y++) {
  204. for (var x = 1; x < nx + 1; x++) {
  205. var v = func(pg, x, y);
  206. error += Math.abs(pg[y][x] - v);
  207. ng[y][x] = v;
  208. }
  209. }
  210. return error;
  211. }
  212.  
  213. if (nr) {
  214. for (var r = 0; r < nr; r++) {
  215. var e = step();
  216. if (eps && e < eps) {break;}
  217. }
  218. } else {
  219. while(true) {
  220. var e = step();
  221. if (e < eps) {break;}
  222. }
  223. };
  224.  
  225. return ng;
  226. }
  227.  
  228. /**
  229. * Solves 2D equation with boundary condition by Gauss-Seidel method
  230. * @param {number} nr - number of repetiation
  231. * @param {number} nx - number of rows
  232. * @param {number} ny - number of columns
  233. * @param {function} func - function which represents equation
  234. * @param {function} boundaryFunc - function to set boundary
  235. * @param {Object} opts - options
  236. * @param {number} opts.nr - number of repetiation
  237. * @param {number} opts.eps - minimum error to stop repetiation
  238. * @return {array} - 2D array with boundary (size = array[ny + 2][nx + 2])
  239. */
  240. function solveByGaussSeidelMethodFor2D(nx, ny, func, boundaryFunc, opts) {
  241. var nr = opts && opts.nr !== undefined ? opts.nr : null;
  242. var eps = opts && opts.eps !== undefined ? opts.eps : null;
  243. if (nr === null && eps === null) {
  244. nr = 100;
  245. eps = 0.01;
  246. }
  247.  
  248. var g = createArray2D(nx + 2, ny + 2);
  249.  
  250. // set up boundary
  251. for (var x = 1; x < nx + 1; x++) {
  252. g[0][x] = boundaryFunc(g, x, 0);
  253. g[ny + 1][x] = boundaryFunc(g, x, ny + 1);
  254. }
  255. for (var y = 1; y < ny + 1; y++) {
  256. g[y][0] = boundaryFunc(g, 0, y);
  257. g[y][nx + 1] = boundaryFunc(g, nx + 1, y);
  258. }
  259. g[0][0] = boundaryFunc(g, 0, 0);
  260. g[0][nx + 1] = boundaryFunc(g, nx + 1, 0);
  261. g[ny + 1][0] = boundaryFunc(g, 0, ny + 1);
  262. g[ny + 1][nx + 1] = boundaryFunc(g, nx + 1, ny + 1);
  263.  
  264. var step = function() {
  265. var error = 0.0;
  266. for (var y = 1; y < ny + 1; y++) {
  267. for (var x = 1; x < nx + 1; x++) {
  268. var v = func(g, x, y);
  269. error += Math.abs(g[y][x] - v);
  270. g[y][x] = v;
  271. }
  272. }
  273. return error;
  274. }
  275.  
  276. if (nr) {
  277. for (var r = 0; r < nr; r++) {
  278. var e = step();
  279. if (eps && e < eps) {break;}
  280. }
  281. } else {
  282. while(true) {
  283. var e = step();
  284. if (e < eps) {break;}
  285. }
  286. };
  287.  
  288. return g;
  289. }
Add Comment
Please, Sign In to add comment