Решение уравнения Шредингера¶
Стационарное уравнение Шредингера для одномерной потенциальной ямы решается как краевая задача. Решение должно удовлетворять набору условий:
- Непрерывно и непрерывно дифференцируемо
- Ограничено
- Интегрируемо с квадратом
В свзи с этим решение УШ выполняют по следующему алгоритму:
- Задают значение энергии Е
- Выбирают интервал, на котором будет решаться УШ (точки положительной и отрицательной бесконечностей)
- Задают условия на левом и правом концах интервала (обычно значения функции и производной вблизи машинного 0)
- Решают задачу Коши для УШ слева и справа, так, чтобы абсциссы конечных точек совпадали.
- Масштабируем (умножаем на число) одну из функций, чтобы значения обеих функций в точке соприкосновения совпадали (непрерывность).
- Сравниваем производные слева и справа в точке сшивки. Если равны, то полученная функция - волновая функция, а энергия - энергетический уровень такой системы.
- Если производные не совпадают, то меняем значение энергии (например с некоторым шагом).
После получения решения нужно проверить, что шаг интегрирования и выбор «бесконечностей» не влияют на полученный результат.
Фрагменты кода.
Задаем силы:
def force(psi, E): """ force function [dx/dx, dpsi/dx, d2psi/dx2] for psi vector [x, psi, psi'] """ return np.array([1.0, psi[2], (V(psi[0])-E)*psi[1]])
Делаем один шаг:
def step(f, x, h, E): """ one step by Runge-Kutta method """ kt1=f(x, E)*h kt2=f(x+kt1/2., E)*h kt3=f(x+kt2/2., E)*h kt4=f(x+kt3, E)*h xn=x+(kt1+2.*kt2+2.*kt3+kt4)/6. return xn
Решаем задачу Коши, результат - список точек (координата, функция, производная):
def solve(f, psi, xs, N, E): """f - function, psi - initial conditions, xs - end point, N - number of points """ h=(xs-psi[0])/N pm=[psi] for i in range(N): psi = step(f, psi, h, E ) pm.append(psi) return pm
Считаем функция справа и слева и находим вронскиан в точке сшивки:
def wronsk(E): """ calculate Wronskian for two parts of solution """ Xm, Xp = -20.0, 20.0 # effective infinities Pm, Pp = 1.0e-15, 1.0e-15 # value of function on effective infinities N = 500 xs = 0.0 #match point psi = np.array([-20., 1.0e-15, 1.0e-15*(V(-20)-E)]) fleft = solve(force, psi, xs, N, E) psi = np.array([20., 1.0e-15, -1.0e-15*(V(20)-E)]) fright = solve(force, psi, xs, N, E) return fleft[-1][2]*fright[-1][1]-fleft[-1][1]*fright[-1][2]
Поиск нуля функции методом деления отрезка пополам:
def zero(wronsk, El, d, delta): """ find zero of wronsk function in Er...Er+d range, with delta precision """ wl=wronsk(El) Er=El+d wr=wronsk(Er) while (abs(Er-El)>delta): En=(El+Er)/2. wn=wronsk(En) if (wn == 0): return En if (wl*wn<0): Er = En wr = wn if (wn*wr<0): El = En wl = wn return (El+Er)/2.