Рівняння Шродінгера з періодичними граничними умовами


9

У мене є кілька питань стосовно наступного:

Я намагаюся вирішити рівняння Шредінгера в 1D за допомогою дискретизації кривошипа Нікольса з подальшим переворотом отриманої тридіагональної матриці. Зараз моя проблема переросла в проблему з періодичними граничними умовами, і тому я змінив свій код, щоб використовувати алгоритм Шермана Моррісона.

Припустимо, vце мій РЗС на кожному етапі, коли я хочу перевернути тридіагональну матрицю. Розмір v- це кількість точок сітки у мене за місцем. Коли я встановив v[0]і v[-1]з точки зору один одного , як це потрібно в моїй періодичної ситуації, моє рівняння підриває. Я не можу сказати, чому це відбувається. Я використовую python2.7 та вбудований scipy в розв'язку для вирішення рівняння.

Це підводить мене до мого другого питання: я використовував python, оскільки це мова, яку я найкраще знаю, але мені здається досить повільною (навіть з оптимізаціями, запропонованими numpy та scipy). Я спробував використовувати C ++, оскільки я досить добре знайомий з ним. Я думав, що буду використовувати GSL, який був би оптимізований BLAS, але не знайшов жодної документації для створення складних векторів або вирішення тридіагональної матриці з такими складними значущими векторами.

Мені б хотілося, щоб в моїй програмі були об'єкти, оскільки я вважаю, що для мене це буде найпростішим способом пізніше узагальнити, щоб включити з'єднання між хвильовими функціями, таким чином я дотримуюся об'єктно-орієнтованої мови.

Я міг би спробувати написати тридіагональну розв'язку матриці вручну, але у мене виникли проблеми, коли я це робив у python. Коли я еволюціонував у великі часи все точнішими та точнішими кроками часу, помилка накопичувалась і викликала дурниці. Маючи це на увазі, я вирішив використовувати вбудовані методи.

Будь-яка порада високо цінується.

EDIT: Ось відповідний фрагмент коду. Позначення запозичено зі сторінки Вікіпедії в рівнянні тридіагональної матриці (TDM). v - RHS алгоритму кривошипного кривошипа на кожному етапі. Вектори a, b і c - діагоналі TDM. Відкоригований алгоритм періодичного випадку походить із CFD Wiki . Я трохи перейменував. Те, що вони назвали u, v Я назвав U, V (з великої літери). Я назвав q доповненням, y тимчасовим рішенням і власне рішення self.currentState. Присвоєння v [0] і v [-1] є тим, що викликає тут проблему, і таким чином було прокоментовано. Ви можете ігнорувати фактори гамми. Вони є нелінійними факторами, які використовуються для моделювання конденсатів Бозе Ейнштейна.

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
Це звучить (на перший погляд) як помилка у ваших періодичних граничних умовах. Хочете опублікувати фрагмент коду?
Девід Кетчесон

2
Ласкаво просимо на обмін стеками! Надалі, якщо у вас є кілька запитань, ви можете поставити їх окремо.
День

Також: Що саме ви маєте на увазі "встановити v [0] і v [-1] в плані один одного"? Ви встановлюєте векторні елементи рівні між собою після вирішення, або ви використовуєте не тридіагональний елемент для їх з'єднання?
День

Я додав свій код вище. Якщо щось незрозуміле, будь ласка, повідомте мене про це. Я пам’ятаю, що наступного разу розміщую окремі запитання.
WiFO215

Дякую! Трохи важко читати ваш код через форматування (дуже довгі рядки). Також коментування самої частини, на яку ви хочете, щоб люди звернули увагу, викликає заплутаність. Cod ви записуєте рівняння, які ви розв'язуєте (за допомогою MathJax), використовуючи те саме позначення, що і ваш код?
Девід Кетчесон

Відповіді:


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

Це я маю на увазі під «повільним циклом пітона». Python forнеприпустимо повільний для більшості числових програм, і Scipy / Numpy взагалі не впливають на це. Якщо ви збираєтесь використовувати python, цей внутрішній цикл повинен бути виражений у вигляді однієї чи двох функцій Numpy / Scipy, які ці бібліотеки можуть або не можуть надавати. Якщо вони не надають щось, що дозволяє переглядати такі масиви та отримувати доступ до сусідніх елементів, python - це неправильний інструмент для того, що ви хочете зробити.

Крім того, ви робите інверсію, а не рішення матриці-вектора. Інверсія матриці з наступним множенням матричного вектора набагато повільніше, ніж рішення матричного вектора. Це майже напевно річ уповільнює ваш код більше, ніж будь-що інше.

Якщо ви хочете скористатися C / C ++, GSL дещо бракує, коли мова йде про складну лінійну алгебру. Я рекомендую або використовувати BLAS або LAPACK безпосередньо, або використовувати бібліотеку типу PETSc або Trilinos. Якщо у вас встановлено MKL, ви можете також використовувати його. Ви також можете перевірити Fortran 2008, орієнтований на об'єкти.

Матриці ваші рідкі, тому ви хочете переконатися, що ви використовуєте розріджені бібліотеки.

Я б також сказав, що те, що ви тут робите, здається досить низьким, що орієнтація на об'єкти, мабуть, не повинна бути вашою основною проблемою. Масив Fortran 90+, мабуть, досить добре відповідає тому, що вам потрібно, і компілятори F90 можуть автоматично паралелізувати деякі цикли.

Також ви можете перевірити Octave або Matlab, які мають цю sparse()функцію. При правильному використанні вони повинні мати можливість працювати досить швидко.


Я, безумовно, загляну у Fortran 2008. У мене вже є «майже тридіагональна» матриця. Я вже згадував вище, що використовував алгоритм Шермана Моррісона.
WiFO215

ОНОВЛЕННЯ: Я намагався прочитати на ScaLAPACK, тому що це виглядає дуже цікаво. Це дозволяє перевернути матриці за допомогою гучного слова, яке я багато чув "паралельно". Все, що я знаю, це те, що він використовує всі мої процесори, і тому йде швидше, але поза цим я не розумію, про що йдеться. Починаючи з фізичного походження, я маю єдину експозицію до обчислень - це 101 курс в Python та C. Навчання, як це використовувати, потребує часу. Сама документація не піддається чистому читанню.
WiFO215

ОНОВЛЕННЯ 2: Людина! Ця річ ScaLAPACK виглядає дійсно складно. Я не розумію голову чи хвіст того, що є на веб-сайті. Я просто плаваю у всій інформації.
WiFO215

ОНОВЛЕННЯ 3: Добре, я переглянув інші рекомендації PETSc та Trilinos. Мій остаточний дзвінок полягає в тому, що я не думаю, що зараз буду використовувати це, оскільки вони виглядають дуже складними. Це не означає, що я не буду їх читати. Я зараз почну їх читати, але до моменту, коли я їх зрозумію та зможу їх реалізувати, минули б місяці. Я відкрию окрему тему для своїх запитань щодо вищезазначеного, оскільки у мене виникають труднощі з цим. Але це є на потім. Тепер я повернувся до вирішення лише питання 1.
WiFO215

Я оновив свою відповідь.
Дан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.