주기적 경계 조건을 가진 슈뢰딩거 방정식


9

다음과 관련하여 몇 가지 질문이 있습니다.

크랭크 nicolson discretization을 사용하여 Schrodinger 방정식을 1D로 풀고 그 결과로 얻은 3 각형 행렬을 뒤집으려고합니다. 내 문제는 이제 주기적 경계 조건과 관련된 문제로 발전했으며 Sherman Morrison 알고리즘을 사용하도록 코드를 수정했습니다.

3 v각형 행렬을 반전시키고 싶을 때 각 시간 단계에서 RHS가 있다고 가정하십시오 . 의 크기는 v공간에 대한 격자 점 수입니다. 정기적 인 상황에서 필요에 따라 서로를 설정 v[0]하고 설정하면 v[-1]방정식이 폭발합니다. 왜 이런 일이 일어나고 있는지 말할 수 없습니다. 나는 python2.7과 scipy의 내장 solve_banded를 사용하여 방정식을 풀고 있습니다.

이것은 두 번째 질문으로 이어집니다. 파이썬은 내가 가장 잘 알고있는 언어이기 때문에 사용했지만 다소 느립니다 (numpy와 scipy가 제공하는 최적화조차도). 나는 C ++을 합리적으로 익숙해 봤다. BLAS 최적화 된 GSL을 사용한다고 생각했지만 복잡한 벡터를 만들거나 복잡한 값을 가진 벡터로 3 각형 행렬을 해결할 수있는 문서를 찾지 못했습니다.

프로그램에서 객체를 원하고 나중에 파형 함수 사이의 커플 링을 포함하도록 일반화하는 가장 쉬운 방법이라고 생각하므로 객체 지향 언어를 고수하고 있습니다.

나는 tridiagonal matrix solver를 직접 작성해 볼 수는 있지만 파이썬에서 그렇게 할 때 문제가 발생했습니다. 더 세밀하고 세밀한 시간 간격으로 여러 번 진화함에 따라 오류가 누적되어 말도 안됩니다. 이를 염두에두고 내장 된 방법을 사용하기로 결정했습니다.

모든 조언을 부탁드립니다.

편집 : 다음은 관련 코드 스 니펫입니다. 이 표기법은 TDM (Tridiagonal Matrix) 방정식에 대한 Wikipedia의 페이지에서 차용되었습니다. v는 각 시간 단계에서 크랭크 니콜슨 알고리즘의 RHS이다. 벡터 a, b 및 c는 TDM의 대각선입니다. 정기 사건에 대한 올바른 알고리즘 은 CFD Wiki 입니다. 나는 약간의 이름을 변경했습니다. 그들이 U라고 부르는 것, v 나는 U, V (자본)라고 불렀습니다. 나는 임시 솔루션과 실제 솔루션 self.currentState를 보완이라고 불렀다. v [0] 및 v [-1]의 할당은 여기서 문제를 일으키는 원인이므로 주석 처리되었습니다. 감마 요인을 무시할 수 있습니다. 이들은 Bose Einstein Condensates를 모델링하는 데 사용되는 비선형 요인입니다.

for T in np.arange(self.timeArraySize):
        for i in np.arange(0,self.spaceArraySize-1):
            v[i] = Y*self.currentState[i+1] + (1-2*Y)*self.currentState[i] + Y*self.currentState[i-1] - 1j*0.5*self.timeStep*potential[i]*self.currentState[i] - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[i])**2)*self.currentState[i]
            b[i] = 1+2*Y + 1j*0.5*self.timeStep*potential[i] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[i])**2)

        #v[0] = Y*self.currentState[1] + (1-2*Y)*self.currentState[0] + Y*self.currentState[-1] - 1j*0.5*self.timeStep*potential[0]*self.currentState[0]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[0])**2)*self.currentState[0]
        #v[-1] = Y*self.currentState[0] + (1-2*Y)*self.currentState[-1] + Y*self.currentState[-2] - 1j*0.5*self.timeStep*potential[-1]*self.currentState[-1]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[-1])**2)*self.currentState[-1]
        b[0] = 1+2*Y + 1j*0.5*self.timeStep*potential[0] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[0])**2)
        b[-1] = 1+2*Y + 1j*0.5*self.timeStep*potential[-1] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[-1])**2)

        diagCorrection[0], diagCorrection[-1] = - b[0], - c[-1]*a[0]/b[0]

        tridiag = np.matrix([
            c,
            b - diagCorrection,
            a,
        ])

        temp = solve_banded((1,1), tridiag, v)

        U = np.zeros(self.spaceArraySize, dtype=np.complex64)
        U[0], U[-1] = -b[0], c[-1]

        V = np.zeros(self.spaceArraySize, dtype=np.complex64)
        V[0], V[-1] = 1, -a[0]/b[0]

        complement = solve_banded((1,1), tridiag, U)

        num = np.dot(V, temp)
        den = 1 + np.dot(V, complement)

        self.currentState = temp  - (num/den)*complement

3
주기적 경계 조건에서 버그처럼 들립니다. 코드 스 니펫을 게시 하시겠습니까?
David Ketcheson

2
Stack Exchange에 오신 것을 환영합니다! 앞으로 몇 가지 질문이있는 경우 별도로 질문 할 수 있습니다.
Dan

