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

/chapter12.m

https://github.com/rwinklerwilkes/Matlab
Objective C | 368 lines | 367 code | 1 blank | 0 comment | 30 complexity | 5469064d5a6c4da8f68b03e313aff046 MD5 | raw file
  1. %Poisson Equation Finite-Difference
  2. %Variable key
  3. %a - Lowest x-value
  4. %b - Highest x-value
  5. %c - Lowest y-value
  6. %d - Highest y-value
  7. %m - Number of y partitions, >=3
  8. %n - Number of x partitions, >=3
  9. %f - Function they satisfy
  10. %gB - Boundary condition for y=c
  11. %gT - Boundary condition for y=d
  12. %gL - Boundary condition for x=a
  13. %gR - Boundary condition for x=b
  14. function p = pefd(a,b,c,d,m,n,f,gB,gT,gL,gR,TOL,maxIter)
  15. %Step 1
  16. h = (b-a)/n;
  17. k = (d-c)/m;
  18. x = zeros(1,n-1);
  19. y = zeros(1,m-1);
  20. %Step 4
  21. w = zeros(n,m);
  22. %Step 2
  23. i=1;
  24. while(i<=(n-1))
  25. x(i) = a+i*h;
  26. i++;
  27. endwhile
  28. %Step 3
  29. i = 1;
  30. while(i<=(m-1))
  31. y(i) = c+i*k;
  32. i++;
  33. endwhile
  34. %Step 5
  35. lambda = (h**2)/(k**2);
  36. mu = 2*(1+lambda);
  37. l = 1;
  38. %Step 6
  39. while(l<=maxIter)
  40. %Step 7
  41. z = ((-h**2)*f(x(1),y(m-1)) +gL(y(m-1)) + lambda*gT(x(1)) + lambda*w(1,m-2) + w(2,m-1))/mu;
  42. NORM = abs(z-w(1,m-1));
  43. w(1,m-1) = z;
  44. %Step 8
  45. i = 2;
  46. while(i<=(n-2))
  47. z = ((-h**2)*f(x(i),y(m-1)) + lambda*gT(x(i)) + w(i-1,m-1) + w(i+1,m-1) + lambda*w(i,m-2))/mu;
  48. if(abs(w(i,m-1) - z) > NORM)
  49. NORM = abs(w(i,m-1)-z);
  50. endif
  51. w(i,m-1) = z;
  52. i++;
  53. endwhile
  54. %Step 9
  55. z = ((-h**2)*f(x(n-1),y(m-1)) + gR(y(m-1)) + lambda*gT(x(n-1)) + w(n-2,m-1) + lambda*w(n-1,m-2))/mu;
  56. if(abs(w(n-1,m-1)-z) > NORM)
  57. NORM = abs(w(n-1,m-1)-z);
  58. endif
  59. w(n-1,m-1) = z;
  60. %Step 10
  61. j = m-2;
  62. while(j>=2)
  63. %Step 11
  64. z = ((-h**2)*f(x(1),y(j)) + gL(y(j)) + lambda*w(1,j+1)+lambda*w(1,j-1)+w(2,j))/mu;
  65. if(abs(w(1,j)-z) > NORM)
  66. NORM = abs(w(1,j)-z);
  67. endif
  68. w(1,j) = z;
  69. %Step 12
  70. i = 2;
  71. while(i<=n-2)
  72. z = ((-h**2)*f(x(i),y(j)) + w(i-1,j) + lambda*w(i,j+1)+w(i+1,j)+lambda*w(i,j-1))/mu;
  73. if(abs(w(i,j)-z) > NORM)
  74. NORM = abs(w(i,j)-z);
  75. endif
  76. w(i,j) = z;
  77. i++;
  78. endwhile
  79. %Step 13
  80. z= (-(h**2)*f(x(n-1),y(j)) + gR(y(j)) + w(n-2,j) + lambda*w(n-1,j+1) + lambda*w(n-1,j-1))/mu;
  81. if(abs(w(n-1,j)-z) > NORM)
  82. NORM = abs(w(n-1,j)-z);
  83. endif
  84. w(n-1,j) = z;
  85. j--;
  86. endwhile
  87. %Step 14
  88. z= (-(h**2)*f(x(1),y(1)) + gL(y(1))+lambda*gB(x(1)) + lambda*w(1,2) + w(2,1))/mu;
  89. if(abs(w(1,1)-z) > NORM)
  90. NORM = abs(w(1,1)-z);
  91. endif
  92. w(1,1) = z;
  93. %Step 15
  94. i = 2;
  95. while(i<=(n-2))
  96. z= (-(h**2)*f(x(i),y(1)) + lambda*gB(x(i))+w(i-1,1) + lambda*w(i,2) + w(i+1,1))/mu;
  97. if(abs(w(i,1)-z) > NORM)
  98. NORM = abs(w(i,1)-z);
  99. endif
  100. w(i,1) = z;
  101. i++;
  102. endwhile
  103. %Step 16
  104. z = (-(h**2)*f(x(n-1),y(1)) + gR(y(1)) + lambda*gB(x(n-1)) + w(n-2,1) + lambda*w(n-1,2))/mu;
  105. if(abs(w(n-1,1) - z) > NORM)
  106. NORM = abs(w(n-1,1) - z);
  107. endif
  108. w(n-1,1) = z;
  109. %Step 17
  110. if(NORM<=TOL)
  111. i = 1;
  112. while(i<=(n-1))
  113. j = 1;
  114. while(j<=(m-1))
  115. printf("x(%d): %g, y(%d): %g, w(%d,%d): %g\n", i,x(i),j,y(j),i,j,w(i,j));
  116. j++;
  117. endwhile
  118. i++;
  119. endwhile
  120. p = 0;
  121. return;
  122. endif
  123. l++;
  124. endwhile
  125. printf("Max iterations exceeded");
  126. p = -1;
  127. return;
  128. endfunction
  129. %g - Dirichlet boundary condition
  130. %g1,g2 - Neumann boundary conditions
  131. %verts - Vertices of the triangulation
  132. %nodes - each node corresponds to the row of verts which contains the vertex for that node
  133. %triVerts - each row has 3 values - the three node numbers of the triangle
  134. %K - Interior triangles
  135. %N - Triangles with at least one Neumann edge
  136. %M - All other triangles (total triangles - K+N+M)
  137. %n - Nodes either in D or on the Neumann edge
  138. %m - Dirichlet nodes
  139. function f = fe(p,q,r,f,g,g1,g2,verts,nodes,triVerts,K,N,M,n,m)
  140. gamma = zeros(1,m);
  141. l = n+1;
  142. while(l<=m)
  143. gamma(l) = g(verts(nodes(l),1),verts(nodes(l),2));
  144. l++;
  145. endwhile
  146. alpha = zeros(n,n);
  147. beta = zeros(1,n);
  148. delta = zeros(1,M);
  149. a = zeros(M,3);
  150. b = zeros(M,3);
  151. c = zeros(M,3);
  152. z = zeros(M,3,3);
  153. J = zeros(M,3,3);
  154. I = zeros(M,3);
  155. H = zeros(M,3);
  156. i = 1;
  157. while(i<=M)
  158. x1 = verts(nodes(triVerts(i,1)),1);
  159. x2 = verts(nodes(triVerts(i,2)),1);
  160. x3 = verts(nodes(triVerts(i,3)),1);
  161. y1 = verts(nodes(triVerts(i,1)),2);
  162. y2 = verts(nodes(triVerts(i,2)),2);
  163. y3 = verts(nodes(triVerts(i,3)),2);
  164. delta(i) = det([1,x1,y1;1,x2,y2;1,x3,y3]);
  165. a(i,1) = (x2*y3-y2*x3)/delta(i);
  166. a(i,2) = (x3*y1-y3*x1)/delta(i);
  167. a(i,3) = (x1*y2-y1*x2)/delta(i);
  168. b(i,1) = (y2-y3)/delta(i);
  169. b(i,2) = (y3-y1)/delta(i);
  170. b(i,3) = (y1-y2)/delta(i);
  171. c(i,1) = (x3-x2)/delta(i);
  172. c(i,2) = (x1-x3)/delta(i);
  173. c(i,3) = (x2-x1)/delta(i);
  174. i++;
  175. endwhile
  176. i = 1;
  177. while(i<=M)
  178. j = 1;
  179. while(j<=3)
  180. k = 1;
  181. while(k<=j)
  182. nj = @(x,y)(a(i,j) + b(i,j)*x + c(i,j)*y);
  183. nk = @(x,y)(a(i,k) + b(i,k)*x + c(i,k)*y);
  184. %Calculate the integrals over the triangles
  185. zIntegral = @(x,y)(r(x,y)*nj(x,y)*nk(x,y));
  186. %Approximate the integral using quadrature rule for triangles
  187. %node 1
  188. x1 = verts(nodes(triVerts(i,1)),1);
  189. y1 = verts(nodes(triVerts(i,1)),2);
  190. %node 2
  191. x2 = verts(nodes(triVerts(i,2)),1);
  192. y2 = verts(nodes(triVerts(i,2)),2);
  193. %node 3
  194. x3 = verts(nodes(triVerts(i,3)),1);
  195. y3 = verts(nodes(triVerts(i,3)),2);
  196. area = (1/6)*abs(det([x1,x2,x3;y1,y2,y3;1,1,1]));
  197. %mid1 = midpoint between node 1 and node 2
  198. midx1 = (x1+x2)/2;
  199. midy1 = (y1+y2)/2;
  200. %mid1 = midpoint between node 2 and node 3
  201. midx2 = (x2+x3)/2;
  202. midy2 = (y2+y3)/2;
  203. %mid1 = midpoint between node 1 and node 3
  204. midx3 = (x1+x3)/2;
  205. midy3 = (y1+y3)/2;
  206. firstTerm = b(i,j)*b(i,k)*area*(p(x1,y1)+p(x2,y2)+p(x3,y3));
  207. secondTerm = c(i,j)*c(i,k)*area*(q(x1,y1)+q(x2,y2)+q(x3,y3));
  208. thirdTerm = -1*area*(zIntegral(x1,y1)+zIntegral(x2,y2)+zIntegral(x3,y3));
  209. z(i,j,k) = firstTerm+secondTerm+thirdTerm;
  210. hInt = @(x,y)(f(x,y)*nj(x,y));
  211. H(i,j) = -1*area*(hInt(x1,y1)+hInt(x2,y2)+hInt(x3,y3));
  212. k++;
  213. endwhile
  214. j++;
  215. endwhile
  216. i++;
  217. endwhile
  218. %Approximate the line integrals for the Neumann nodes
  219. %%%%%%%%%%%%%%%%%%%%%%%%%%%%
  220. %Unfinished, probably doesn't work
  221. i = K+1;
  222. while(i<N)
  223. j = 1;
  224. while(j<=3)
  225. k = 1;
  226. while(k<=j)
  227. node1X = verts(nodes(i),1);
  228. node1Y = verts(nodes(i),2);
  229. node2X = verts(nodes(i+1),1);
  230. node2Y = verts(nodes(i+1),2);
  231. length = sqrt((node2X-node1X)**2+(node2Y-node1Y)**2);
  232. nj = @(x,y)(a(i,j) + b(i,j)*x + c(i,j)*y);
  233. nk = @(x,y)(a(i,k) + b(i,k)*x + c(i,k)*y);
  234. firstInt = @(x,y)(g1(x,y)*nj(x,y)*nk(x,y));
  235. secondInt = @(x,y)(g2(x,y)*nj(x,y));
  236. J(i,j,k) = (length/4)*(firstInt(node1X,node1Y)+firstInt(node2X,node2Y));
  237. I(i,j) = (length/4)*(secondInt(node1X,node1Y)+secondInt(node2X,node2Y));
  238. k++;
  239. endwhile
  240. j++;
  241. endwhile
  242. i++;
  243. endwhile
  244. %%%%%%%%%%%%%%%%%%%%%%%%%%%%
  245. %Step 7
  246. i = 1;
  247. while(i<=M)
  248. k = 1;
  249. while(k<=3)
  250. %Step 8
  251. triNodeIKX = verts(nodes(triVerts(i,k)),1);
  252. triNodeIKY = verts(nodes(triVerts(i,k)),2);
  253. l = 1;
  254. while(l<=M)
  255. if((verts(nodes(l),1)==triNodeIKX)&&(verts(nodes(l),2)==triNodeIKY))
  256. break;
  257. endif
  258. l++;
  259. endwhile
  260. %Step 9
  261. if(k>1)
  262. j = 1;
  263. while(j<=k-1)
  264. %Step 10
  265. triNodeIKX = verts(nodes(triVerts(i,j)),1);
  266. triNodeIKY = verts(nodes(triVerts(i,j)),2);
  267. t = 1;
  268. while(t<=M)
  269. if((verts(nodes(t),1)==triNodeIKX)&&(verts(nodes(t),2)==triNodeIKY))
  270. break;
  271. endif
  272. t++;
  273. endwhile
  274. %Step 11
  275. if(l<=n)
  276. if(t<=n)
  277. alpha(l,t) = alpha(l,t)+z(i,k,j);
  278. alpha(t,l) = alpha(t,l)+z(i,k,j);
  279. else
  280. beta(l) = beta(l) - gamma(t)*z(i,k,j);
  281. endif
  282. else
  283. if(t<=n)
  284. beta(t) = beta(t) - gamma(l)*z(i,k,j);
  285. endif
  286. endif
  287. j++;
  288. endwhile
  289. endif
  290. if(l<=n)
  291. alpha(l,l) = alpha(l,l) + z(i,k,k);
  292. beta(l) = beta(l) + H(i,k);
  293. endif
  294. k++;
  295. endwhile
  296. i++;
  297. endwhile
  298. %Step 13
  299. i = K+1;
  300. while(i<=N)
  301. %Step 14
  302. k = 1;
  303. while(k<=3)
  304. %Step 15
  305. triNodeIKX = verts(nodes(triVerts(i,k)),1);
  306. triNodeIKY = verts(nodes(triVerts(i,k)),2);
  307. l = 1;
  308. while(l<=M)
  309. if((verts(nodes(l),1)==triNodeIKX)&&(verts(nodes(l),2)==triNodeIKY))
  310. break;
  311. endif
  312. l++;
  313. endwhile
  314. %Step 16
  315. if(k>1)
  316. j = 1;
  317. while(j<=k-1)
  318. %Step 17
  319. triNodeIKX = verts(nodes(triVerts(i,j)),1);
  320. triNodeIKY = verts(nodes(triVerts(i,j)),2);
  321. t = 1;
  322. while(t<=M)
  323. if((verts(nodes(t),1)==triNodeIKX)&&(verts(nodes(t),2)==triNodeIKY))
  324. break;
  325. endif
  326. t++;
  327. endwhile
  328. %Step 18
  329. if(l<=n)
  330. if(t<=n)
  331. alpha(l,t) = alpha(l,t) + J(i,k,j);
  332. alpha(t,l) = alpha(t,l) + J(i,k,j);
  333. else
  334. beta(l) = beta(l) - gamma(t)*J(i,k,j);
  335. endif
  336. else
  337. if(t<=n)
  338. beta(t) = beta(t)-gamma(l)*J(i,k,j);
  339. endif
  340. endif
  341. j++;
  342. endwhile
  343. endif
  344. %Step 19
  345. if(l<=n)
  346. alpha(l,l) = alpha(l,l) + J(i,k,k);
  347. beta(l) = beta(l) + I(i,k);
  348. endif
  349. k++;
  350. endwhile
  351. i++;
  352. endwhile
  353. disp(alpha);
  354. disp(beta');
  355. solution = alpha \ beta';
  356. disp(solution);
  357. i = 1;
  358. while(i<=M)
  359. j = 1;
  360. while(j<=3)
  361. printf("Triangle %i, a(%i): %4g, b(%i): %4g, c(%i): %4g\n",i,j,a(i,j),j,b(i,j),j,c(i,j));
  362. j++;
  363. endwhile
  364. i++;
  365. endwhile
  366. return;
  367. endfunction