Praktická cvičení z Numerické matematiky
Numerické řešení PDR - 11. týden
- Rovnice vedeni tepla, explicitní schema (Cely skript heateq.m)
du/dt = p d2u/dx2 + f(x,t)
Oblast: [a, b] x [ 0, T]
Data ulohy: (uzivame vektorove operace, zapis operace "s teckou")
p = 0.25; fxt = 'exp( -t)'; u0 = 'sin(pi * x)'; alfa = '0 + 0 * t'; beta = '0 + 0 * t.^2';Oblast QT:
b = 1; a = 0; T = 1;Sit a volba kroku:
n = 10; maxk = 100; h = (b - a) / n; tau = T / maxk;Stabilita:
sigma = p * tau / (h * h); printf('Stabilita %g <= 0.5 ?\n', sigma); if (sigma > 0.5) printf('\nNESPLNENO!\n\nVypocet nestabilni metodou!\n'); else printf('Splneno.\n'); endSit a zdrojovy clen:
xx = a:h:b; tt = 0:tau:T; [xsit, tsit] = meshgrid(xx, tt); x = xsit; t = tsit; f = eval(fxt);Pocatecni a okrajove podminky:
U = 0 * xsit; % << reseni ma stejny rozmer jako xx. x = xx; U(1,:) = eval(u0); t = tt; U(:,1) = eval(alfa); U(:,end) = eval(beta);Vlastni vypocet (cyklem):
for k = 1:maxk, for i = 2:(n-1) U(k + 1, i) = (1 - 2 * sigma) * U(k, i) + sigma * U(k, i + 1) + sigma * U(k, i - 1) + tau * f(k, i); end endGraf reseni:
mesh(xsit, tsit, U); % nebo surf(xsit, tsit, U);
- Vypocet nove casove vrstvy:
for(i = 1; i < n; i++) { xi = a + i * h; ukplus1[i] = (1 - 2 * sigma) * uk[i] + sigma * uk[i - 1] + sigma * uk[i + 1] + tau * f(xi, tk); }
splot "reseni.dat" matrix with lines linecolor 3 linewidth 0.1 % nebo zkracene sp "reseni.dat" matrix w l lc 3 lw 0.1
Zmenime cast vlastni vypocet, nejprve pridame:
Pridame matici prechodu z jedne casove vrstvy na dalsi:
% Matice prechodu z jedne casove vrstvy na dalsi: A = diag((1 - 2 * sigma) * ones(n - 1, 1)); A = A + diag(sigma * ones(n - 2, 1), -1); A = A + diag(sigma * ones(n - 2, 1), 1); % Vliv okrajových podmínek zahrneme do matice: A = [ zeros(n - 1, 1), A, zeros(n - 1, 1) ]; A(1,1) = -sigma; A(end,end) = -sigma;Vlastni vypocet pak realizujeme takto:
for k = 1:maxk, newU = A * U(k,:)' + tau * f(k,2:end - 1)'; U(k+1,2:end - 1) = newU'; end
Oproti maticovemu zapisu zmenime jen matici prechodu a vypocet Matice prechodu z jedne casove vrstvy na dalsi (implicitne, reseni soustavy rovnic):
A = diag((1 + 2 * sigma) * ones(n + 1, 1)); A = A - diag(sigma * ones(n, 1), -1); A = A - diag(sigma * ones(n, 1), 1); A(1,1:2) = [ 1, 0]; A(end,end-1:end) = [0, 1];Vlastni vypocet:
for k = 1:maxk, newU = A \ (U(k,:)' + tau * f(k,:)'); U(k+1,:) = newU'; end