Advertisement
Guest User

Untitled

a guest
Apr 2nd, 2020
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 6.15 KB | None | 0 0
  1. % Onni Pohjavirta 04.04.2019
  2.  
  3. % Revision history:
  4. %   - 02.01.2020 Cleaning up the code
  5.  
  6. %   2D p-FEM solver for a PDE with given weak form
  7. %   applying zero boundary conditions
  8. %   (expandable to other boundary conditions)
  9. %
  10. %       This is a FEM solver which uses p'th order polynomial basis
  11. %       defined on quadrilateral elements. The mesh is imported in
  12. %       standard form: matrices {p, e, t} where
  13. %           -p holds coordinates of mesh nodes         (2-by-x)
  14. %           -e holds indeces of edge nodes             (1-by-x)
  15. %           -t holds indeces of nodes in each element  (4-by-x)
  16. %
  17. %
  18.  
  19.  
  20. %% DEFINE THE FOLLOWING:
  21.  
  22. % Mesh via matrices p e t
  23.    
  24.     % For example:
  25.     % L-domain - w/ refined corner
  26.     p = [0.5 0; 0.75 0; 1 0; 1 0.25; 1 0.5; 1 0.75; 1 1; 0.75 1; 0.5 1; ...
  27.         0.25 1; 0 1; 0 0.75; 0 0.5; 0.25 0.5; 0.5 0.25; ...
  28.         0.75 0.25; 0.75 0.5; 0.75 0.75; 0.5 0.75; 0.25 0.75; ...
  29.         0.5 0.45; 0.55 0.45; 0.55 0.5; 0.55 0.55; ...
  30.         0.5 0.55; 0.45 0.55; 0.45 0.5; 0.5 0.5]';
  31.     t = [1 2 16 15; 2 3 4 16; 4 5 17 16; 5 6 18 17; 6 7 8 18; ...
  32.          8 9 19 18; 9 10 20 19; 10 11 12 20; 12 13 14 20; ...
  33.          15 16 22 21; 16 17 23 22; 17 18 24 23; 18 19 25 24; ...
  34.          19 20 26 25; 20 14 27 26; 21 22 23 28; 23 24 25 28; ...
  35.          25 26 27 28]';
  36.      e = [1:14 27 28 21 15];
  37.  
  38.    
  39. % Path of auxiliary FEM functions
  40.     addpath('C:\Users\Onni\Dropbox\Opinnot_Aallossa\FiniteElementMethod\ProjectClean\functions');
  41.  
  42. % Degree of polynomial basis
  43.     pp = 1;
  44.  
  45. % Load function
  46.     f = @(x,y) sin(pi*x).*sin(pi*y);
  47.  
  48. % Weak form B(u,v) = L(v):
  49.     B = @(Xp,U,V,dU,dV) dU{1}.*dV{1} + dU{2}.*dV{2};
  50.     L = @(Xp,V,dV) f(Xp{1},Xp{2}).*V;
  51.  
  52. % Exact solution - for error estimation (if known)
  53.     fex = @(x,y) 1/(2*pi^2) * sin(pi*x).*sin(pi*y);
  54.     fexdx = @(x,y) 1/(2*pi) * cos(pi*x).*sin(pi*y);
  55.     fexdy = @(x,y) 1/(2*pi) * sin(pi*x).*cos(pi*y);
  56.  
  57.    
  58.    
  59.  
  60. %% INITIALIZE
  61.  
  62. Nel = size(t,2);                % #elements
  63. Nn  = size(p,2);                % #nodes
  64. Nb  = 4 + 4*(pp-1) + (pp-1)^2;  % #local basis functions
  65. N   = pp+2;                     % #1D quadrature points  
  66.  
  67. % Fix node indeces in t to go anti-clockwise in each element
  68. t = fixMeshIndeces(t,p);
  69. p1 = p(1,:); p2 = p(2,:);   % Visualize
  70. figure; patch(p1(t), p2(t), 0)
  71.  
  72. % 1D Quadrature points and weights
  73. [qp1D,w1D] = gaussint(N, -1, 1);
  74.  
  75. % 2D Quadrature points and weights:
  76. qp = {repmat(qp1D , 1, N) , repmat(qp1D', N, 1)};
  77. w = w1D*w1D';
  78.  
  79. % Legendre pol. & der. coefficients
  80. legc  = legendrepol(pp);
  81. legdc = legc(:,2:end).*(1:pp);  % shift and scale
  82.  
  83. % Basis functions & their gradients (derivatives) at quadrature points
  84. ph  = evaluateBasis(qp{1}, qp{2}, pp, legc);
  85. dph = evaluateBasisGradients(qp{1}, qp{2}, pp, legc, legdc);
  86.  
  87. % Indeces of sides of elements in the mesh  &  number of sides
  88. [s, Ns] = t2si(t,Nn);
  89.  
  90. % Index of global basis function corresponding to (k,j):
  91. % j'th local basis function in k'th element
  92. ind = lbi2gbi(t,s,pp,Nn,Ns,Nel);
  93.  
  94. % Edge function indeces (for setting boundary values later)
  95. xei = edgefunind(pp,t,e,ind);
  96.  
  97. % Parity indeces (-1,+1) for (k,j) = k'th element, j'th (loc.) b. function
  98. par = parityVec(pp,s,t,Ns,Nel,Nb);
  99.  
  100.  
  101.  
  102.  
  103. %% ASSEMBLE
  104.  
  105. % Dimension of the global polynomial space
  106. Np = Nn + Ns*(pp-1) + Nel*(pp-1)^2;
  107.  
  108. % Initialize A & b and find entries by looping over elements
  109. gdph = cell(length(dph),Nel); gqp = cell(2,Nel); Jdets = cell(1,Nel);
  110. b = zeros(Np, 1); A = sparse(Np, Np);
  111. for k = 1:Nel
  112.  
  113.     % Current node indeces and nodes in global coordinates
  114.     tc = t(:,k);
  115.     P = p(:,tc);
  116.    
  117.     % Global quadrature points and f evaluated in them
  118.     gqp(:,k) = F(qp{1}, qp{2}, P);
  119.    
  120.     % Jacobian matrix in qp's (2x2 cell) and determinants (square mat)
  121.     J = JF(P, dph(1:4));
  122.     Jdets{k} = J{1,1}.*J{2,2} - J{2,1}.*J{1,2};
  123.  
  124.     % Gradients of the global basis functions (manual inv. of 2x2 Jacobian)            
  125.     for j = 1:length(dph)
  126.     gdph{j,k} = {(J{2,2}.*dph{j}{1}  -J{2,1}.*dph{j}{2})./Jdets{k}, ...
  127.                 (-J{1,2}.*dph{j}{1}  +J{1,1}.*dph{j}{2})./Jdets{k}};
  128.     end
  129.    
  130.     % Assemble matrix
  131.     for i = 1:Nb
  132.         for j = 1:Nb
  133.             pm = par(k,i)*par(k,j); % plus/minus 1, from parity fix
  134.             Ae = sum(sum( pm*abs(Jdets{k}).*w.* B(gqp(:,k),ph{i},ph{j},gdph{i,k},gdph{j,k}) ));
  135.             A(ind(k,i),ind(k,j)) = A(ind(k,i),ind(k,j)) + Ae;
  136.         end
  137.     end
  138.    
  139.     % Assemble load vector
  140.     for j = 1:Nb
  141.         b(ind(k,j)) = b(ind(k,j)) + sum(sum(par(k,j)*abs(Jdets{k}).*w.* L(gqp(:,k),ph{j},gdph{j}) ));
  142.     end
  143.  
  144. end
  145.  
  146.  
  147.  
  148. %% BOUNDARY CONDITIONS AND SOLVING
  149.  
  150. % Zero-boundary conditions, solve, assemble global solution
  151. xg = zeros(Np,1);
  152. xsi = setdiff(1:Np, xei);   % Complement of boundary functions
  153. xg(xsi) = A(xsi,xsi)\b(xsi);
  154.  
  155.  
  156.  
  157. %% PLOTTING & ERROR ESTIMATION
  158.  
  159. % For more explanation, see the loop in "ASSEMBLY" section
  160. %
  161.  
  162. % Plot points on ref. elem.
  163. npp = 20;
  164. [xloc,yloc] = meshgrid(linspace(-1,1,npp), linspace(-1,1,npp));
  165.  
  166. % corresponding phi values
  167. pph = evaluateBasis(xloc, yloc, pp, legc);
  168.  
  169. figure; hold on;
  170. X = []; Y = []; Zfem = []; Zdxfem = []; Zdyfem = []; Jd = [];
  171. for k = 1:Nel
  172.     tc = t(:,k);
  173.     P = p(:,tc);
  174.    
  175.     % Global plot and quadrature points
  176.     xyg = F(xloc,yloc,P);
  177.    
  178.     % FEM solution values
  179.     solp = zeros(length(xloc));
  180.     solqp = zeros(size(w));
  181.     soldxqp = solqp; soldyqp = solqp;
  182.    
  183.     for i = 1:Nb
  184.         solp = solp + xg(ind(k,i))*par(k,i)*pph{i};
  185.         solqp   = solqp   + xg(ind(k,i))*par(k,i)*ph{i};
  186.         soldxqp = soldxqp + xg(ind(k,i))*par(k,i)*gdph{i,k}{1};
  187.         soldyqp = soldyqp + xg(ind(k,i))*par(k,i)*gdph{i,k}{2};
  188.     end
  189.    
  190.     X = [X gqp{1,k}];
  191.     Y = [Y gqp{2,k}];
  192.     Zfem   = [Zfem solqp];
  193.     Zdxfem = [Zdxfem soldxqp];
  194.     Zdyfem = [Zdyfem soldyqp];
  195.     Jd = [Jd Jdets{k}];
  196.    
  197.     surf(xyg{1}, xyg{2}, solp); % Plot
  198.    
  199. end
  200.  
  201. % Evaluate exact solution (if known)
  202. Zex   = fex(X,Y);
  203. Zdxex = fexdx(X,Y);
  204. Zdyex = fexdy(X,Y);
  205.  
  206. L2err = sqrt(sum(sum( abs(Jd).*repmat(w,1,Nel).*( Zex-Zfem ).^2 )));
  207. L2graderr = sqrt(sum(sum( abs(Jd).*repmat(w,1,Nel).*( (Zdxex-Zdxfem).^2 + (Zdyex-Zdyfem).^2 ) )));
  208. %}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement