Хабрахабр

Квантовые траектории и с чем их едят

Эта небольшая заметка про то, как рисовать красивые картинки, ну и немного про физику, о которой редко говорят, про бомовскую квантовую механику.
image

Небольшое введение

Как нам любит рассказывать всякая научная фантастика и псевдонаучная ерунда, типа фильма «Секрет», законы микромира, очень сильно отличаются от привычных нам, классических.
В мире квантовой механики правит всем вероятность, задаваемая волновой функцией $\psi$ (интересующиеся деталями могут заглянуть, например, в пост «Мюонный катализ с точки зрения квантовой химии. Часть I: обычный водород vs. мюонный водород»).
Из вероятностных свойств квантмеха растут ноги всяких забавных вещей, типа котов Шрёдингера, принципов неопределённости Гейзенберга и неравенств Белла.

Чтобы прояснить эту ситуацию, физики потратили много времени, но так и не справились с этим. Но все эти картинки со всякими орбиталями электрона не давали ответа на вопрос «как же электрон летит в пространстве». И, в отличие от фейнмановских интегралов по траекториям, эта траектория у каждой частицы ровно одна. Зато Дэвид Бом (известный многим по эффекту Ааронова — Бома) окончательно создал один из формализмов квантовой механики (имени себя), в котором всё-таки есть траектории, по которым движется квантовая частица. Это свойство принципиально позволяет отследить движение частиц, и сравнить движение классических и квантовых частиц, чем мы и займёмся в этой заметке.

не только формализм

Собственно, сам формализм никому особо не интересен, но из этого формализма можно построить одну из интерпретаций квантовой механики, которую, из-за кажущийся простоты классической механики любят некоторые фрики (не многие, ибо въехать в это дело не очень просто, да и известна/интересна эта часть квантмеха только особым извращенцам).
Эту (как и другие) интерпретацию мы обсуждать не будем.

Классические и квантовые траектории

Мы будем рассматривать достаточно скучную систему: один электрон в поле нескольких протонов. Об этой системе, а также о классической и квантовой механике можно почитать в первой и второй частях постов «Мюонный катализ с точки зрения квантовой химии».

Классическая задача о движении частицы в некотором потенциале даётся вторым законом Ньютона:

$m \ddot = F$

где m — масса частицы, x — координата, F — сила, действующая на частицу, а $\ddot{x} = \frac{d^2 x}{dt^2}$ — вторая производная координаты частицы по времени, или ускорение. Если в системе действуют только потенциальные силы, то силу можно выразить через новую сущность, потенциальную энергию V как

$F = - \frac{dV}{dx}$

В нашем случае, электрона в поле нескольких протонов,
image
где электрон взаимодействует с каждым из протонов по закону Кулона

$V(R) = - k e^2/R$

, где k — коэффициент, равный 1 в атомных единицах, e — заряд электрона, а R — расстояние от электрона до протона.
В этом случае суммарный потенциал, действующий на электрон будет равен

$V = \sum_{n=1}^N V_n(R_n) = - \sum_{n=1}^N \frac{k e^2}{R_n} \ ,$

где индекс n нумерует протоны (всего протонов N штук), а Rn — расстояние от электрона до n-го протона.

Если электрон будет лететь слишком быстро, то он вырвется за пределы притяжения протона(ов) и улетит на бесконечность, а если энергии будет чуть-чуть, то он будет вечно бултыхаться туды-сюды в поле одного из ядер, никогда не посещая другие.
Численно решить диффур, который представляет из себя второй закон Ньютона, задача халтурная, главное задать начальные положение и скорость.

Лучистое трение

Если бы мы учли лучистое трение, которое возникает из-за того, что при движении с ускорением, электрон будет часть своей энергии движения отдавать электромагнитному полю, излучая его куда-то, то электрон в итоге скатился бы на ядро за какое-то время.

Так что происходит в классике, мы знаем.

помимо классического потенциала, на неё будет действовать ещё и другая сущность: квантовый потенциал $V_\mathrm{Q}$, имеющий (в 1D случае) вид
А что же будет в бомовской динамике?
В этом случае частица тоже будет двигаться по второму закону Ньютона с потенциалом $V = V_\mathrm{C} + V_\mathrm{Q}$, где $V_\mathrm{C}$ — классический потенциал из обычного закона Ньютона, который в нашем случае имеет вид, данный выше.
Т.е.

$V_\mathrm{Q} = - \frac{\hbar^2}{2mA} \frac{ d^2A}{ dx^2}$

где A — это амплитуда (модуль) волновой функции $A = |\psi|$ ($\psi = A \exp(i \varphi)$, где $\varphi$ — фаза волновой функции).
Значит, чтобы получить уравнение движения квантовой частицы, нам всё равно нужно знать что-то о волновой функции.

Про скрытые параметры

Но поскольку скрытый параметр (волновая функция) — нелокален, то результаты вычислений в этом формализме всё равно удовлетворяют вышеупомянутым неравенствам Белла.
Формализм Бома является теорией со скрытыми параметрами.

В случае одного протона нам известно (см., например, тут) точное выражение волновой функции электрона в основном (1s) состоянии:

$\psi(R) = \exp(-R)$

О нормировке

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

В случае нескольких протонов, в рамках метода молекулярных орбиталей как комбинаций атомных орбиталей (МО ЛКАО, см. тут) основное состояние с достаточной степенью точности будет даваться суммой 1s-орбиталей каждого из атомов:

$\psi \approx \sum_{n=1}^N \psi_n(R_n) = \sum_{n=1}^N \exp(-R_n)$

Теперь, чтобы узнать квантовый потенциал, нужно всего-то воспользоваться этим выражением.

Ну<s>д</s>жные вычисления

В итоге наш квантовый потенциал мы можем записать как

$V_\mathrm{Q} \approx \frac{\hbar^2}{m} \sum_{n=1}^N \frac{ \exp(-R_n)}{R_n}$

и с этим выражением мы можем уже гонять бомовскую динамику электрона в поле многих протонов.

Реализация

Для этого всего безобразия был написан код на питоне, он доступен тут:

Код на питоне

from math import *
import numpy as np cutoff=5.0e-4
Quantum=True def dist(r1,r2): return np.dot((r1-r2), (r1-r2)) def Vc(r, r0): if dist(r, r0)>=cutoff: return -1.0/dist(r, r0) else: return -1.0/cutoff rH=[]
#h1
#rH.append(np.array([ 0.0, 0.0, 0.0])) #h2
rH.append(np.array([-1.0, 0.0, 0.0]))
rH.append(np.array([+1.0, 0.0, 0.0])) def Vat(r): V=0.0 for rh in rH: V+=Vc(r,rh) return V def PsiA(r): psi=0.0 for rh in rH: if dist(r, rh)<1.0e3: psi+=np.exp(-dist(r, rh)) return psi def Vq(r): vq=0.0 for rh in rH: if dist(r, rh)>=cutoff: vq-=2.0*np.exp(-dist(r, rh))/dist(r, rh) else: vq-=2.0*np.exp(-cutoff)/cutoff vq*=(-0.5) # -0.5*hbar**2/me return vq def GradF(F, r): grad=np.zeros(3) dx=0.1 for i in range(0,3): dr=np.zeros(3) dr[i]=dx #print(dr) #print(F(r+dr)-F(r-dr)) grad[i]+=(F(r+dr)-F(r-dr))/(2.*dx) return grad dt=0.001
tmax=2.0e1
DR=1.0
dx=0.001 MaxR=10.0 t=0.0 cent=np.zeros(3) Ntrj=30
m=1.0 def GenRvBox(DX): return np.random.uniform(-DX,+DX,3) def GenRvSph(DX): r=np.random.uniform(0.0,DX) phi=np.random.uniform(0.0,2.0*np.pi) theta=np.random.uniform(0.0,np.pi) x=r*np.sin(theta)*np.cos(phi) y=r*np.sin(theta)*np.sin(phi) z=r*np.cos(theta) return np.array([x,y,z]) for ntrj in range(0,Ntrj): if Quantum: outf=open("bmd_%05i" % (ntrj) + ".trj", "w") else: outf=open("cmd_%05i" % (ntrj) + ".trj", "w") nat=np.random.randint(0,len(rH)) r=rH[nat]+GenRvSph(DR) rprev=r+GenRvBox(dx) outf.write("%15.10f %15.10f %15.10f\n" % tuple(r)) t=0.0 while t<=tmax and dist(r,cent)<=MaxR: F= -GradF(Vat, r) if Quantum: F-= GradF(Vq, r) rnew= 2.*r - rprev + (F/m)*dt**2 rprev=r r=rnew outf.write("%15.10f %15.10f %15.10f\n" % tuple(r)) t+=dt outf.close() exit()

Мы же только обсудим несколько моментов.
Интегрируется второй закон Ньютона при помощи алгоритма Верле:

$x(t + \Delta t) = 2 x(t) - x(t - \Delta t) + \frac{F(t)}{m} \Delta t^2$

Начальное положение генерируется путём случайного выбора одного из протонов, вокруг него случайно выбирается направление (используя сферические координаты). Чтобы задать начальную скорость, нужно задать ещё одно, предыдущее положение. Оно выбирается ещё при помощи одного маленького случайного вектора.

Включая/выключая квантовый потенциал, мы переходим в квантовый/классический режимы движения.

Ну а дальше, можно построить красивые картинки, используя Gnuplot, для атома водорода
image
и для молекулы H2+
image

В квантовом же случае (нижние, розовые), квантовый потенциал позволяет электронам гулять существенно дальше от ядра, а в случае молекулы H2+, позволяет бегать от одного протона к другому, что является прямой визуализацией химических связей. Как видно, классические траектории (верхние, синие) или очень локализованы, или, если слишком быстро заставить двигаться электрон, убегают от ядер.

Для удобства выбора такой палитры можно, например, воспользоваться сайтом https://www.color-hex.com/
Пример скрипта приведён ниже.
Пару слов о построении картинок: чтобы создать эффект неона, каждая траектория рисуется много раз, от тонкой белой, до толстой чёрной, через тени интересующего цвета.

Скрипт для Gnuplot

unset key
set xyplane relative 0

unset box

set view map

set size ratio -1

unset border
unset xtics
unset ytics

set terminal pngcairo size 2160,4096 backgr rgb "black"
set output "tmp.png"

0
maxiC=29
maxiQ=29
splot \
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 30. yshift=-5. 0 lc rgb "#071b33" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 17. 0 lc rgb "#030d19" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 18. 0 lc rgb "#0e3766" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 15. 0 lc rgb "#0a294c" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 16. 0 lc rgb "#155399" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 13. 0 lc rgb "#11457f" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 14. 0 lc rgb "#1c6fcc" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 11. 0 lc rgb "#1861b2" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 12. 0 lc rgb "#238bff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 9. 0 lc rgb "#1f7de5" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 10. lc rgb "#4ea2ff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 7. 0 lc rgb "#3896ff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 8. lc rgb "#7bb9ff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 5. lc rgb "#65adff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 6. lc rgb "#a7d0ff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 3. lc rgb "#91c5ff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 4. lc rgb "#d3e7ff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 1. lc rgb "#bddcff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 2. 5 lc rgb "#ffffff" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 30. lc rgb "#e9f3ff" not,\
for [i=0:maxiC] sprintf("cmd_%05i.trj", i) w l lw 0. 0 lc rgb "#330c27" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 17. 0 lc rgb "#190613" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 18. 0 lc rgb "#66184f" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 15. 0 lc rgb "#4c123b" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 16. 0 lc rgb "#992476" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 13. 0 lc rgb "#7f1e63" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 14. 0 lc rgb "#cc309e" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 11. 0 lc rgb "#b22a8a" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 12. 0 lc rgb "#ff3dc6" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 9. 0 lc rgb "#e536b2" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 10. lc rgb "#ff63d1" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 7. 0 lc rgb "#ff50cb" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 8. lc rgb "#ff8adc" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 5. lc rgb "#ff77d7" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 6. lc rgb "#ffb1e8" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 3. lc rgb "#ff9ee2" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 4. lc rgb "#ffd8f3" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 1. lc rgb "#ffc4ed" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 2. 5 lc rgb "#ffffff" not
lc rgb "#ffebf9" not,\
for [i=0:maxiQ] sprintf("bmd_%05i.trj", i) u 1:($2+yshift):3 w l lw 0.

Заключение

Бомовские траектории, хоть и сложны в понимании и вычислении, позволяют рисовать красивые картинки, которые показывают, насколько квантовая механика веселее и богаче классической.

🙂 Если есть комментарии, вопросы, предложения: пишите.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть