У мене є кілька питань стосовно наступного:
Я намагаюся вирішити рівняння Шредінгера в 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