FFT 푸 아송 솔버의 수렴 률


16

FFT 독 솔버의 이론적 수렴 률은 얼마입니까?

I는 포아송 방정식 오전 : 와 도메인 에서 주기적으로 경계 조건. 이 전하 밀도는 순 중립입니다. 해결책은 다음과 같습니다. 여기서 입니다. 역수 공간에서 여기서 는 역수 공간 벡터입니다. Hartree 에너지에 관심이 있습니다. n ( x , y , z ) = 3

2VH(엑스,와이,)=4π(엑스,와이,)
[0,2]×[0,2]×[0,2]VH(x)=n( y )
(엑스,와이,)=π((엑스1)2+(와이1)2+(1)21)
[0,2]×[0,2]×[0,2]x=(x,y,z)VH(G)=4πn(G)
VH(엑스)=(와이)|엑스와이|와이
엑스=(엑스,와이,) GEH=1
VH()=4π()2
이자형H=12(엑스)(와이)|엑스와이|엑스와이=12VH(엑스)(엑스)엑스
역수 공간에서 이것은 다음과 같이됩니다 ( 후) : 유효 전하 밀도하게되는 기간이 생략 중성 순 (그리고 때문에 이미 중립이라면 모든 것이 일관됩니다).
이자형H=2π0|()|22
=0

위의 테스트 문제의 경우 분석적으로 평가할 수 있으며 다음과 같은 결과를 얻을 수 있습니다. 이 에너지는 얼마나 빨리 수렴해야합니까?

이자형H=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

위의 스크립트 (업데이트 된 스크립트 )에 넣을 수 있습니다 . 정확한 해결책은 입니다. 이 경우 정확한 적분은 입니다. 그러나 FFT 솔버는 여전히 위의 스크립트를 실행하고 수렴 ( 플롯으로 업데이트 된 노트북) 을 플롯 하여 확인할 수있는 것처럼이 정확한 솔루션을 향해 선형으로 만 수렴합니다 .VH=(π엑스)(π와이)(π)이자형H=π8

누구나 선형보다 빠른 수렴을 볼 수 있도록 3D의 벤치 마크를 알고 있습니까?


Ondrej, 부드러운 밀도의 푸리에 변환이 델타 함수가 아닙니까? 나는 그것을 실행하기에는 너무 게으르다는 것을 인정하지만, 첫 번째 시도에서 정확한 대답을 얻어야합니다.
Matt Knepley

나는 생각합니다. 그러나 노트북 플롯에서 볼 수 있듯이 한 번의 반복으로 수렴하지 않습니다. 나는 무슨 일이 일어나고 있는지 전혀 모른다.
Ondřej Čertík

Ondrej, 구현이 정확합니까? 나는 대학원 학교에서 숙제를 위해 스펙트럼 솔버를 구현하고 상수를 완전히 퍼부었던 것을 기억합니다. 계산 된 에너지와 정확한 에너지 사이의 절대 거리를보고 오류를 측정하고 있음을 알았습니다. 수렴은 문제의 실제 솔루션과 어떤 모양입니까? 이것은 계산하기 쉽고 문제의 2 차원 조각에 대해 플롯해야합니다.
Aron Ahmadia

Aron --- 다른 코드와 비교하여 구현을 확인했지만 잘못된 초기 샘플링을 확인하고 있었으므로 두 코드에서 동일한 버그가 발생했습니다. Matt가 옳았습니다. 이제 첫 번째 시도에서 수렴됩니다. 아래 답변을 참조하십시오.
Ondřej Čertík

답변:


10

먼저 모든 질문에 대답하겠습니다.

FFT 독 솔버의 이론적 수렴 률은 얼마입니까?

해가 충분히 부드럽다면 이론적 수렴은 지수입니다.

이 에너지는 얼마나 빨리 수렴해야합니까?

Hartree 에너지 는 충분히 부드러운 솔루션을 위해 기하 급수적으로 수렴해야합니다. 솔루션이 덜 매끄럽다면 수렴이 느려집니다.이자형H

누구나 선형보다 빠른 수렴을 볼 수 있도록 3D의 벤치 마크를 알고 있습니까?

주기적이며 무한히 차별화 가능한 솔루션 (주기적인 경계를 포함하여)을 생성하는 모든 오른쪽은 기하 급수적으로 수렴해야합니다.


위의 코드에는 버그가 발생하여 수렴이 지수보다 느립니다. 매끄러운 밀도 코드 ( 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

문제는 실제 공간 샘플링 이 첫 번째 지점과 마지막 지점을 반복 할 수 없다는 것입니다 (정기 경계 조건으로 인해 같은 값을 가짐). 즉, 초기 샘플링을 설정하는 데 문제가있었습니다.

이 수정 후, Matt가 위에서 말한 것처럼 밀도는 한 번의 반복으로 수렴합니다. 그래서 수렴 그래프도 그리지 않았습니다.

그러나 다음과 같이 더 어려운 밀도를 시도 할 수 있습니다.

     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.