La meilleure façon de le faire est (comme vous l'avez dit) d'utiliser simplement la définition des conditions aux limites périodiques et de configurer correctement vos équations dès le départ en utilisant le fait que . En fait, encore plus fortement, les conditions aux limites périodiques identifient x = 0 avec x = 1 . Pour cette raison, vous ne devez avoir qu'un seul de ces points dans votre domaine de solution. Un intervalle ouvert n'a pas de sens lors de l'utilisation de conditions aux limites périodiques car il n'y a pas de limite .u(0)=u(1)x=0x=1
Ce fait signifie que vous ne devez pas placer un point à car il est identique à x = 0 . Discrétisant avec N + 1 points, vous utilisez ensuite le fait que par définition, le point à gauche de x 0 est x N et le point à droite de x N est x 0 .x=1x=0N+1x0 xNxN x0
Votre PDE peut ensuite être discrétisé dans l'espace comme
∂∂t⎡⎣⎢⎢⎢⎢x0x1⋮xN⎤⎦⎥⎥⎥⎥=1Δx2⎡⎣⎢⎢⎢⎢xN−2x0+x1x0−2x1+x2⋮xN−1−2xN+x0⎤⎦⎥⎥⎥⎥
Cela peut être écrit sous forme de matrice comme
où
A=[ - 2 1 0 ⋯ 0 1 1 - 2 1 0 ⋯ 0
∂∂tx⃗ =1Δx2Ax⃗
A=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢−21011−2⋱⋯001⋱⋱0⋯⋯0⋱⋱100⋯⋱−21101−2⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.
Bien sûr, il n'est pas nécessaire de créer ou de stocker cette matrice. Les différences finies doivent être calculées à la volée, en prenant soin de traiter les premier et dernier points spécialement si nécessaire.
∂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