또한 "정확하게 v [0]과 v [-1]을 설정한다는 것은 무엇을 의미합니까? 해결 후 벡터 요소를 서로 동일하게 설정합니까, 아니면 삼각 관계를 벗어난 요소를 사용하여 결합합니까?
Dan

위의 코드를 추가했습니다. 확실치 않은 사항이 있으면 알려주십시오. 다음에 별도의 질문을 게시해야합니다.
WiFO215 5

감사! 형식화 (매우 긴 행)로 인해 코드를 읽기가 약간 어렵습니다. 또한 사람들이주의를 기울여야 할 부분에 대해 언급하는 것은 혼란 스럽습니다. 코드와 같은 표기법을 사용하여 풀고있는 수학 식 (MathJax로)을 작성 하시겠습니까?
David Ketcheson

답변:


2

두 번째 질문

Scipy / Numpy를 호출하는 코드는 일반적으로 벡터화 할 수있는 경우에만 빠릅니다. 파이썬 루프 안에 "느린"것은 없어야합니다. 그럼에도 불구하고 컴파일 된 언어로 비슷한 라이브러리를 사용하는 것보다 조금 느리다는 것은 불가피합니다.

for i in np.arange(0,self.spaceArraySize-1):
            v[i] = Y*self.currentState[i+1] + (1-2*Y)*self.currentState[i]   ...
            b[i] = 1+2*Y + 1j*0.5*self.timeStep*potential[i] + ...

이것이 바로 "파이썬 루프에서 느리게"라는 의미입니다. 파이썬 for은 대부분의 숫자 응용 프로그램에서 허용 할 수 없을 정도로 느리며 Scipy / Numpy는 이것에 전혀 영향을 미치지 않습니다. 파이썬을 사용하려는 경우이 내부 루프는 하나 또는 두 개의 Numpy / Scipy 함수로 표현되어야하며, 이러한 라이브러리는 제공하거나 제공하지 않을 수 있습니다. 그들이 이런 배열을 반복하고 인접한 요소에 액세스 할 수있는 것을 제공하지 않으면 python은 당신이하고 싶은 일에 대한 잘못된 도구입니다.

또한 행렬 벡터 해결 대신 반전을 수행하고 있습니다. 행렬 반전과 행렬 벡터 곱셈은 행렬 벡터 해석 보다 훨씬 느립니다. 이것은 거의 다른 무엇보다 코드를 느리게 만드는 것입니다.

C / C ++를 사용하려면 복잡한 선형 대수와 관련하여 GSL이 부족합니다. BLAS 또는 LAPACK을 직접 사용하거나 PETSc 또는 Trilinos와 같은 라이브러리를 사용하는 것이 좋습니다. MKL이 설치되어 있으면 사용할 수도 있습니다. 개체 지향적 인 Fortran 2008을 확인하십시오.

행렬이 희박하므로 희소 라이브러리를 사용해야합니다.

또한 당신이 여기서하고있는 일이 객체 지향이 아마도 당신의 주요 관심사가되어서는 안될 정도로 저수준으로 보인다고 말할 것입니다. Fortran 90+ 배열은 아마도 당신이 필요로하는 것과 아주 잘 어울릴 것입니다 .F90 컴파일러는 일부 루프를 자동 병렬화 할 수 있습니다.

또한, sparse()기능 이있는 Octave 또는 Matlab을 확인하고 싶을 수도 있습니다. 올바르게 사용하면 꽤 빨리 실행될 수 있습니다.


나는 확실히 Fortran 2008을 조사 할 것이다. 나는 이미 '거의 삼각형'행렬을 얻었다. 위에서 Sherman Morrison 알고리즘을 사용하고 있다고 언급했습니다.
WiFO215 5

업데이트 : ScaLAPACK은 매우 흥미로워 서 읽으려고했습니다. 그것은 내가 "병렬로"많이 듣는 버즈 단어를 사용하여 행렬을 반전시킬 수있게한다. 내가 아는 것은 모든 프로세서를 사용하므로 더 빠르다는 것입니다. 그러나 그 이상으로 나는 그것이 무엇인지 이해하지 못합니다. 물리학 배경에서 비롯된 Python과 C의 101 개 과정을 통해 유일하게 컴퓨팅에 노출됩니다.이를 사용하는 방법을 배우려면 시간이 걸릴 것입니다. 문서 자체는 깨끗한 독서에 적합하지 않습니다.
WiFO215

업데이트 2 : 남자! 이 ScaLAPACK은 정말 복잡해 보입니다. 웹 사이트에있는 내용의 머리 나 꼬리를 이해하지 못합니다. 나는 단순히 모든 정보에서 수영하고 있습니다.
WiFO215

업데이트 3 : 좋아, 나는 다른 권장 사항 PETSc와 Trilinos를 겪었습니다. 마지막 호출은 매우 복잡해 보이기 때문에 지금 사용하지 않을 것이라고 생각합니다. 그렇다고 읽지 않는다는 의미는 아닙니다. 지금부터 읽을 것입니다. 그러나 이해하고 구현할 수있을 때까지 몇 달이 지났습니다. 문제가 생길 때 위의 질문에 대해 별도의 스레드를 열어야하지만 나중에 가능합니다. 이제 저는 1 번 문제 만 다루었습니다.
WiFO215

내 답변을 업데이트했습니다.
Dan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.