Quel est le taux de convergence théorique d'un solveur FFT Poison?
Je une équation de Poisson: avec sur le domaine avec périodique condition limite. Cette densité de charge est nette neutre. La solution est donnée par: où . Dans l'espace réciproque où sont les vecteurs spatiaux réciproques. Je m'intéresse à l'énergie Hartree: n ( x , y , z ) = 3
Pour le problème de test ci-dessus, cela peut être évalué analytiquement et on obtient: quelle vitesse cette énergie devrait-elle converger?
Voici un programme utilisant NumPy qui fait le calcul.
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()
Et voici un graphique de convergence (en traçant simplement le conv.txt
script ci-dessus, voici un cahier qui le fait si vous voulez jouer avec cela vous-même):
Comme vous pouvez le voir, la convergence est linéaire, ce qui m'a surpris, j'ai pensé que la FFT converge beaucoup plus vite que cela.
Mise à jour :
La solution a un point culminant à la frontière (je ne m'en étais pas rendu compte auparavant). Pour que la FFT converge rapidement, la solution doit avoir tous les dérivés lisses. J'ai donc également essayé le côté droit suivant:
nr = 3*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)/4
Que vous pouvez simplement mettre dans le script ci-dessus ( script mis à jour ). La solution exacte est , qui devrait être infiniment différentiable. L'intégrale exacte dans ce cas est . Pourtant, le solveur FFT ne converge toujours que linéairement vers cette solution exacte, comme cela peut être vérifié en exécutant le script ci-dessus et en traçant la convergence ( bloc-notes mis à jour avec des tracés).
Quelqu'un connaît-il une référence en 3D pour que je puisse voir une convergence plus rapide que linéaire?
la source
Réponses:
Permettez-moi d'abord de répondre à toutes les questions:
La convergence théorique est exponentielle tant que la solution est suffisamment lisse.
Tout côté droit qui produit une solution périodique et différentiable à l'infini (y compris à travers la frontière périodique) doit converger de façon exponentielle.
Dans le code ci-dessus, il se trouve qu'il y a un bogue, qui ralentit la convergence par rapport à l'exponentielle. À l'aide du code de densité lisse ( https://gist.github.com/certik/5549650/ ), le correctif suivant corrige le bogue:
Le problème était que l'échantillonnage dans l'espace réel ne peut pas répéter le premier et le dernier point (qui ont la même valeur en raison de la condition aux limites périodique). En d'autres termes, le problème résidait dans la mise en place de l'échantillonnage initial.
Après ce correctif, la densité converge en une seule itération, comme Matt l'a dit ci-dessus. Je n'ai donc même pas tracé les graphiques de convergence.
Cependant, on peut essayer une densité plus difficile, par exemple:
alors la convergence est exponentielle, comme prévu. Voici les graphiques de convergence pour cette densité:
la source