11 april 2005 2D1212 NumProg för T1 VT2005 A Föreläsning 14: Exempel på randvärdesproblem. LU-faktorisering för att lösa linjära ekvationssystem. Kapitel 8 och 5 i Q&S Stationär värmeledning i 1-D Betrakta ett rör av längden L med konstant cylindrisk tvärsnittsarea. I röret finns en vätska som värms upp av en elektrisk spole. Värmen sprider sig i röret och vid jämvikt ges temperaturen T (x) av följande differentialekvation: d dx (κdt dx ) + vρc dt = Q(x) 0 <x<l. (1) }{{}}{{ dx} diffusion konvektion I ekvationen ingår följande konstanter: värmeledningskoefficienten κ vätskans strömningshastighet i x-riktningen v dess densitet ρ och värmekapacitet C. Den elektriska spolen modelleras av funktionen 0 0 x<a Q(x) = Q 0 sin ( x a b a π) a x b 0 b<x L där a och b är sådana att 0 <a<b<l. I ändarna x =0och x = L av röret hålls vätskan vid de konstanta temperaturerna T in och T ut. Detta ger randvillkoren T (0) = T in T(L) =T ut. (2) Uppgiften är nu att skriva ett Matlab-program som beräknar temperaturfördelningen i röret vid jämvikt genom att diskretisera randvärdesproblemet (1) - (2) med andra ordningens finita differenser. Följande värden på i problemet ingåe parametrar ska användas: L =10 a =1 b =3 Q 0 =50 κ =0.5 ρ =1 C =1 T in =0 T ut = 400 v =0 0.1 0.5 1 10. (Fallet v =0svarar mot att bara värmediffusion förekommer.)
Lösning Diskretisera intervallet [0L] med ett konstant steg h = L/N genom att införa noderna x j = jh (0 j N). Temperaturen T är känd i ändpunkterna och i de inre noderna uppfyller T differentialekvationen (1) så vi har T (x 0 )=T in κ d2 T (x dx 2 j )+vρc dt (x dx j)=q(x j ) 1 j N 1 T (x N )=T ut För att approximera derivatorna använder vi andra ordningens noggranna finita differenser: T (x j+1 ) 2T (x j )+T(x j 1 ) = d2 T h 2 dx (x j)+o(h 2 ) 2 T (x j+1 ) T (x j 1 ) 2h = dt dx (x j)+o(h 2 ). Vi inför nu de obekanta T j (0 j N) och beräknar deras värden genom att lösa det linjära ekvationssystemet (det är faktiskt det!): T 0 = T in κ T j+1 2T j +T j 1 h 2 T N = T ut + vρc T j+1 T j 1 2h = Q(x j ) 1 j N 1 Om vi gjort rätt gäller det nu att T j = T (x j )+O(h 2 ) dvs vi har beräknat en andra ordningens noggrann approximation av temperaturen T inodernax j! Det linjära ekvationssystemet kan skrivas T 0 = T in ( κ h vρc 2 2h ) 2κ T j 1 +( }{{} h ) }{{} 2 β α T N = T ut T j +( κ h + vρc 2 2h ) }{{} T j+1 = Q(x j ) 1 j N 1 β + De okända värdena är ju egentligen bara T j för 1 j N 1 och för dessa skriver vi upp det linjära ekvationssystemet på matrisform: α β + 0 0 0... 0 β α β + 0 0... 0 T 1 Q(x 1 ) β T in 0 β α β + 0... 0 T 2 Q(x 2 ) T 3 Q(x 3 ) =................... T 0 0 0... 0 β α N 1 Q(x N 1 ) β + T ut Lösningen består således i att skriva ett Matlab-program som för de olika värdena på v formulerar ovanståe linjära ekvationssystem på matrisform löser det och ritar upp lösningen. Det visar sig att lösningen blir som i följande figur:
400 Stationär värmeledning i 1 D 350 v=0 300 v=0.1 250 Temperatur 200 150 v=0.5 100 v=1 50 0 0 1 2 3 4 5 6 7 8 9 10 x v=10 Figur 1: Temperaturfördelningen i röret vid jämvikt för olika värden på vätskans strömningshastighet v. Diskutera gärna varför graferna ser ut som de gör i de olika fallen! Matlab-program ut: Så här kan ett Matlab-program för att beräkna lösningen se %Stationär värmeledning i 1-D lösning %med finita differensmetoden. % %Magnus Strömgren 050408 clear close all %Problem parametrar---------------------- L=10; a=1; b=3; Q0=50; kappa=0.5; rho=1; C=1; Tin=0; Tut=400; %---------------------------------------- %Diskretisering-------------------------- N=100; h=l/n; x=h*(0:n) ; xin=x(2:-1); %---------------------------------------- for v=[0 0.1 0.5 1 10] %Matrisen A alpha=2*kappa*h^(-2); beta_p=-kappa*h^(-2)+0.5*v*rho*c*h^(-1); beta_m=-kappa*h^(-2)-0.5*v*rho*c*h^(-1);
D=ones(size(xin))*[beta_m alpha beta_p]; A=spdiags(D[-1 0 1]N-1N-1); %Högerledet f f=zeros(size(xin)); index=find((xin <= b) & (xin >= a)); f(index)=q0*sin((xin(index)-a)*pi/(b-a)); f(1)=f(1)-beta_m*tin; f()=f()-beta_p*tut; %Lösningen T=A\f; %Plotta figure(1) hold on plot(x[tin; T; Tut]); gtext([ v= num2str(v)]); xlabel( x ); ylabel( Temperatur ); title( Stationär värmeledning i 1-D );
LU-faktorisering I många av de numeriska metoder vi stött på i den här kursen har man förr eller senare behövt lösa ett linjärt ekvationssystem Ax = b. Tänkt.ex. på finita differensmetoden för randvärdesproblem interpolation/mkm och Newtons metod för system av icke-linjära ekvationer. (Om du inte kommer ihåg repetera!). Därför är det inte förvånande att utvecklandet av bra metoder för att lösa linjära ekvationssystem har varit ett av de viktigaste problemen för forskare och ingenjörer som arbetar med numeriska metoder. Vi har tidigare i kursen löst linjära ekvationssystem med operatorn \ (backslash) i Matlab utan att fundera närmare på det. Men vad gör Matlab egenligen för att beräkna lösningen? Vi ska nu beskriva en algoritm för att beräkna lösningen till Ax = b. Den kallas LU-faktorisering och kommer visa sig vara välbekant från mattekurserna. LU-faktorisering är exempel på en direkt metod för att lösa linjära ekvationssystem. Sådana karaktäriseras av att lösningen beräknas i ett på förhand känt ändligt antal steg. Det finns också iterativa metoder och dessa karaktäriseras av att man försöker beräkna lösningen genom iterationer. Iterationerna avbryts då någon feluppskattning indikerar att man kommit tillräckligt nära lösningen. Om en direkt eller iterativ metod är bäst för ett givet problem Ax = b beror på matrisen A t.ex dess dimension om den är mycket gles eller har andra egenskaper. Triangulära matriser Problemet är att beräkna en lösning till Ax = b dära är en kvadratisk matris av dimensionen n. OmAärlågtriangulär såatta = L = {l ij } med l ij =0för j>i kan vi beräkna lösningen genom enkel framåtsubstitution: x 1 = b 1 l 11 x i = 1 i 1 (b i l ij x j ) l ii j=1 i =2...n. På samma sätt om A är högtriangulär såatta = U = {u ij } med u ij =0för i>j kan vi beräkna lösningen genom bakåtsubstitution: x n = b n u nn x i = 1 u ii (b i n j=i+1 u ij x j ) i = n 1...1. Observera att diagonalelementen l ii respektive u ii måste vara skilda från noll för att det ska fungera. Men detta är ju en förutsättning för att det ska gå att finna en lösning över huvudtaget: diagonalelementen är de triangulära matrisernas egenvärden och om något av dem är noll så är ju matrisen singulär!
Allmänna matriser Så för linjära ekvationssystem vars matriser är triangulära och har nollskilda element på diagonalen kan vi enkelt beräkna lösningen. Men vad gör vi för en allmän matris A? Jo vi kan försöka LU-faktorisera A så att A = LU där L är en lågtriangulär matris med ettor på diagonalen och U är en högtriangulär matris med nollskilda element på diagonalen. Genom att faktorisera A på det här sättet kan vi lösa Ax = b i följande steg: 1. Beräkna faktorerna L och U sådana att A = LU. 2. Lös Ly = b med framåtsubstitution. 3. Lös Ux = y med bakåtsubstitution. Låter LU-faktorisering obekant? Vad sägs om Gausselimination? Det är samma sak! Gausselimination går ju till så att man stegar sig fram kolumn för kolumn och nollar elementen under diagonalen: det är i själva verket matrisen U som man beräknar. I mattekurserna brukar man inte spara eliminationskoefficienterna men det gör vi här: dessa koefficienter är elementen i matrisen L. Algoritmen för LUfaktorisering/Gausselimination kan skrivas: for k =1...n 1 for i = k +1...n l ik = a ik a kk for j = k +1...n a ij = a ij l ik a kj Elementen i matrisen U står efter avslutad genomgång att finna i den högtriangulära delen av A: u ij = a ij för j i. Elementenl ij i matrisen L beräknas i algoritmen för i>j. För de diagonala elementen gäller att l ii =1. Vi noterar också att elementen a kk kallas pivotelement och att inget av dessa får bli noll under beräkningarnas gång om vi ska kunna LU-faktorisera matrisen A med algoritmen ovan. Pivotering Dessvärre kan det under LU-faktorisering av en matris A hända att ett pivotelement blir noll även om A är icke-singulär. Man kan dock visa att om man under faktoriseringens gång hela tiden väljer det till beloppet största elementet i de aktuella raderna som pivotelement så går det att beräkna LU-faktoriseringen för varje icke-singulär matris A. Strategin kallas radpivotering och den modifierade algoritmen blir:
for k =1...n 1 for i = k +1...n Hitta r så att a rk =max i=k...n a ik Byt plats på raderna k och r l ik = a ik a kk for j = k +1...n a ij = a ij l ik a kj Matlab LU-faktorisering med radpivotering är en av de algoritmer som gömmer sig bakom kommandot \ i Matlab. Vilken algoritm som faktiskt används beror som tidigare nämnts på matrisen A. Ibland kan man vilja ha tillgång till faktorerna L och U av en matris. T.ex. om man vill lösa flera linjära ekvationssystem med samma systemmatris A men olika högerled b k. Då behöver man bara faktorisera A en gång och sedan kan man lösa två triangulära ekvationssystem Ly = b k och Ux = y för varje högerled. I Matlab får man LU-faktorerna med kommandot [LU]=lu(A). Matrisen L är lågtriangulär bara om inga radpivoteringar behövdes för att beräkna faktoriseringen. Om radpivoteringar behövdes kan man få ut en lågtriangulär matris L högtriangulär U och permutationsmatrisen P (sådana att PA = LU) genom att skriva [LUP]=lu(A). Ekvationssystemet Ax = b k löses då i följande steg: 1. Beräkna faktorerna L U och P. 2. Lös Ly = P b k med framåtsubstitution. 3. Lös Ux = y med bakåtsubstitution. Nästa föreläsning: LU-faktorisering används för att illustrera önskvärda egenskaper hos algoritmer: effektivitet och noggrannhet. Vi räknar flyttalsoperationer (effektivitet) och introducerar begreppet konditionstal för att diskutera hur avrundningsfelen kan påverka den beräknade lösningen (noggrannhet).