Der beste Weg, dies zu tun, ist (wie Sie sagten), einfach die Definition der periodischen Randbedingungen zu verwenden und Ihre Gleichungen von Anfang an korrekt unter Verwendung der Tatsache aufzustellen, dass . Tatsächlich identifizieren periodische Randbedingungen noch stärker x = 0 mit x = 1 . Aus diesem Grund sollten Sie nur einen dieser Punkte in Ihrer Lösungsdomäne haben. Ein offenes Intervall ist bei periodischen Randbedingungen nicht sinnvoll, da es keine Grenze gibt .u(0)=u(1)x=0x=1
Diese Tatsache bedeutet, dass Sie keinen Punkt bei da er mit x = 0 identisch ist . Diskretisierung mit N + 1 Punkten, verwenden Sie dann die Tatsache , dass der Punkt links von definitions x 0 heißt x N und der Punkt rechts von x N istx=1x=0N+1x0 xNxN x0 .
Ihre PDE kann dann im Raum als ∂ diskretisiert werden
∂∂t⎡⎣⎢⎢⎢⎢x0x1⋮xN⎤⎦⎥⎥⎥⎥=1Δx2⎡⎣⎢⎢⎢⎢xN−2x0+x1x0−2x1+x2⋮xN−1−2xN+x0⎤⎦⎥⎥⎥⎥
Dies kann in Matrixform als
wobei
A=[ - 2 1 0 ⋯ 0 1 1 - 2 1
∂∂tx⃗ =1Δx2Ax⃗
A=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢−21011−2⋱⋯001⋱⋱0⋯⋯0⋱⋱100⋯⋱−21101−2⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.
Natürlich muss diese Matrix nicht erstellt oder gespeichert werden. Die endlichen Differenzen sollten im laufenden Betrieb berechnet werden, wobei darauf zu achten ist, dass der erste und der letzte Punkt nach Bedarf behandelt werden.
Als einfaches Beispiel löst das folgende MATLAB-Skript
mit periodischen Randbedingungen auf der Domäne x ∈ [ - 1 , 1 ) . Die hergestellte Lösung U Ref ( t , x ) = exp ( - t ) cos ( 5 π x ) = ( 25 π 2 -
∂tu=∂xxu+b(t,x)
x∈[−1,1)uRef(t,x)=exp(−t)cos(5πx) verwendet wird, was bedeutet ,
. Ich habe der Einfachheit halber die Euler-Vorwärts-Zeitdiskretisierung verwendet und die Lösung sowohl mit als auch ohne Bildung der Matrix berechnet. Die Ergebnisse sind unten gezeigt.
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