Phương trình Schrodinger với các điều kiện biên định kỳ


9

Tôi có một vài câu hỏi liên quan đến các vấn đề sau:

Tôi đang cố gắng giải phương trình Schrodinger trong 1D bằng cách sử dụng phương pháp phân tách nicolson quây sau đó đảo ngược ma trận tridia chéo kết quả. Vấn đề của tôi bây giờ đã phát triển thành một vấn đề với các điều kiện biên định kỳ và vì vậy tôi đã sửa đổi mã của mình để sử dụng thuật toán Sherman Morrison.

Giả sử vlà RHS của tôi ở mỗi bước khi tôi muốn đảo ngược ma trận ba cực. Kích thước của vlà số điểm lưới tôi có trên không gian. Khi tôi thiết lập v[0]v[-1]xét về nhau theo yêu cầu trong tình huống định kỳ của mình, phương trình của tôi sẽ nổ tung. Tôi không thể nói tại sao điều này xảy ra. Tôi đang sử dụng python2.7 và scipy đã sẵn sàng giải quyết_banded để giải phương trình.

Điều này dẫn tôi đến câu hỏi thứ hai của tôi: Tôi đã sử dụng python vì đó là ngôn ngữ tôi biết rõ nhất, nhưng tôi thấy nó khá chậm (ngay cả với các tối ưu hóa được cung cấp bởi numpy và scipy). Tôi đã thử sử dụng C ++ vì tôi khá quen thuộc với nó. Tôi nghĩ rằng tôi sẽ sử dụng GSL sẽ được tối ưu hóa BLAS, nhưng không tìm thấy tài liệu nào để tạo ra các vectơ phức tạp hoặc giải ma trận tam giác với các vectơ có giá trị phức tạp như vậy.

Tôi muốn các đối tượng trong chương trình của mình vì tôi cảm thấy đó là cách dễ nhất để tôi khái quát hóa sau này để bao gồm khớp nối giữa các hàm sóng do đó tôi gắn bó với ngôn ngữ hướng đối tượng.

Tôi có thể thử viết bộ giải ma trận ba cực bằng tay, nhưng tôi gặp vấn đề khi tôi làm như vậy với python. Khi tôi tiến hóa qua thời gian lớn với các bước thời gian tốt hơn và tốt hơn, lỗi đã tích lũy và khiến tôi vô nghĩa. Ghi nhớ điều này, tôi quyết định sử dụng các phương pháp xây dựng.

Bất cứ lời khuyên được nhiều đánh giá cao.

EDIT: Đây là đoạn mã có liên quan. Ký hiệu được mượn từ trang Wikipedia về phương trình ma trận ba cực (TDM). v là RHS của thuật toán quây nicolson ở mỗi bước thời gian. Các vectơ a, b và c là các đường chéo của TDM. Thuật toán sửa cho trường hợp định kỳ là từ CFD Wiki . Tôi đã thực hiện một chút đổi tên. Cái mà họ gọi là u, v tôi đã gọi là U, V (viết hoa). Tôi đã gọi q là phần bù, y là giải pháp tạm thời và giải pháp thực tế self.cienState. Việc gán v [0] và v [-1] là nguyên nhân gây ra vấn đề ở đây và do đó đã được nhận xét. Bạn có thể bỏ qua các yếu tố của gamma. Chúng là các yếu tố phi tuyến tính được sử dụng để mô hình hóa 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
Nghe có vẻ (thoạt nhìn) giống như một lỗi trong điều kiện biên định kỳ của bạn. Muốn đăng một đoạn mã?
David Ketcheson

2
Chào mừng bạn đến với Sàn giao dịch Stack! Trong tương lai, nếu bạn có một vài câu hỏi, bạn có thể muốn hỏi riêng họ.
Dan

Ngoài ra: Chính xác thì bạn có ý gì "đặt v [0] và v [-1] về mặt nhau"? Bạn đang thiết lập các phần tử vectơ bằng nhau sau khi giải, hoặc bạn đang sử dụng phần tử ngoại vi để ghép chúng?
Dan

Tôi đã thêm mã của tôi ở trên. Nếu bất cứ điều gì chưa rõ, xin vui lòng cho tôi biết. Tôi sẽ nhớ để gửi câu hỏi riêng biệt thời gian tới.
WiFO215

Cảm ơn! Thật khó để đọc mã của bạn do định dạng (dòng rất dài). Ngoài ra, bình luận ra chính phần mà bạn muốn mọi người chú ý đến là khó hiểu. Cod bạn viết ra các phương trình bạn đang giải (với MathJax) bằng cách sử dụng ký hiệu giống như mã của bạn?
David Ketcheson

Câu trả lời:


2

Câu hỏi thứ hai

