Jaki jest teoretyczny współczynnik zbieżności dla narzędzia FFT Poison?
Rozwiązuję równanie Poissona: przy n ( x , y , z ) = 3
Oto program korzystający z NumPy, który wykonuje obliczenia.
from numpy import empty, pi, meshgrid, linspace, sum
from numpy.fft import fftn, fftfreq
E_exact = 128/(35*pi)
print "Hartree Energy (exact): %.15f" % E_exact
f = open("conv.txt", "w")
for N in range(3, 384, 10):
print "N =", N
L = 2.
x1d = linspace(0, L, N)
x, y, z = meshgrid(x1d, x1d, x1d)
nr = 3 * ((x-1)**2 + (y-1)**2 + (z-1)**2 - 1) / pi
ng = fftn(nr) / N**3
G1d = N * fftfreq(N) * 2*pi/L
kx, ky, kz = meshgrid(G1d, G1d, G1d)
G2 = kx**2+ky**2+kz**2
G2[0, 0, 0] = 1 # omit the G=0 term
tmp = 2*pi*abs(ng)**2 / G2
tmp[0, 0, 0] = 0 # omit the G=0 term
E = sum(tmp) * L**3
print "Hartree Energy (calculated): %.15f" % E
f.write("%d %.15f\n" % (N, E))
f.close()
A oto wykres konwergencji (wystarczy wykreślić conv.txt
powyższy skrypt, oto notatnik, który robi to, jeśli chcesz się tym bawić):
Jak widać, zbieżność jest liniowa, co było dla mnie zaskoczeniem, pomyślałem, że FFT zbiega się znacznie szybciej.
Aktualizacja :
Rozwiązanie ma granicę na granicy (wcześniej nie zdawałem sobie z tego sprawy). Aby FFT szybko się zjednoczył, rozwiązanie musi mieć gładkie wszystkie pochodne. Więc spróbowałem również następującej prawej strony:
nr = 3*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)/4
Czy ktoś zna jakiś punkt odniesienia w 3D, dzięki czemu mogę zobaczyć szybszą zbieżność niż liniową?
źródło
Odpowiedzi:
Pozwól mi najpierw odpowiedzieć na wszystkie pytania:
Teoretyczna zbieżność jest wykładnicza, o ile rozwiązanie jest wystarczająco gładkie.
Każda prawa strona, która wytwarza rozwiązanie, które jest okresowe i nieskończenie zróżnicowane (w tym przez granicę okresową), powinna zbiegać się wykładniczo.
W powyższym kodzie występuje błąd, który powoduje, że konwergencja jest wolniejsza niż wykładnicza. Za pomocą kodu gładkiej gęstości ( https://gist.github.com/certik/5549650/ ) następująca łatka naprawia błąd:
Problem polegał na tym, że próbkowanie przestrzeni rzeczywistej nie może powtórzyć pierwszego i ostatniego punktu (który ma tę samą wartość ze względu na okresowe warunki brzegowe). Innymi słowy, problemem było ustawienie początkowego próbkowania.
Po tej poprawce gęstość zbiega się w jednej iteracji, jak powiedział Matt powyżej. Więc nawet nie wykreśliłem wykresów konwergencji.
Można jednak spróbować trudniejszej gęstości, na przykład:
następnie konwergencja jest wykładnicza, zgodnie z oczekiwaniami. Oto wykresy konwergencji dla tej gęstości:
źródło