Численное решение уравнения Шредингера - собственные значения

Это мой первый вопрос здесь. Я пытаюсь численно решить уравнение Шредингера для потенциала Вудса-Саксона и найти собственные значения энергии и собственные функции, но я не понимаю, как именно это нужно сделать.

В прошлом я решал некоторые задачи с начальными значениями, используя итерационные методы, такие как Рунге-Кутта. Я читал, что метод Нумерова — это способ решения уравнения Шредингера, но Википедия также описывает его как итерационный метод для задач с начальными значениями.

Как использовать его для решения задачи на собственные значения?

Меня это смущает по следующим причинам:

  • Разве итеративное решение ДУ не потребует знания собственных значений энергии для использования в качестве входных данных для расчета? Я еще не знаю собственных значений; это именно то, что я пытаюсь вычислить.
  • Если бы я сделал это, разве я не получил бы просто уникальное решение вместо семейства собственных функций и собственных значений?

Я видел некоторые упоминания о том, что «трехдиагональные матрицы» каким-то образом генерируются, но я не уверен, какими будут элементы этой матрицы или как это относится к проблеме. Леандро М. упомянул, что «дискретизация определяет конечномерную (матричную) проблему собственных значений». Кажется, это правильный путь, по которому я должен идти, но я не смог найти ничего, что явно объясняло бы этот процесс или то, как строится матрица. Если это правильная процедура, то как строится такая матрица?

Будет ли вычислительная наука лучшим местом для ответа на этот вопрос?
@DavidZ Удовлетворительна ли теперь формулировка вопроса?
Намного лучше, да. (и я заметил, что с тех пор, как вы его отредактировали, вопрос уже накопил еще несколько голосов за повторное открытие, так что, вероятно, он будет повторно открыт даже без меня, именно так и должна работать система!) Кстати, извините, я не получил посмотреть на это раньше; Прошлой ночью я оказался гораздо более занят, чем думал.
Если вы можете решить задачи с начальными значениями, вы можете решить задачу с граничными значениями, используя метод стрельбы .
Я не смог найти ничего, что явно объясняло бы этот процесс или то, как строится матрица. Тогда вы не удосужились открыть книгу о числовых УЧП.
Почему бы не использовать вместо этого вариационный метод?

Ответы (2)

Я рад, что наконец могу ответить на этот вопрос.

Метод Нумерова, описанный в Википедии, здесь не подходит . Чтобы дать вам представление о том, как действовать, давайте начнем с упрощенной версии метода. Что я собираюсь сделать, так это просто наивно дискретизировать дифференциальный оператор, например так:

г 2 г Икс 2 ψ ψ ( Икс г ) 2 ψ ( Икс ) + ψ ( Икс + г ) г 2 ψ н 1 2 ψ н + ψ н + 1 г 2

Последнее уравнение — это просто определение — я рассматриваю пространство как решетку с точками. г врозь и я звоню ψ н значение волновой функции на н й точке.. Теперь уравнение Шредингера читается в этих обозначениях:

2 2 м ψ н 1 2 ψ н + ψ н + 1 г 2 + В н ψ н знак равно Е ψ н

Но это матричное уравнение! Позвольте мне быть более явным:

2 2 м г 2 ( 2 1 1 2 1 1 2 1 1 2 ) ( ψ 1 ψ 2 ψ Н 1 ψ Н ) + ( В 1 В 2 В Н 1 В Н ) ( ψ 1 ψ 2 ψ Н 1 ψ Н ) знак равно Е ( ψ 1 ψ 2 ψ Н 1 ψ Н )

Конечно, я должен был выбрать какое-то целое число Н это просто соответствует помещению системы в ящик, который «достаточно велик», чтобы иметь конечную систему.

Теперь ясно, что у вас есть задача на собственные значения матрицы вида

А ψ знак равно Е ψ

и вы можете продолжать диагонализовать его любым способом, который вы выберете. Обратите внимание, что мы называем А трехдиагональная матрица по понятным причинам. Возможно, вы захотите сначала позаботиться о граничных условиях — вы сделаете это, установив ψ 1 знак равно ψ н знак равно 0 прежде чем построить матрицу, которая соответствует установке нуля в первом и последнем столбцах. Это даст вам несколько ложных собственных функций с нулевым собственным значением, которые вы можете просто отбросить. Если у вас разные граничные условия, вам не повезло — я не знаю, как заставить это работать вообще.

Теперь вам просто нужно повторить вышеописанное с полным методом Нумерова, который будет немного сложнее, и все готово.

Кажется, это то, что вы ищете, но, конечно, это не единственный способ сделать это. Гриффитс описывает один из них, называемый «вилять собакой», который состоит из следующего: вы угадываете начальное значение энергии и вычисляете волновую функцию, как хотите (например, RK). Скорее всего, это не будет собственным значением, поэтому волновая функция взорвется на бесконечности. Это может пойти на + для больших Икс или это может пойти на . Теперь вы медленно меняете энергию до тех пор, пока поведение на бесконечности не «перевернется», то есть пока хвост не «виляет». Это позволит вам ограничить значение одного собственного значения энергии и даст вам форму волновой функции до некоторого максимального размера, который увеличивается с выбранным значением. Е приближается к точному собственному значению.

Вам лучше установить ψ 0 знак равно ψ Н + 1 знак равно 0 вместо того ψ 1 знак равно ψ Н знак равно 0 (т.е. поместите точку с р знак равно 0 в н знак равно 0 ). Таким образом, вы специально исключаете точки, которые на самом деле не нужны, и фактически ваша матрица уже представляет такой выбор. Тогда не будет ложных решений, и в качестве бонуса вы также сможете решать проблемы кулоновского потенциала (поскольку сингулярность исключается из точек, для которых вы решаете). Также обратите внимание, что, поскольку проблема является трехмерной, и вы решаете радиальную часть волновой функции, найденное решение следует разделить на р .

Вы можете искать собственные значения, используя метод деления пополам.

Предварительные сведения: чтобы получить собственные значения методом Нумерова, вам необходимо знать волновую функцию на границах. Обычно это означает, что вам нужно установить потенциал на бесконечность на границах, следовательно, обнулить волновую функцию в этих точках. Для вашего потенциала измените его следующим образом:

V = бесконечность, если -50 фм>r>50 фм V = 0, если |r|>8,5 фм V = потенциал Вуда в противном случае

Суть дела: теперь напишите программу для расчета волновой функции в приведенном выше потенциале, используя любую произвольную энергию в области -50 фм.

Вот код Python, который находит собственное значение в заданном интервале (E1, E2), если оно существует.


import numpy as np

rmin = 0 rmax = 0

def vradial(r): global rmin global rmax if r < rmin or r > rmax: #This is important. >= and <= won't work #as they interfere with the bc on psi return np.inf elif r > rmin and r < rmin + 2: return (r - rmin - 2)**2 elif r > rmax - 2 and r < rmax: return (r - rmax + 2)**2 else: return 0

def f(l,E,r): """Calculate the f(r) in the Schrodinger equation of the form D2(Psi(r)) = f(r)Psi(r)""" if r == 0: return np.inf return l*(l+1)/(r**2) + vradial(r) - E

def psitophi(psi, l, E, r, delta): if psi == 0: return 0 #To handle the 0*infinity case of boundary return psi*(1-(f(l, E, r)*delta**2)/12)

def phitopsi(phi, l, E, r, delta): #if phi == 0: return 0 return phi/(1-(f(l, E, r)*delta**2)/12)

def calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, E):

psiarray = []
r = np.linspace(rmin, rmax, N)
delta = r[1]-r[0]

#Assume psi(rmin) = psibcmin and psi(rmin+delta) = 1 and then
#calculate phi0 and phi1
psiarray.append(psibcmin)
psiarray.append(1)
phi0 = psitophi(psiarray[0], l, E, r[0], delta) #r[0]=rmin
phi1 = psitophi(psiarray[1], l, E, r[1], delta)

#Now populate the psiarray for each value of r
for i in range(2, len(r)):
    phi2 = 2*phi1 - phi0 + (delta**2)*f(l, E, r[i-1])*psiarray[i-1]
    psi = phitopsi(phi2, l, E, r[i], delta)
    psiarray.append(psi)
    phi0 = phi1
    phi1 = phi2

return r, psiarray

def normalize(delta, psi): area = 0 for i in range(1,len(psi)-1): area = area + abs(psi[i])*delta

for i in range(len(psi)):
    psi[i] = psi[i]/area

return psi

def locateEvalueInBracket(rmin, rmax, N, psibcmin, psibcmax, l, e1, e2,\ tol): #Any value of Psi smaller than psi is while abs(e2-e1) > tol:
r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, e1) psi1 = psi.pop() r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, e2) psi2 = psi.pop()

    if psi1*psi2 < 0:
        emid = e1 + (e2 - e1) * 0.5
        r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, emid)
        psimid = psi.pop()

        if psimid*psi1 < 0:
            e2 = emid

        elif psimid*psi2 < 0:
            e1 = emid
    elif psi1*psi2 > 0:
        print "There are either no eigenvalues or too many of them in"+\
        " the given energy interval. For e1={} psi={} and e2={} psi=".format(e1, psi1, e2)+\
        "{}".format(psi2)
        return e1,e2
return e1,e2

def main(): import sys import matplotlib.pyplot as plt global rmin global rmax

e1 = float(sys.argv[1])
e2 = float(sys.argv[2])
l = int(sys.argv[3])
if l == 0:
    rmin = -1
else:
    rmin = 0
tol =1e-5
rmax = 1
psibcmin = 0
psibcmax = 0
N = 100

e1, e2 = locateEvalueInBracket(rmin, rmax, N, psibcmin, psibcmax,\
        l, e1, e2, tol)

fig = plt.figure()
ax = fig.add_subplot(111)
r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, e1)
ax.plot(r,psi, 'o')
r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l ,e2)
ax.plot(r, psi, 'g')
ax.set_title("l = {} and E_blue = {}, E_green={}".format(l,e1,e2))
plt.show()

if name=="main": main()

Пожалуйста, используйте разумные отступы при копировании и вставке приведенного выше кода. Я не могу понять, как заставить его красиво отображать здесь. Я пришлю вам копию, если вы напишите мне.