Professional Documents
Culture Documents
Table of contents
Previous Matlab knowledge ..............................................................................2 Some basics .....................................................................................................2 Creating vectors and matrices ......................................................................2 Other ways of generating vectors and matrices............................................4 Generating sequences .................................................................................4 Diagonals......................................................................................................5 Exercise........................................................................................................6 Length and size ............................................................................................6 Parts of vectors and matrices .......................................................................6 Exercise........................................................................................................8 Exercise........................................................................................................8 Multiplication of vectors, etc........................................................................10 Meshgrid.....................................................................................................11 Gradients ....................................................................................................11 Exercise......................................................................................................13 Copying plots..............................................................................................13 Adding legends...........................................................................................13 Numerical differentiation .................................................................................14 Example .....................................................................................................14 Linear Systems ...............................................................................................15 Exercise......................................................................................................16 Iterative methods ............................................................................................16 Convergence ..............................................................................................18 Numerical Integration......................................................................................19 Trapezoidal rule..........................................................................................19 Ordinary differential equations ........................................................................20 Eulers method first-order ODE................................................................20 Interval-halving ...........................................................................................22 The Finite Difference Method..........................................................................23 Explicit method ...........................................................................................23 Recording results........................................................................................25 Stability .......................................................................................................25 Implicit BTCS scheme ................................................................................26
SOME BASICS
Try all the following by entering the code given at the command line. Note that much of the code can be copied and pasted. Everything below is relevant to the exercises in this module so make sure you understand it. NOTE: VERY IMPORTANT There are two main ways of running code in Matlab: you can enter commands at the command line or you can put them in a script file and run them. The command line is very useful for trying things out: type in a command (or copy and paste it), press Enter, and you see immediately what happens. If you are doing something, however, that requires a number of lines of code (say >2) then you should put them in a script file.
NOTE: Semi-colons in Matlab A semi-colon in Matlab tells it to move on to a new row. Matrices can be entered in the same way as vectors. For example c = [1 2; 3 4; 5 6] produces a matrix with the values: 1 2 3 4 5 6 See what happens if you enter c = c' Note that transposing a matrix is different to rotating it. What do you think will happen if you enter the following two commands? x = [1 2 3] y = [x x] First try and work out the answer; then enter the two commands and see what happens. Similarly try x = [0 x] and see what happens to x. This process of sticking things together to form something larger is known as Concatenation. Also try x = [x ; x] What if you have two vectors q = [3 4 3 6 5 7] r = [1 2 3 7 5 9] and you want to join them to form this matrix? 1 3 2 4 3 3 7 6 5 5 9 7 Note that matrices can be concatenated together in the same way as vectors and scalars so long as all the matrices to be joined have the same number of rows. If you enter a = [1 2 3]
MM281 Notes. Dr. Alan Kennedy, 2011
b = [1 2; 3 4] and then try c = [a b] you will get an error message because the numbers of rows in a and b are not the same. NOTE: Error Messages in Matlab Note that these notes do not explain the error messages in Matlab. It is important, however, that you get used to the common messages. If you get an error message and cannot understand it then ask your lecturer to explain it to you.
Generating sequences
Entering p = 1:5 will create a 15 vector with the values 1 2 3 4 5
You can read the : in this context as to so 1:5 is read as one to five. Entering q = 3:2:9 will create a vector with the values 3 5 7 9 You can read 3:2:9 as three to nine with step-size two. Note that such a vector will not necessarily contain the end value. For example, check what this does: q = 3:0.3:4 This can be helpful in some cases because you dont have to worry about what exact value the end-value should have. To create a column vector with the values 1:10 simply use the transpose operator. Try this note that you will have to use brackets. Try creating a vector with the values 1 0.8 0.6 0.4 0.2 0
Diagonals
In real problems, matrices often have similar values on the diagonals. To enter the following matrix: 2 0 0 0 0 3 2 0 0 0 A = 0 3 2 0 0 0 0 3 2 0 0 0 0 3 2 using A = [2 0 0 0 0; 3 2 0 0 0; 0 3 2 0 0, etc. would be very time consuming. If the matrix was 100100 then this method of entry would not be practical! You can use the diag function to create a matrix with given values on a diagonal. For example x = diag(ones(1,3),0) takes the vector given (in this case one with three ones) and creates a square matrix with those values on the main diagonal (specified by the zero). Check what happens if you enter x = diag(ones(1,3),1) or x = diag(1:3,-1) The matrix A above has 5 twos on diagonal 0 and 4 threes on diagonal 1. You could use
A = diag(zeros(1,5)+2,0) + diag(zeros(1,4)+3,-1) to create it. Make sure you understand this line of code fully before you carry on. Note that A = diag(zeros(1,5)+2,0) + diag(zeros(1,5)+3,-1) will give you an error (since the second matrix in the addition is larger than the first one). This is an easy mistake to make. Enter the line and see what error message Matlab gives you. Now try creating the following matrix in a similar way: 1 4 0 0 0 0 0 0 2 1 4 0 0 0 0 0 0 2 1 4 0 0 0 0 0 0 2 1 4 0 0 0 B= 0 0 0 2 1 4 0 0 0 0 0 0 2 1 4 0 0 0 0 0 0 2 1 4 0 0 0 0 0 0 2 1
Exercise
Create an NN matrix of twos where the value of N has been specified beforehand. For example if you first enter N = 3 your code should create a 33 matrix of twos. If you entered N = 10 first, however, then the same code should create a 1010 matrix of twos. NOTE: PUT THIS CODE IN A SCRIPT FILE.
q = [5 4 2 6 1 5 9] and the matrix w = [2 9; 7 8; 5 4] Now q(3) is the third value in vector q. Similarly w(3) is the third value in matrix w this may be confusing but dont worry, this is not the normal way to access part of a matrix. You can read a value, e.g. x = q(4) or change an individual value, e.g. q(5) = 3 Note that it is more common to access values in matrices by specifying both the row and the column, e.g. w(1,2) gives you the value in w on row 1 and column 2. As well as accessing individual values you can also read or change sections of a vector or matrix. For example q(1:3) gives the first 3 values in q. What does q(2:2:6) give? What does q([1 3 5]) give? What is q(1:3) + q(2:4) What will q(2:length(q)) give? A common error message you will get is Matrix dimensions must agree. if you try to add/subtract/etc. two matrices/vectors that dont have the same size. For example, try q(1:3) + q(2:5) In the case of matrices, things are slightly more complicated. Let m = rand(4,4) What if you just want the first column? You can get this using m(:,1)
In this context, the : can be read as all the rows. This then gives you the values in all the rows in column 1. Similarly m(1,:) gives the first column. What do the following give? m(1:2,:) m([1 4],:) m(1:2,2:3) Often a matrix is most easily created in more than one step. For example 2 0 0 0 0 3 2 0 0 0 A = 0 3 2 0 0 0 0 3 2 0 0 0 0 0 2 is very similar to one given above it only differs by one value. You could create this using A = diag(zeros(1,5)+2,0) + diag(zeros(1,4)+3,-1) A(5,4) = 0 The first line creates a matrix with five 2s on the main diagonal and four 3s on the first lower diagonal. The next line changes one of those 3s to a zero.
Exercise
Create an NN matrix which has 5s on diagonal zero and 3s on diagonal 1 with the exception of the first row and the first column which should be all 1s. For example, if N = 5 you should get: 1 1 1 1 1 1 5 3 0 0 A = 1 0 5 3 0 1 0 0 5 3 1 0 0 0 5 Hint: do this with more than one command.
Exercise
Enter the following lines: x = 0:0.1:6; y = sin(x); plot(x, y) These create a vector of x points, calculate the sine of those points, and plot one against the other. Now assume you are measuring something that varies
sinusoidally. In many situations when something is measured, the readings differ from the actual values due to noise in the system. For example, when measurements are taken using an electrical system, electrical interference can occur just like with radio or television signals. Enter the following lines: ny = y+randn(1,length(y))/5; plot(x,ny) These add random noise to the y vector (see Figure 1). Note that randn is different to rand in that the random numbers produced have a mean of zero and are normally distributed like much real noise.
1.5
0.5
-0.5
-1
-1.5 0
You can smooth data like this by using a moving average. This averages consecutive points. In a 3-point moving average, overlapping sets of 3 points are averaged the result is a set of smoothed points. If the original values are numbered ny1 to nyN and the smoothed points are Sy1 to SyN, then Syn = (nyn1 + nyn + nyn+1)/3 so, for example, the second smoothed point is the average of the first 3 original points, and so on. Note that Sy1 and SyN cannot be determined in this way. In this exercise, let Sy1 = ny1 and SyN = nyN. Using the values in ny, calculate the equivalent vector of smoothed values and plot them against x. Note that you should start by calculating points Sy2 to SyN1 Sy(2:length(ny)-1) = and then set the end values. Figure 2 shows values the data in Figure 1 after smoothing using a 3-point moving average. Note that moving averages using more points will increase the smoothness of the data but may distort it.
4 3 2 1 0 -1 -2 -3 -4 0
10
Meshgrid
The surf instruction allows you to plot a surface. For example, lets plot
f ( x, y ) = x 2 + y 2
The ranges for both x and y will be [-1, 1]. We can start by getting x and y vectors that will hold the x and y values at which the surface points will be calculated: x = -1:0.1:1 y = -1:0.1:1 The x and y values both have step-sizes of 0.1. A smaller step-size will produce a more accurate result but will take more time and memory space. Each of these vectors contains 21 values. If you calculate f = x.^2 + y.^2 then you end up with a 121 vector. This is no use for plotting a surface. What surf needs is values of f(x,y) for every possible combination of x and y value i.e. a 2121 matrix in this case. The way to do this is to use the meshgrid function. If you give it two vectors, one of x values and one of y values, then it outputs two matrices of the right size, one of x values and one of y values. Enter [X, Y] = meshgrid(x,y) Check the output and make sure you know what it has done. Now you can calculate f = X.^2 + Y.^2 which gives a 2121 matrix. You can plot f(x, y) against x and y using surf(x, y, f) Note that you must give surf vectors (not matrices) containing the x and y values (i.e. x and y rather than X and Y in this case). Sometimes such results can be viewed more clearly using contour plots. Try contour (x, y, f) and contourf (x, y, f) You can add a colour bar to a contour plot by entering colorbar Try these.
Gradients
Following on from the last exercise, you will now calculate the gradients of the surface. The gradient at any point on a surface is a vector the direction of the vector equals the direction of the gradient at that point and the magnitude of the vector equals the magnitude of the slope in that direction.
11
The gradient vector is made up of the slope in the x-direction and the y-direction. These can be calculated using the gradient function. Enter the line [dx, dy] = gradient (f, 0.1, 0.1) This calculates two matrices one that contains a numerical estimate of the slope in the x-direction at all points, and one with the equivalent values for the ydirection (i.e. estimates of the partial derivatives
f x
and
f y
).
Note that you have to tell the gradient function the spacing of the values in the x and y directions both 0.1 in this case since it needs that information to estimate the derivatives. Plot the contours of f again contour (x, y, f) Now enter hold on Then enter quiver(x,y,dx,dy) which will create an arrow or quiver plot on top of the contours. This shows the gradient vectors. Note that the arrows always point in the direction of positive slope (i.e. uphill). Use surf (x, y, dx) and surf (x, y, dy) to view the two partial differentials. Do these make sense? are they what you would expect? NOTE: Hold On Normally when you plot something a new figure window appears and the plot is shown in it. This is then the active figure. If you use another plot command, the second plot also goes into this active figure but the first one is removed. If you want to things to be plotted in the one figure, first plot one of them, then run the hold on command, and then plot the second one. NOTE: Figure What if you want to plot two things in two separate figure windows? First plot the first one, then run the figure command, then plot the second one. To illustrate hold on and figure, enter the following code: x = 1:0.1:10; y = sin(x) z = cos(x) plot(x,y) hold on plot(x,z)
12
and see what it does. Then enter the following code: figure plot(x,y) figure plot(x,z) and see what it does. How many figures do you have now?
Exercise
Plot the contours and the gradients of the function f(x, y) = x2 + xy y2 over the range x = [1, 1] and y = [1, 1] with step sizes of 0.05 in both directions. You should end up with something like that shown in Figure 3.
1 0.8 0.6 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8 -1 -1 -0.8 -0.6 -0.4 -0.2 0 0.2 0.4 0.6 0.8 1
Copying plots
When you create a plot, the resulting figure window has a menu. Under EDIT there are two options of interest, COPY FIGURE and COPY OPTIONS. For copying into Word or other applications, you should first change the options so that Transparent background and Preserve information are selected then simply copy the figure and paste it where you want it.
Adding legends
Enter the following:
13
plot([1 2 3], [3 2 1]) hold on plot([1 2 3], [4 1 6],'r') Remember that hold on means that the first plot will not be removed when the second is shown: i.e. they will both appear together. You can now add a legend to a plot indicating what each line is (as in Figure 4). For example, enter legend('First', 'Second')
6 5.5 5 4.5 4 3.5 3 2.5 2 1.5 1 1 1.2 1.4 1.6 1.8 2 2.2 2.4 2.6 2.8 3 First Second
Note that the legend can be moved after it has appeared. Alternatively add a third value to indicate where you want it. For example legend('First', 'Second', 2) will put the legend in the top left-hand corner (3 indicates bottom-right and 4 indicates bottom-left).
NUMERICAL DIFFERENTIATION
The differential of a function f(x) at x can be estimated using the formula
f ( x )
f ( x + x ) f ( x ) x
where x is the step-size used. The smaller x is, the more accurate the result will be but only up to a point. After that, as x is decreased, round-off errors make the estimate less accurate.
Example
Estimate df(3)/dx where f(x) = sin(x). This can be done with the following commands: x = 3; Dx = 1e-5; dfdx = (sin(x+Dx)-sin(x))/Dx This code is not well written. To see why, consider what you would have to do to change it so that the function is f(x) = sin(x2+3x). The third line would become dfdx = (sin((x+Dx)^+3*(x+Dx))-sin(x^2+3*x))/Dx
14
This is messy, difficult to read and the chances of making a mistake in the code are significant. Here is a much better version: x_value = 3; Dx = 1e-5; x = x_value; fx = sin(x); x = x_value + Dx; fx_plus_Dx = sin(x); dfdx = (fx_plus_Dx- fx)/Dx Enter this code and test it. Now change it so that the function is f(x) = sin(x2+3x). It should be much easier to change and the chances of making a mistake are reduced significantly. There is a better, neater, way of doing this. It involves writing your own function in Matlab. This will not be covered in this module. Now you will investigate the effect of the step-size, x, on the approximation. To do this, add a loop to the code above so that it becomes: x_value = 3; for i = 1:15 Dx = 10^(-i); x = x_value; fx = sin(x); x = x_value + Dx; fx_plus_Dx = sin(x); dfdx = (fx_plus_Dx- fx)/Dx end This will display the estimate obtained with x = 0.1, with x = 0.01, and so on down to x = 1015. The exact answer is, in this case, 0.989992496600445 What happens to the error in the estimate as x is decreased?
15
Exercise
Solve the following system of equations:
x + 2 y + 3 z = 12 4 x + 5 y + 6 z = 33 x + 2 y 2z = 2
Firstly enter the coefficient matrix, A, and the right-hand vector, b. You can now solve the problem using the inv (matrix inverse) function: x = inv(A)*b This gets a solution but it is not the most efficient method for doing so. This doesnt matter for a small number of equations but this method may be very slow if the number of equations is large. A better way is using the left matrix divide operator \ i.e. the backslash operator: x = A\b Why is this more efficient? Because it takes more effort to find the inverse of an NN matrix than it takes to find the solution of N linear equations. Also, when you use the backslash operator, Matlab attempts to pick the method that best suits the particular set of equations this can give big savings as will be seen below.
2T 2T + =0 x 2 y 2
Consider a square plate. You wish to calculate the temperature at a grid of points (or nodes) as shown in Figure 5. The temperature along the left-hand side is fixed at 100 degrees as indicated. That along the bottom side is at 50 degrees. The temperatures at the other two sides is also known and shown. Note that the temperatures at the four corners do not matter in the calculations you will perform.
16
100
100
50
You will use a finite difference method to estimate the temperature at all the nodes. The approximation is that the temperature at any node is simply the average of the temperatures at the four nodes surrounding that node. A node and its surrounding nodes are shown in Figure 6.
Clearly this formula cannot be applied to the nodes at the edges of the plates (the boundary nodes) but this doesnt matter since the values there are already known. The plate is 1 metre by 1 metre. You will solve the problem using a 2121 grid. This means that the points are 0.05 metres apart in both the x and y directions. Create a new script file. You will use the Jacobi method to solve the equations. This requires an initial guess for the unknowns. In this case start with the temperature at all the internal nodes (i.e. nodes away from the boundaries) set to zero, i.e. N = 21; T = zeros(N,N); T(1,:) = 50; T(N,:) = 100; T(:,1) = 100; T(:,N) = 0; Note that row 1 is assumed to be at the bottom and row N at the top. The method is an iterative one so add a loop below this that repeats 100 times for i = 1:100 end Within the loop you need to calculate the temperature at all the internal nodes by simply applying the formula that the temperature at each node is the average of the temperatures at the four nodes surrounding it.
17
You can only calculate the temperature for the internal nodes so the line within the loop will start with T(2:N-1,2:N-1) = If you entered T(2:N-1,2:N-1) = T(1:N-2,2:N-1); then this would set the values in the middle to be equal to those 1 node below. Similarly T(2:N-1,2:N-1) = (T(1:N-2,2:N-1) + T(3:N,2:N-1))/2; would set the node temperature equal to the average of that at the nodes above and below. The full line that needs to go in the loop is T(2:N-1,2:N-1) = (T(1:N-2,2:N-1) + T(3:N,2:N-1) + T(2:N1,1:N-2) + T(2:N-1,3:N))/4; Take time to understand this. Now you need to add lines after the loop to create a surface plot of the solution with the correct x and y values. Note that the difference between consecutive x and y values, i.e. x and y, is, since the problem space is 1 metre 1 metre, x = y = 1/(N1)
Convergence
At the moment your program only does 100 iterations. Is that enough? Is it too many? In practice, the number of iterations required depends on the accuracy required. You will now change your program so that it runs until
Tni Tni 1
is satisfied for all nodes. Tni is the temperature at node n at iteration i. The value of determines the accuracy of the answer and needs to be specified in your program e = 1e-5; Within the loop you need to compare the new values in T with the previous values. The problem is that when you calculate the new values the old ones are lost. The answer is to store the old values first. Add the following line at the correct position in your program: PreviousT = T;
18
Once the new values are calculated you can compare the two. Add the following code at the appropriate location: if max(max(abs(T-PreviousT))) <= e i break end The second line will output the number of the iteration when the solution converged. The break command will cause the loop to stop. Run the program. Note that the correct level of convergence may not be achieved with 100 iterations so adjust the loop so that it goes from 1 to 5000. How many iterations are required?
19
To calculate the integral between the limits, simply sum the N In values. All of this can be done with one line. Add the following code: I = sum( (fx(1:N)+fx(2:N+1))*h/2 ); I Now run the program. The result should be: 1.41609963133789 The analytical solution is 1.41614683654714 Calculate the absolute error. Determine the order of the accuracy.
The Week 6 test will be based on the material covered up to this point. YOU CAN NOW DO Exercise 3 OF Project 2
ORDINARY DIFFERENTIAL EQUATIONS
Eulers method first-order ODE
Create a new script file called euler1. You will write a program to solve
dy = yx dx
over the range x = [0, 10] with initial condition x(0) = 3. Enter the following code: h = 0.1; x_start = 0; x_end = 10; N = 1+(x_end-x_start)/h; %Set x(1) and y(1) x = x_start; y = 3; for i = 2:N x(i) = x(i-1) + h; end
20
This specifies the step-size (h) and the limits on x. It then calculates the number of points to be calculated i.e. the number of steps plus one. The program will generate two vectors, one containing the x-values (x) and one containing the y-values (y). The line x = x_start; puts the first x-value into x. The first y-value is known from the initial condition and the next line puts that in y. Note that these lines could be replaced by x(1) = x_start; y(1) = 3; but the lines that are there do something else they clear out any values that already exist in x and y. The line x(1) = x_start; changes the first value but leaves any other existing values alone. The line x = x_start; makes x a new vector with only one value in it. The loop goes from 2 to N. This is because you already know the first value in the solution. At the moment the one line in the loop simply calculates the current x-value. All x-values will be in x once the loop is finished. You can read the line x(i) = x(i-1) + h; as the current x-value is the previous x-value plus h. You now need to add a line within the loop to calculate the y-values. Using Eulers method to solve the given ODE, the current y-value will be the previous yvalue plus h times the previous y-value minus the previous x-value. Be careful with brackets. Now add the following to plot the result: figure plot(x,y,'k') xlabel('x') ylabel('y') title ('Solution of dy/dx = y-x with y(0) = 3') If you have done it correctly you should get a graph like that shown in Figure 7.
21
x 10
2.5
1.5
0.5
0 0
5 x
10
The figure command is important here. This creates a new figure window each time the code is run. This means that if you run the program a few times with different settings, all the graphs remain available to you. Without this, each new plot would simply overwrite the previous one. What if you wanted to compare the results from two runs of the program? e.g. with two different step-sizes. Take out the figure command. Then add hold on after the line that does the plotting. This means that when you run the program the first time, the results will be plotted as usual. When you run it the second time, the new plot wont overwrite the previous one (because hold is on) instead the new plot will appear with the previous one. Try this out. Check the value of y(10) i.e. the last value in y by entering y(N) at the command line. You should get 2.757222467964455e+004 Repeat the calculation with h = 0.01 and check y(10) again. You will see that the solution is highly dependent on the step-size used.
Interval-halving
You have calculated y(10) using a step-size of 0.1: 2.757222467964455e+004 Now repeat the calculation using a step-size of 0.05. You should get 3.459616163031999e+004 You can use these two values to estimate the relationship between the accuracy of y(10) and h. The scheme is of order h so we know that 2.757222467964455e+004 y(10) + c(0.1) where y(10) is the exact solution and we assume c is a constant (but which is actually dependent on x). We also know that 3.459616163031999e+004 y(10) + c(0.05)
22
Combining these two so as to eliminate y(10) gives 3.459616163031999e+004 2.757222467964455e+004 c(0.05) and so c 1.404787390135088e+005 or, in other words, the error in the estimate of y(10) is approximately 150000h. To find y(10) to within an accuracy of 1 would require approximately h = 1/150000 or a total of 1.5 million steps!
T 2T =D 2 t x
We will use this to calculate the temperature in a thin uniform rod, insulated so that heat can only flow along its length so that it can be treated as a onedimensional problem. This equation is first-order with respect to time and so, in order to solve for what happens over time, initial conditions are needed i.e. you need to know the initial temperature of the rod. In this case assume it is zero everywhere except at the ends. The PDE is second-order with respect to x and so two pieces of information are needed. The boundary conditions are that the rod is held at 50 degrees at one end and at 100 degrees at the other. The rod is 1 metre long, i.e. the boundary conditions are
Create a new script file and add in the following code: N = 21; D = 0.1; Dx = 1/(N-1); x= 0:Dx:1; Dt = 0.01; %Initial conditions T = zeros(1,N); T(1) = 50; T(N) = 100;
23
This sets up the value of D, the number of nodes, and the time step (t) to be used in the calculation. It also calculates the node spacing (x) and creates a vector for the initial temperature at each node and another for the x-positions of each node. Now add a loop to go through 100 time steps with i going from 1 to 100 i.e. initially you will run the model for 100 time steps (i.e. for 1 second). Within the loop you will have to calculate T(2:N-1) for each time step i.e. the temperature at all the internal nodes. The FD equation to be used (the FTCS forward-time, centred-space scheme) is
k +1 n
T = kTn +
where k is the number of the time step and n is the number of the node. The line inside the loop will implement this equation and will be of the form T(2:N-1) = T(2:N-1) + Complete this line. If the program is run now nothing will appear. You could plot T against x after the loop but this will not show you what happens over time. Instead lets get it to plot the temperature along the bar at each time step. First add the line figure('DoubleBuffer','on') before the loop. The setting specified will lead to flicker-free animation remove it once the program works to see the effect. Now add plot(x,T,'k') inside the loop. You will find that if you run the program, you only see what is plotted at the end. This is because plot is given a low priority compared with the rest of your code plotting is only done when the code is finished. To get it to plot at each time step add drawnow after the plot line. You should see the graph change until it reaches a state as shown in Figure 8.
100 90
80
70
60
50
40
30 0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
24
One problem is that the graph still flickers as a result of the vertical axis limits changing. You can solve this problem by adding axis([0 1 0 100]) just before drawnow. This sets the horizontal axis limits to 0 and 1 and the vertical axis limits to 0 and 100 each time. Run it again.
Recording results
Lets record the temperature at the mid-point as it changes over time. Add the line mid_T(i) = T(ceil(N/2)); within the loop note that the ceil function rounds up to the nearest integer and so ceil(N/2) will be the number of the central node whether N is odd or even and figure plot(mid_T) after the loop. If you zoom in on the graph you will see that the value remains at zero for the first 10 time steps. This is because of the method being used. In the explicit scheme the temperature at each node is calculated using the values on either side from the previous time step. This means that heat can only travel at a maximum speed of 1 node per time step and therefore it takes 11 time steps before the temperature in the middle rises above zero.
Stability
The accuracy of the results depends on the node spacing, on the time step, and on how quickly the temperature is changing. As the solution approaches a steady-state (youll see that it does if you run the model for 5 seconds instead of 1) the temperature is changing very little, and so, for a given accuracy, you could use a much longer time step than is needed initially. The problem is, however, that the FTCS scheme is conditionally stable. If you change Dt to 0.02 you will see that it is unstable for the given D and x settings. This means that, even when the temperature is changing slowly, you cannot use a long time step. Set Dt = 0.01 again and increase the number of nodes to 101 something you might do to get greater accuracy. You will again see that the method is unstable. Stability depends on both x and t decrease the node spacing and you may have to decrease the time step too. In fact, in this case, you will find that stability dictates that the time step must be less than 0.0005 for the given problem with 101 nodes. So increase the number of nodes for increased accuracy (which means more calculations per time step), and you find that the time step must be reduced meaning you also need more time steps! And you cant do anything about it even if the solution is hardly changing from one time step to the next.
25
where
D =
D t x 2
In this equation, the new values are based on the old values but you need to calculate all the new values simultaneously because they depend on each other. The equations for each node can be arranged in tridiagonal matrix form
0 0 0 0 T1 L 1 50 D 1 + 2 D D T T 0 0 L 2 2 0 T3 D 1 + 2 D D 0 T3 L = M M M M M M M 0 TN 1 D 1 + 2 D D TN 1 0 L 0 0 0 1 L 0 100 k TN k +1
where the right-hand vector contains the temperatures at time step k, and the solution vector contains the temperatures at time step k+1. Copy the previous file and save it under a new name. Add a new line to calculate D' Dp = Dt*D/Dx^2; Also, before the loop add code to generate the coefficient matrix. Be careful with the first and last rows. Now look at the matrix equation above. This is of the form
ATk +1 = Tk
where Tk is the column vector of temperature values at time step k. Knowing the initial temperatures, these equations can be solved to find those at time step 1, and so on. Replace the current line for the explicit method with a new line solving these equations (using \). Be careful to make T a column vector. You will find, by adjusting t and N, that this method is unconditionally stable. From looking at the plot of the mid-point temperature it should be clear that it
26
changes from the first iteration. This is because, in the implicit equations, the temperature at every node affects the temperature at every other node. Note that stability does not imply accuracy if you use a large time step and/or a large node spacing then you may get very poor results. Stability does mean, however, that you can use large time steps when the solution is varying slowly and still get reasonable accuracy in your solution.
27