Cara terbaik untuk melakukan ini adalah (seperti yang Anda katakan) hanya menggunakan definisi kondisi batas periodik dan mengatur persamaan Anda dengan benar dari awal menggunakan fakta bahwa . Bahkan, lebih kuat lagi, kondisi batas periodik mengidentifikasi x = 0 dengan x = 1 . Karena alasan ini, Anda hanya boleh memiliki salah satu dari poin ini di domain solusi Anda. Interval terbuka tidak masuk akal ketika menggunakan kondisi batas periodik karena tidak ada batas .u(0)=u(1)x=0x=1
Fakta ini berarti Anda tidak boleh menempatkan titik pada karena sama dengan x = 0 . Diskritisasi dengan N + 1 poin, Anda kemudian menggunakan fakta bahwa menurut definisi, titik di sebelah kiri x 0 adalah x N dan titik di sebelah kanan x N adalah x 0 .x=1x=0N+1x0 xNxN x0
PDE Anda kemudian dapat didiskresi dalam ruang sebagai
∂∂t⎡⎣⎢⎢⎢⎢x0x1⋮xN⎤⎦⎥⎥⎥⎥=1Δx2⎡⎣⎢⎢⎢⎢xN−2x0+x1x0−2x1+x2⋮xN−1−2xN+x0⎤⎦⎥⎥⎥⎥
Ini dapat ditulis dalam bentuk matriks sebagai
mana
A=[ - 2 1 0 ⋯ 0 1 1 - 2 1 0 ⋯ 0
∂∂tx⃗ =1Δx2Ax⃗
A=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢−21011−2⋱⋯001⋱⋱0⋯⋯0⋱⋱100⋯⋱−21101−2⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.
Tentu saja tidak perlu untuk benar-benar membuat atau menyimpan matriks ini. Perbedaan yang terbatas harus dihitung dengan cepat, berhati-hati untuk menangani poin pertama dan terakhir secara khusus sesuai kebutuhan.
∂tu=∂xxu+b(t,x)
x∈[−1,1)uRef(t,x)=exp(−t)cos(5πx)b(t,x)=(25π2−1)exp(−t)cos(5πx)
clear
% Solve: u_t = u_xx + b
% with periodic boundary conditions
% analytical solution:
uRef = @(t,x) exp(-t)*cos(5*pi*x);
b = @(t,x) (25*pi^2-1)*exp(-t)*cos(5*pi*x);
% grid
N = 30;
x(:,1) = linspace(-1,1,N+1);
% leave off 1 point so initial condition is periodic
% (doesn't have a duplicate point)
x(end) = [];
uWithMatrix = uRef(0,x);
uNoMatrix = uRef(0,x);
dx = diff(x(1:2));
dt = dx.^2/2;
%Iteration matrix:
e = ones(N,1);
A = spdiags([e -2*e e], -1:1, N, N);
A(N,1) = 1;
A(1,N) = 1;
A = A/dx^2;
%indices (left, center, right) for second order centered difference
iLeft = [numel(x), 1:numel(x)-1]';
iCenter = (1:numel(x))';
iRight = [2:numel(x), 1]';
%plot
figure(1)
clf
hold on
h0=plot(x,uRef(0,x),'k--','linewidth',2);
h1=plot(x,uWithMatrix);
h2=plot(x,uNoMatrix,'o');
ylim([-1.2, 1.2])
legend('Analytical solution','Matrix solution','Matrix-free solution')
ht = title(sprintf('Time t = %0.2f',0));
xlabel('x')
ylabel('u')
drawnow
for t = 0:dt:1
uWithMatrix = uWithMatrix + dt*( A*uWithMatrix + b(t,x) );
uNoMatrix = uNoMatrix + dt*( ( uNoMatrix(iLeft) ...
- 2*uNoMatrix(iCenter) ...
+ uNoMatrix(iRight) )/dx^2 ...
+ b(t,x) );
set(h0,'ydata',uRef(t,x))
set(h1,'ydata',uWithMatrix)
set(h2,'ydata',uNoMatrix)
set(ht,'String',sprintf('Time t = %0.2f',t))
drawnow
end