Mã gọi Scipy / Numpy thường chỉ nhanh nếu có thể được vector hóa; bạn không nên có bất cứ thứ gì "chậm" bên trong vòng lặp trăn. Ngay cả sau đó, điều khá khó tránh khỏi là nó sẽ chậm hơn một chút so với thứ gì đó sử dụng một thư viện tương tự trong một ngôn ngữ được biên dịch.

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] + ...

Đây là những gì tôi có nghĩa là "chậm trong một vòng lặp python". Python forchậm đến mức không thể chấp nhận được đối với hầu hết các ứng dụng số và Scipy / Numpy hoàn toàn không ảnh hưởng đến điều này. Nếu bạn định sử dụng python, vòng lặp bên trong này phải được thể hiện dưới dạng một hoặc hai hàm Numpy / Scipy, mà các thư viện đó có thể hoặc không thể cung cấp. Nếu họ không cung cấp thứ gì đó cho phép bạn lặp lại các mảng như thế này và truy cập các phần tử lân cận, python là công cụ sai cho những gì bạn muốn làm.

Ngoài ra, bạn đang thực hiện một phép nghịch đảo thay vì giải toán vectơ ma trận. Một nghịch đảo ma trận, tiếp theo là một ma trận vector nhân, là nhiều chậm hơn so với một ma trận vector giải quyết. Điều này gần như chắc chắn là điều làm chậm mã của bạn hơn bất cứ điều gì khác.

Nếu bạn muốn sử dụng C / C ++, GSL là loại thiếu khi nói đến đại số tuyến tính phức tạp. Tôi khuyên bạn nên sử dụng BLAS hoặc LAPACK trực tiếp hoặc sử dụng thư viện như PETSc hoặc Trilinos. Nếu bạn đã cài đặt MKL, bạn cũng có thể sử dụng nó. Bạn cũng có thể muốn kiểm tra Fortran 2008, hướng đối tượng.

Ma trận của bạn rất thưa thớt, vì vậy bạn sẽ muốn đảm bảo rằng bạn sử dụng các thư viện thưa thớt.

Tôi cũng sẽ nói rằng những gì bạn đang làm ở đây dường như đủ mức độ thấp để định hướng đối tượng có lẽ không phải là mối quan tâm chính của bạn. Một mảng Fortran 90+ có lẽ phù hợp khá tốt với những gì bạn cần và trình biên dịch F90 có thể tự động song song hóa một số vòng lặp.

Ngoài ra, bạn có thể muốn kiểm tra Octave hoặc Matlab, có sparse()chức năng này. Nếu được sử dụng đúng cách, chúng sẽ có thể chạy khá nhanh.


Tôi chắc chắn sẽ xem xét Fortran năm 2008. Tôi đã có ma trận 'gần như tridia chéo'. Tôi đã đề cập ở trên rằng tôi đang sử dụng thuật toán Sherman Morrison.
WiFO215

CẬP NHẬT: Tôi đã cố gắng đọc lên ScaLAPACK vì nó trông rất thú vị. Nó cho phép một người đảo ngược các ma trận bằng cách sử dụng một từ buzz mà tôi đã nghe rất nhiều "song song". Tất cả những gì tôi biết là nó sử dụng tất cả các bộ xử lý của tôi và do đó nó đi nhanh hơn, nhưng hơn thế nữa, tôi không hiểu nó là gì. Xuất phát từ một nền tảng vật lý, sự tiếp xúc duy nhất với máy tính mà tôi có là với 101 khóa học về Python và C. Học cách sử dụng điều này sẽ mất thời gian. Các tài liệu chính nó không cho vay để đọc sạch.
WiFO215

CẬP NHẬT 2: Người đàn ông! Điều ScaLAPACK này trông thực sự phức tạp. Tôi không hiểu đầu hoặc đuôi của những gì trên trang web. Tôi chỉ đơn giản là bơi trong tất cả các thông tin.
WiFO215

CẬP NHẬT 3: Được rồi, tôi đã xem qua các đề xuất khác về PETSc và Trilinos. Cuộc gọi cuối cùng của tôi là tôi không nghĩ rằng tôi sẽ sử dụng chúng ngay bây giờ vì chúng trông rất phức tạp. Điều đó không có nghĩa là tôi sẽ không đọc chúng. Tôi sẽ bắt đầu đọc chúng ngay bây giờ, nhưng đến khi tôi hiểu và có khả năng thực hiện chúng, nhiều tháng sẽ trôi qua. Tôi sẽ mở một chủ đề riêng cho các câu hỏi của tôi ở trên vì tôi gặp khó khăn với nó. Nhưng đó là cho sau này. Bây giờ, tôi quay lại để giải quyết câu hỏi 1.
WiFO215

Tôi đã cập nhật câu trả lời của mình.
Dan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.