%% FEM vs analytical solution for -(lambda(x) u')' = 0 with Dirichlet BC clear; clc; %% Parameters n = 20; % number of elements (increase for nicer plot) h = 1/n; x = linspace(0,1,n+1)'; % node coordinates % Jump location x0 = 1/sqrt(2); % Piecewise lambda function lambda_fun = @(x) (x < x0).*1 + (x >= x0).*10; %% Assemble FEM matrix and RHS (lifting via u_D(x)=x) A = zeros(n+1,n+1); F = zeros(n+1,1); % Derivatives of linear shape functions are constant on each element phi_prime = [-1/h; 1/h]; for e = 1:n % element nodes nodes = [e, e+1]; xL = x(nodes(1)); xR = x(nodes(2)); % CASE A: no jump inside the element if (xR <= x0) || (xL >= x0) lambda_e = lambda_fun((xL + xR)/2); % constant lambda A_e = lambda_e * (1/h) * [1 -1; -1 1]; % load due to u_D'(x)=1 F_e = [ lambda_e; -lambda_e ]; % CASE B: jump inside the element -> split integrals else h1 = x0 - xL; h2 = xR - x0; % Local stiffness contributions A_e = [ (1*h1 + 10*h2)/h^2 , -(1*h1 + 10*h2)/h^2 ; -(1*h1 + 10*h2)/h^2 , (1*h1 + 10*h2)/h^2 ]; % load vector components F_e = [ (h1 + 10*h2)/h ; -(h1 + 10*h2)/h ]; end % Assemble A(nodes,nodes) = A(nodes,nodes) + A_e; F(nodes) = F(nodes) + F_e; end %% Apply Dirichlet BC: u(0)=0, u(1)=1 % Dirichlet BC: w(0)=0, w(1)=0 A(1,:) = 0; A(:,1) = 0; A(1,1) = 1; A(end,:) = 0; A(:,end) = 0; A(end,end) = 1; F(1) = 0; F(end) = 0; %% Solve FEM w = A \ F; u_fem = x + w; %% Analytical solution with piecewise λ(x) x0 = 1/sqrt(2); J = 1 / (x0 + (1-x0)/10); u_exact = @(x) (x <= x0) .* (J*x) + ... (x > x0) .* ( J*x0 + (J/10)*(x - x0) ); u_an = u_exact(x); %% Plot plot(x,u_fem,'o-','LineWidth',2); hold on; plot(x,u_an,'r--','LineWidth',2); legend('FEM','Analytical','Location','Best'); xlabel('x'); ylabel('u(x)'); title('FEM vs Analytical Solution for (B)'); grid on;