อัตราการลู่เข้าของตัวแก้ปัญหา FFT Poisson


16

อัตราการรวมทางทฤษฎีสำหรับตัวแก้พิษแบบ FFT คืออะไร?

ฉันกำลังแก้สมการปัวซอง: กับ n ( x , y , z ) = 3

2VH(x,Y,Z)=-4πn(x,Y,Z)
บนโดเมน[0,2]×[0,2]×[0,2]โดยมีเงื่อนไขขอบเขตเป็นระยะ ความหนาแน่นประจุนี้เป็นกลางสุทธิ วิธีแก้ปัญหานั้นได้รับ: VH(x)=n(
n(x,Y,Z)=3π((x-1)2+(Y-1)2+(Z-1)2-1)
[0,2]×[0,2]×[0,2] ที่x=(x,Y,Z) ในพื้นที่ซึ่งกันและกัน VH(G)=4πn(G)
VH(x)=n(Y)|x-Y|d3Y
x=(x,Y,Z) โดยที่Gเป็นเวกเตอร์พื้นที่ส่วนกลับ ฉันสนใจพลังงาน Hartree: EH=1
VH(G)=4πn(G)G2
G ในพื้นที่ซึ่งกันและกันสิ่งนี้จะกลายเป็น (หลังจาก discretization): EH=2πG0 | n( G ) | 2
EH=12n(x)n(Y)|x-Y|d3xd3Y=12VH(x)n(x)d3x
G=0ระยะถูกละไว้อย่างมีประสิทธิภาพซึ่งจะทำให้ค่าความหนาแน่นสุทธิเป็นกลาง (และเพราะมันเป็นธรรมชาติอยู่แล้วทุกอย่างเป็นสิ่งที่สอดคล้องกัน)
EH=2πΣG0|n(G)|2G2
G=0

EH=12835π=1.16410 ...

นี่คือโปรแกรมที่ใช้ NumPy ที่ทำการคำนวณ

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

และนี่คือกราฟคอนเวอร์เจนซ์ (เพียงแค่พล็อตconv.txtจากสคริปต์ด้านบนนี่คือโน้ตบุ๊กที่ทำถ้าคุณต้องการเล่นด้วยตัวคุณเอง):

กราฟลู่ FFT

อย่างที่คุณเห็นการบรรจบกันนั้นเป็นเส้นตรงซึ่งทำให้ฉันประหลาดใจฉันคิดว่า FFT ลู่เข้าหาได้เร็วกว่านั้นมาก

อัปเดต :

วิธีแก้ปัญหามีจุดที่ขอบเขต (ฉันไม่ได้ตระหนักถึงสิ่งนี้มาก่อน) เพื่อให้ FFT เข้าหากันอย่างรวดเร็วการแก้ปัญหาจะต้องมีอนุพันธ์ที่ราบรื่นทั้งหมด ดังนั้นฉันจึงลองด้านขวาดังต่อไปนี้:

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

VH=บาป(πx)บาป(πY)บาป(πZ)EH=3π8

มีใครรู้บ้างว่ามีมาตรฐานในแบบ 3 มิติเพื่อที่ฉันจะได้เห็นการลู่เข้าที่รวดเร็วกว่าเชิงเส้น


ในวันที่, การแปลงฟูริเยร์ของความหนาแน่นที่ราบรื่นของคุณไม่ใช่ฟังก์ชันเดลตา? ฉันยอมรับที่จะขี้เกียจเกินไปที่จะเรียกใช้ แต่ควรได้รับคำตอบที่ถูกต้องในการลองครั้งแรก
Matt Knepley

ฉันคิดว่ามันคือ. แต่มันไม่ได้มาบรรจบกันในการทำซ้ำครั้งเดียวดังที่เห็นได้จากแปลงสมุดบันทึก ฉันไม่รู้ว่าเกิดอะไรขึ้น
OndČejČertík

เมื่อวาน, คุณแน่ใจหรือว่าการใช้งานของคุณถูกต้อง? ฉันจำได้ว่าพยายามใช้นักแก้ปัญหาสเปกตรัมสำหรับการบ้านในโรงเรียนที่จบการศึกษา ฉันสังเกตว่าคุณกำลังวัดความผิดพลาดโดยดูจากระยะห่างที่แน่นอนระหว่างพลังงานที่คำนวณและพลังงานที่แน่นอน การบรรจบกันของคุณมีลักษณะอย่างไรในการแก้ปัญหาที่แท้จริงของปัญหา? นี่ควรจะง่ายต่อการคำนวณและแม้กระทั่งพล็อตมากกว่าสองมิติของปัญหา
Aron Ahmadia

อารอน --- ฉันตรวจสอบการติดตั้งของฉันกับรหัสอื่น ๆ แต่ฉันตรวจสอบมันสำหรับการสุ่มตัวอย่างเริ่มต้นที่ไม่ถูกต้องดังนั้นฉันจึงมีจุดบกพร่องเดียวกันในรหัสทั้งสอง แมตต์ถูกต้องตอนนี้มันมาบรรจบกันในความพยายามครั้งแรก ดูคำตอบของฉันด้านล่าง
OndČejČertík

คำตอบ:


10

ให้ฉันก่อนตอบคำถามทั้งหมด:

อัตราการรวมทางทฤษฎีสำหรับตัวแก้พิษแบบ FFT คืออะไร?

การลู่เข้าทางทฤษฎีนั้นมีความเป็นเอกซ์โพเนนเชียลหากการแก้ปัญหานั้นราบรื่นพอสมควร

พลังงานนี้ควรมาบรรจบกันเร็วแค่ไหน?

พลังงาน Hartree EHควรมาบรรจบกันเพื่อหาทางออกที่ราบรื่นพอสมควร หากการแก้ปัญหาราบรื่นน้อยกว่าการบรรจบกันจะช้าลง

มีใครรู้บ้างว่ามีมาตรฐานในแบบ 3 มิติเพื่อที่ฉันจะได้เห็นการลู่เข้าที่รวดเร็วกว่าเชิงเส้น

ทางด้านขวามือใด ๆ ที่ก่อให้เกิดทางออกที่เป็นระยะและมีความแตกต่างกันอย่างไม่สิ้นสุด (รวมถึงข้ามเขตแดนเป็นระยะ) ควรมาบรรจบกันแบบทวีคูณ


ในรหัสด้านบนมีข้อผิดพลาดที่ทำให้การบรรจบกันช้ากว่าเลขชี้กำลัง การใช้รหัสความหนาแน่นที่ราบรื่น ( https://gist.github.com/certik/5549650/ ) แพทช์ต่อไปนี้จะแก้ไขข้อบกพร่อง:

@@ -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

ปัญหาคือการสุ่มตัวอย่างพื้นที่จริงไม่สามารถทำได้ทำซ้ำจุดแรกและจุดสุดท้าย (ซึ่งมีค่าเดียวกันเนื่องจากเงื่อนไขขอบเขตเป็นระยะ) ในคำอื่น ๆ ปัญหาคือในการตั้งค่าการสุ่มตัวอย่างเริ่มต้น

หลังจากการแก้ไขนี้ความหนาแน่นจะมาบรรจบกันในหนึ่งรอบตามที่แมตต์กล่าวไว้ข้างต้น ดังนั้นฉันจึงไม่ได้พล็อตกราฟการลู่เข้า

อย่างไรก็ตามเราสามารถลองความหนาแน่นที่ยากขึ้นได้เช่น:

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

จากนั้นการบรรจบกันนั้นจะเป็นการยกกำลังอย่างที่คาดไว้ นี่คือกราฟการลู่เข้าสำหรับความหนาแน่นนี้: ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่


น่ากลัว ขอโทษฉันไม่ได้ช่วยอะไรอีก!
Aron Ahmadia
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.