|
1 | | -function u = cnPDE(u0,alpha,beta,tEnd,dx,gamma,L,t0) |
2 | | -% Solve the 1D heat equation u_t = gamma*u_{xx} on a rod of length L |
3 | | -% using the Crank-Nicolson method |
4 | | -% u(t,0) = alpha(t) |
5 | | -% u(t,L) = beta(t) |
6 | | -% u(t0,x) = u0 |
7 | | -% The desired spatial resolution is dx |
8 | | -% Output is u = u(tEnd,x_m), a vector of values on the mesh points |
9 | | - |
10 | | -% Define dt with reference to both error and stability concerns |
11 | | -% Optimal dt for stability |
12 | | -dtOpt = dx; |
13 | | -% Forcing an integer numbers of dt steps that terminate at tEnd |
14 | | -dt = tEnd/ceil((tEnd-t0)/dtOpt); |
15 | | - |
16 | | -% Set up the helper values for defining the required matrices |
17 | | -numRows = L/dx-1; |
18 | | -mu = gamma*dt/(dx^2); |
19 | | -baseDiag = ones(1,numRows); |
20 | | - |
21 | | -% % Define modA for the explicit updating rule |
22 | | -% % modA-I = (A-I)/2, where I is the identity matrix |
23 | | -modA = eye(numRows); |
24 | | - |
25 | | -% % Define modB for the implicit updating rule |
26 | | -% % modB-I = (B-I)/2, where I is the identity matrix |
27 | | -modB = eye(numRows); |
28 | | - |
29 | | -% Initialize bAvg = b^(j)+b^(j+1) as a vector of zeros |
30 | | -bAvg = zeros(numRows,1); |
31 | | - |
32 | | -% Define a spatial mesh vector |
33 | | -xVals = linspace(0,L,round(L/dx)+1); |
34 | | - |
35 | | -% Initialize the output to the interior points of u0 |
36 | | -u = u0(2:end-1); |
37 | | - |
38 | | -% To visualize the outputs |
39 | | -p = plot(xVals,u0,"LineWidth",4); |
40 | | -ax = p.Parent; |
41 | | - |
42 | | -% Set the y limits to reasonable fixed values |
43 | | -minAlpha = min(alpha(0:dt:tEnd)); |
44 | | -maxAlpha = max(alpha(0:dt:tEnd)); |
45 | | -minBeta = min(beta(0:dt:tEnd)); |
46 | | -maxBeta = max(beta(0:dt:tEnd)); |
47 | | -yLower = min([ax.YLim(1),minAlpha,minBeta]); |
48 | | -yUpper = max([ax.YLim(2),maxAlpha,maxBeta]); |
49 | | -scale = (yUpper-yLower)*0.05; |
50 | | -ax.YLim = [yLower-scale yUpper+scale]; |
51 | | - |
52 | | -title("Solving $\frac{\partial u}{\partial t} = \gamma \frac{\partial^2 u}{\partial x^2}$","Interpreter","latex") |
53 | | -subtitle("$t=0$","Interpreter","latex") |
54 | | -xlabel("$x$","Interpreter","latex") |
55 | | -ylabel("$u$","Interpreter","latex") |
56 | | - |
57 | | -% Compute new values for halfB*u^(j+1)-b^(j+1) = halfA*u^(j)+b^(j) |
58 | | -% Loop over timesteps to reach tEnd |
59 | | -for j = 0:(tEnd/dt - 1) |
60 | | - % % Fix the values of bAvg for this iteration here |
61 | | - |
62 | | - % % Sove for the new value of u |
63 | | - |
64 | | - % To visualize the outputs |
65 | | - hold on |
66 | | - delete(ax.Children(1:end-1)); |
67 | | - plot(xVals,[alpha((j+1)*dt);u;beta((j+1)*dt)],"SeriesIndex",2,"LineWidth",4) |
68 | | - subtitle("$t = $"+dt*(j+1)) |
69 | | - drawnow |
70 | | - pause(0.1) |
71 | | - hold off |
72 | | - % End visualization code |
73 | | -end |
74 | | - |
75 | | -end |
| 1 | +function u = cnPDEu0(u0,alpha,beta,tEnd,dx,gamma,L,t0) |
| 2 | +% Solve the 1D heat equation u_t = gamma*u_{xx} on a rod of length L |
| 3 | +% using the Crank-Nicolson method |
| 4 | +% u(t,0) = alpha(t) |
| 5 | +% u(t,L) = beta(t) |
| 6 | +% u(t0,x) = u0 |
| 7 | +% The desired spatial resolution is dx |
| 8 | +% Output is u = u(tEnd,x_m), a vector of values on the mesh points |
| 9 | + |
| 10 | +% Define dt with reference to both error and stability concerns |
| 11 | +% Optimal dt for stability |
| 12 | +dtOpt = dx; |
| 13 | +% Forcing an integer numbers of dt steps that terminate at tEnd |
| 14 | +dt = tEnd/ceil((tEnd-t0)/dtOpt); |
| 15 | + |
| 16 | +% Set up the helper values for defining the required matrices |
| 17 | +numRows = L/dx-1; |
| 18 | +mu = gamma*dt/(dx^2); |
| 19 | +baseDiag = ones(1,numRows); |
| 20 | + |
| 21 | +% % Define modA for the explicit updating rule |
| 22 | +% % modA-I = (A-I)/2, where I is the identity matrix |
| 23 | +modA = eye(numRows); |
| 24 | + |
| 25 | +% % Define modB for the implicit updating rule |
| 26 | +% % modB-I = (B-I)/2, where I is the identity matrix |
| 27 | +modB = eye(numRows); |
| 28 | + |
| 29 | +% Initialize bAvg = b^(j)+b^(j+1) as a vector of zeros |
| 30 | +bAvg = zeros(numRows,1); |
| 31 | + |
| 32 | +% Define a spatial mesh vector |
| 33 | +xVals = linspace(0,L,round(L/dx)+1); |
| 34 | + |
| 35 | +% Initialize the output to the interior points of u0 |
| 36 | +u = u0(2:end-1); |
| 37 | + |
| 38 | +% To visualize the outputs |
| 39 | +p = plot(xVals,u0,"LineWidth",4); |
| 40 | +ax = p.Parent; |
| 41 | + |
| 42 | +% Set the y limits to reasonable fixed values |
| 43 | +minAlpha = min(alpha(0:dt:tEnd)); |
| 44 | +maxAlpha = max(alpha(0:dt:tEnd)); |
| 45 | +minBeta = min(beta(0:dt:tEnd)); |
| 46 | +maxBeta = max(beta(0:dt:tEnd)); |
| 47 | +yLower = min([ax.YLim(1),minAlpha,minBeta]); |
| 48 | +yUpper = max([ax.YLim(2),maxAlpha,maxBeta]); |
| 49 | +scale = (yUpper-yLower)*0.05; |
| 50 | +ax.YLim = [yLower-scale yUpper+scale]; |
| 51 | + |
| 52 | +title("Solving $\frac{\partial u}{\partial t} = \gamma \frac{\partial^2 u}{\partial x^2}$","Interpreter","latex") |
| 53 | +subtitle("$t=0$","Interpreter","latex") |
| 54 | +xlabel("$x$","Interpreter","latex") |
| 55 | +ylabel("$u$","Interpreter","latex") |
| 56 | + |
| 57 | +% Compute new values for halfB*u^(j+1)-b^(j+1) = halfA*u^(j)+b^(j) |
| 58 | +% Loop over timesteps to reach tEnd |
| 59 | +for j = 0:(tEnd/dt - 1) |
| 60 | + % % Fix the values of bAvg for this iteration here |
| 61 | + |
| 62 | + % % Sove for the new value of u |
| 63 | + |
| 64 | + % To visualize the outputs |
| 65 | + hold on |
| 66 | + delete(ax.Children(1:end-1)); |
| 67 | + plot(xVals,[alpha((j+1)*dt);u;beta((j+1)*dt)],"SeriesIndex",2,"LineWidth",4) |
| 68 | + subtitle("$t = $"+dt*(j+1)) |
| 69 | + drawnow |
| 70 | + pause(0.1) |
| 71 | + hold off |
| 72 | + % End visualization code |
| 73 | +end |
| 74 | + |
| 75 | +end |
0 commit comments