La mejor manera de hacer esto es (como dijiste) simplemente usar la definición de condiciones de contorno periódicas y configurar tus ecuaciones correctamente desde el principio usando el hecho de que . De hecho, aún más fuertemente, las condiciones de contorno periódicas identifican x = 0 con x = 1 . Por esta razón, solo debe tener uno de estos puntos en su dominio de solución. Un intervalo abierto no tiene sentido cuando se usan condiciones de límite periódicas ya que no hay límite .u(0)=u(1)x=0x=1
Este hecho significa que no debe colocar un punto en ya que es lo mismo que x = 0 . Discretizando con N + 1 puntos, entonces usa el hecho de que, por definición, el punto a la izquierda de x 0 es x N y el punto a la derecha de x N esx=1x=0N+1x0 xNxN x0 .
Su PDE se puede discretizar en el espacio como
∂∂t⎡⎣⎢⎢⎢⎢x0x1⋮xN⎤⎦⎥⎥⎥⎥=1Δx2⎡⎣⎢⎢⎢⎢xN−2x0+x1x0−2x1+x2⋮xN−1−2xN+x0⎤⎦⎥⎥⎥⎥
Esto se puede escribir en forma de matriz como
donde
A=[ - 2 1 0 ⋯ 0 1 1 - 2 1
∂∂tx⃗ =1Δx2Ax⃗
A=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢−21011−2⋱⋯001⋱⋱0⋯⋯0⋱⋱100⋯⋱−21101−2⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.
Por supuesto, no hay necesidad de crear o almacenar esta matriz. Las diferencias finitas deben calcularse sobre la marcha, teniendo cuidado de manejar el primer y el último punto especialmente según sea necesario.
Como ejemplo simple, el siguiente script de MATLAB resuelve
con condiciones de contorno periódicas en el dominio x ∈ [ - 1 , 1 ) . Se utiliza la solución fabricada u Ref ( t , x ) = exp ( - t ) cos ( 5 π x ) , lo que significa b ( t ,
∂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