A melhor maneira de fazer isso é (como você disse), basta usar a definição de condições de contorno periódicas e configurar suas equações corretamente desde o início, usando o fato de que . De fato, ainda mais fortemente, as condições de contorno periódicas identificam com . Por esse motivo, você deve ter apenas um desses pontos no domínio da solução. Um intervalo aberto não faz sentido ao usar condições de limite periódicas, pois não há limite .u(0)=u(1)x=0x=1
Esse fato significa que você não deve colocar um ponto em pois é o mesmo que . Discretizando com pontos, você usa o fato de que, por definição, o ponto à esquerda de é e o ponto à direita de é .x=1x=0N+1x0 xNxN x0
Seu PDE pode ser discretizado no espaço como
∂∂t⎡⎣⎢⎢⎢⎢x0x1⋮xN⎤⎦⎥⎥⎥⎥=1Δx2⎡⎣⎢⎢⎢⎢xN−2x0+x1x0−2x1+x2⋮xN−1−2xN+x0⎤⎦⎥⎥⎥⎥
Isso pode ser escrito em forma de matriz como
que
∂∂tx⃗ =1Δx2Ax⃗
A=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢−21011−2⋱⋯001⋱⋱0⋯⋯0⋱⋱100⋯⋱−21101−2⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.
Obviamente, não há necessidade de criar ou armazenar essa matriz. As diferenças finitas devem ser calculadas em tempo real, tendo o cuidado de lidar com o primeiro e o último pontos, especialmente conforme necessário.
Como um exemplo simples, o script MATLAB a seguir resolve
com condições de contorno periódicas no domínio . A solução fabricada é usada, o que significa . Usei a discretização do tempo de Euler para simplificar e calculei a solução com e sem formar a matriz. Os resultados são mostrados abaixo.
∂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