Tingkat konvergensi pemecah FFT Poisson

16

Berapa tingkat konvergensi teoretis untuk pemecah FFT Poison?

Saya memecahkan persamaan Poisson: dengan n ( x , y , z ) = 3

2VH(x,y,z)=-4πn(x,y,z)
pada domain[0,2]×[0,2]×[0,2]dengan kondisi batas periodik. Kerapatan muatan ini netral bersih. Solusi diberikan oleh: VH(x)=n(
n(x,y,z)=3π((x-1)2+(y-1)2+(z-1)2-1)
[0,2]×[0,2]×[0,2] manax=(x,y,z). Dalam ruang timbal balik VH(G)=4πn(G)
VH(x)=n(y)|x-y|d3y
x=(x,y,z) di manaGadalah vektor ruang timbal balik. Saya tertarik pada energi Hartree: EH=1
VH(G)=4πn(G)G2
G Dalam ruang timbal balik, ini menjadi (setelah diskritisasi): EH=2πG0 | n( G ) | 2
EH=12n(x)n(y)|x-y|d3xd3y=12VH(x)n(x)d3x
IstilahG=0dihilangkan, yang secara efektif membuat kerapatan muatan menjadi netral (dan karena sudah netral, maka semuanya konsisten).
EH=2πG0|n(G)|2G2
G=0

EH=12835π=1.16410 ...

Berikut adalah program menggunakan NumPy yang melakukan perhitungan.

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()

Dan di sini adalah grafik konvergensi (hanya memplot conv.txtdari script di atas, di sini adalah notebook yang melakukan itu jika Anda ingin bermain dengan ini sendiri):

Grafik konvergensi FFT

Seperti yang Anda lihat, konvergensi linier, yang merupakan kejutan bagi saya, saya pikir FFT bertemu lebih cepat dari itu.

Perbarui :

Solusinya memiliki titik puncak pada batas (saya tidak menyadari ini sebelumnya). Agar FFT dapat konvergen dengan cepat, solusinya harus memiliki semua turunannya lancar. Jadi saya juga mencoba sisi kanan berikut:

nr = 3*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)/4

VH=dosa(πx)dosa(πy)dosa(πz)EH=3π8

Adakah yang tahu benchmark apa pun dalam 3D sehingga saya bisa melihat konvergensi yang lebih cepat daripada linear?

OndČej Čertík
sumber
Ondrej, bukankah transformasi Fourier dari kepadatan halus Anda merupakan fungsi delta? Saya akui terlalu malas untuk menjalankannya, tetapi harus mendapatkan jawaban yang tepat pada percobaan pertama.
Matt Knepley
Aku rasa ini. Tapi itu tidak bertemu dalam satu iterasi, seperti yang bisa dilihat dari plot notebook. Aku tidak tahu apa yang sedang terjadi.
Ondřej Čertík
Ondrej, apakah Anda yakin implementasi Anda benar? Saya ingat mencoba menerapkan pemecah spektral untuk tugas pekerjaan rumah di sekolah pascasarjana dan benar-benar menggagalkan konstanta. Saya perhatikan bahwa Anda mengukur kesalahan dengan melihat jarak absolut antara energi yang dihitung dan yang tepat. Seperti apa konvergensi Anda dengan solusi aktual masalah itu? Ini harus mudah untuk dihitung dan bahkan plot lebih dari sepotong 2-D masalah.
Aron Ahmadia
Aron --- Saya memeriksa implementasi saya terhadap beberapa kode lain, tapi saya mengeceknya untuk pengambilan sampel awal yang salah, jadi saya memiliki bug yang sama di kedua kode. Matt benar, sekarang menyatu pada percobaan pertama. Lihat jawaban saya di bawah ini.
Ondřej Čertík

Jawaban:

10

Biarkan saya menjawab semua pertanyaan:

Berapa tingkat konvergensi teoretis untuk pemecah FFT Poison?

Konvergensi teoretis adalah eksponensial selama solusinya cukup lancar.

Seberapa cepat energi ini bertemu?

Energi Hartree EHharus menyatu secara eksponensial untuk solusi yang cukup halus. Jika solusinya kurang mulus, maka konvergensi lebih lambat.

Adakah yang tahu benchmark apa pun dalam 3D sehingga saya bisa melihat konvergensi yang lebih cepat daripada linear?

Sisi kanan mana pun yang menghasilkan solusi yang periodik dan dapat dibedakan tanpa batas (termasuk melintasi batas periodik) harus bertemu secara eksponensial.


Dalam kode di atas ada bug, yang menyebabkan konvergensi lebih lambat daripada eksponensial. Menggunakan kode kepadatan halus ( https://gist.github.com/certik/5549650/ ), tambalan berikut memperbaiki bug:

@@ -6,7 +6,7 @@ f = open("conv.txt", "w")
 for N in range(3, 180, 10):
     print "N =", N
     L = 2.
-    x1d = linspace(0, L, N)
+    x1d = linspace(0, L, N+1)[:-1]
     x, y, z = meshgrid(x1d, x1d, x1d)

     nr = 3*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)/4

Masalahnya adalah bahwa pengambilan sampel ruang nyata tidak dapat mengulangi titik pertama dan terakhir (yang memiliki nilai yang sama karena kondisi batas periodik). Dengan kata lain, masalahnya adalah menyiapkan sampel awal.

Setelah perbaikan ini, kepadatan berkumpul dalam satu iterasi, seperti yang Matt katakan di atas. Jadi saya bahkan tidak memetakan grafik konvergensi.

Namun, seseorang dapat mencoba kepadatan yang lebih sulit, misalnya:

     nr = 3*pi*exp(sin(pi*x)*sin(pi*y)*sin(pi*z))/4

maka konvergensi bersifat eksponensial, seperti yang diharapkan. Berikut adalah grafik konvergensi untuk kerapatan ini: masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

OndČej Čertík
sumber
Luar biasa. Maaf saya tidak membantu lagi!
Aron Ahmadia