function [A,g,xmesh,ucomp] = fe_linear(M,a,c,f) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function [A,g,xmesh,ucomp] = fe_linear(M,a,c,f) % This function uses a Galerkin finite element method with % linear elements to form an approximate solution to the % differential equation % -(a(x) u'(x))' + c(x) u(x) = f(x) for x in (0,1) % with u(0)=u(1)=0. % % The function a should satisfy a(x) \ge a_0 > 0 on (0,1), % and the function c should satisfy c(x) \ge 0 on (0,1). % % Inputs: % M defines the number of mesh points, including the % endpoints of the interval. % a, c, and f are user-defined Matlab functions. % Their input is a row or column vector of x coordinates % in the interval [0,1], and their output is a vector of % values of a(x), c(x), or f(x). % The function a also has a second output argument, a vector of % values of a'(x). % % Outputs: % A is the matrix from which the coefficients of the solution are % computed. % g is the right-hand side of the matrix problem. % xmesh contains the equally-spaced points at which the solution % is computed. % ucomp is the vector of coefficients of the solution in the % finite element basis, equal to the value of the % computed solution at the interior mesh points. % % The method uses the weak formulation of the equation % to compute an approximate solution: % a(u,v) = (f,v) for all piecewise linear functions v % where u(x) = ucomp(1) phi_1(x) + ... + ucomp(M-2) phi_{M-2}(x) % Here, % a(u,v) = int(a(x) u'(x) v'(x) + c(x) u(x) v(x)) dx, % (f,v) = int(f(x) v(x)) dx, % and the limits of integration are [0,1]. % % The phi basis functions are linear hat-functions: % phi_j (x_j) = 1, phi_j (x_k) = 0 for j not equal to k, % and phi_j is zero outside the interval [x_{j-1},x_{j+1}]. % fe_linear.m Dianne P. O'Leary January 2005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initialize some parameters. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% x = linspace(0,1,M); h = x(2); n = M - 2; % n is the number of unknowns. xmesh = x(2:n+1)'; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Compute the matrix and the right-hand side in order % to solve for the coefficients ucomp of the approximate solution. % The matrix is symmetric, made up of 3 diagonals. % The (j,k) element is a(phi_k,phi_j). % The j-th element of the right-hand side is (f,phi_j). % % The data for the main diagonal is stored in diag0. % The data for the first superdiagonal is stored in diag1. % The data for the right-hand side is stored in rhs. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diag0 = zeros(n,1); diag1 = zeros(n,1); rhs = zeros(n,1); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Form the matrix and solve the linear system. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for i=1:n, diag0(i) = quad(@axlin,x(i ),x(i+1),1.e-6,0, h,x(i)) ... + quad(@axlin,x(i+1),x(i+2),1.e-6,0,-h,x(i+2)); diag1(i) = quad(@bxlin,x(i+1),x(i+2),1.e-6,0, h,x(i+1),x(i+2)); rhs (i) = quad(@fxlin,x(i ),x(i+1),1.e-6,0, h,x(i )) ... + quad(@fxlin,x(i+1),x(i+2),1.e-6,0,-h,x(i+2)); end diag1u= [0;diag1(1:n-1)]; A = spdiags([diag1,diag0,diag1u],-1:1,n,n); g = rhs; ucomp = A \ g;