Cách tốt nhất để làm điều này là (như bạn đã nói) chỉ sử dụng định nghĩa về các điều kiện biên định kỳ và thiết lập chính xác các phương trình của bạn ngay từ đầu bằng cách sử dụng thực tế là . Trong thực tế, thậm chí mạnh hơn, các điều kiện biên định kỳ xác định với . Vì lý do này, bạn chỉ nên có một trong những điểm này trong miền giải pháp của mình. Một khoảng mở không có ý nghĩa khi sử dụng các điều kiện biên định kỳ vì không có ranh giới .x = 0 x = 1u(0)=u(1)x=0x=1
Thực tế này có nghĩa là bạn không nên đặt một điểm tại vì nó giống với . Phân biệt với điểm, sau đó bạn sử dụng thực tế là theo định nghĩa, điểm ở bên trái của là và điểm ở bên phải của là .x = 0 N + 1 x 0 x N x N x 0x=1x=0N+1x0 xNxN x0
PDE của bạn sau đó có thể được rời rạc trong không gian dưới dạng
∂∂t⎡⎣⎢⎢⎢⎢x0x1⋮xN⎤⎦⎥⎥⎥⎥= 1Δ x2⎡⎣⎢⎢⎢⎢xN- 2 x0+ x1x0- 2 x1+ x2⋮xN- 1- 2 xN+ x0⎤⎦⎥⎥⎥⎥
Điều này có thể được viết dưới dạng ma trận dưới dạng
trong đó
Một=[ - 2 1 0 ⋯ 0 1 1 - 2 1 0 ⋯ 0
∂∂tx⃗ = 1Δ x2Một x⃗
Một = ⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢- 21011- 2⋱⋯001⋱⋱0⋯⋯0⋱⋱100⋯⋱- 21101- 2⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.
Tất nhiên không cần phải thực sự tạo hoặc lưu trữ ma trận này. Sự khác biệt hữu hạn nên được tính toán một cách nhanh chóng, chú ý xử lý các điểm đầu tiên và cuối cùng đặc biệt khi cần thiết.
Ví dụ đơn giản, tập lệnh MATLAB sau đây giải quyết
với các điều kiện biên định kỳ trên miền . Giải pháp được sản xuất được sử dụng, nghĩa là . Tôi đã sử dụng chuyển tiếp thời gian Euler để đơn giản hóa và tính toán giải pháp cả có và không tạo thành ma trận. Các kết quả được hiển thị dưới đây.x ∈ [ - 1 , 1 ) u Ref ( t , x ) = exp ( - t ) cos ( 5 π x ) b ( t , x ) = ( 25 π 2 - 1 ) điểm kinh nghiệm ( - t
∂tu = ∂x xu + b ( t , x )
x ∈ [ - 1 , 1 )bạnTham chiếu( t , x ) = điểm kinh nghiệm( - t ) cos( 5 πx )b ( t , x ) = ( 25 π2- 1 ) điểm kinh nghiệm( - 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