Последний раз редактировалось kw_artem 30.04.2015, 12:57, всего редактировалось 2 раз(а).
Тема очень интересная, и не верится, что к ней пропал интерес участников (особенно в связи с недавней темой про моделирование двухщелевого эксперимента): уверен, интересно не только самому, но и всем, наверняка просто время иногда не находится, поэтому решил попробовать сам. Посмотрел Кунина, сделал по нему одномерную схему с сохранением унитарности, вот что получилось (с Mathematic-ой знаком менее месяца): (Оффтоп)
Код: TMA[V_, m_, \[HBar]_, \[CapitalDelta]t_, \[CapitalDelta]x_] := Module[{a, b, P, Q, d, ans}, a = \[HBar]/(4 m \[CapitalDelta]x^2); b = V/\[HBar] + 2 a - I/\[CapitalDelta]t; Function[{\[Psi] }, d = ListConvolve[{1, -2, 1}, \[Psi]]; PrependTo[d, d[[1]]]; AppendTo[d, d[[-1]]]; d = I \[Psi]/\[CapitalDelta]t - a d; P = Array[0 &, n]; Q = P; ans = Array[0 &, n + 1]; P[[1]] = a/b[[1]]; Q[[1]] = -d[[1]]/b[[1]]; Do[P[[i]] = a/(b[[i]] - a P[[i - 1]]), {i, 2, n - 1}]; Do[Q[[i]] = (a Q[[i - 1]] - d[[i]])/(b[[i]] - a P[[i - 1]]), {i, 2, n}]; Do[ans[[i]] = P[[i]] ans[[i + 1]] + Q[[i]], {i, n, 1, -1}]; Most[ans]]]
(*Пример*) n = 100; V = Array[0&, n];
step = TMA[V, 100., 1., .1, .1]; \[Psi]0 = Array[Exp[I 2 \[Pi] 6 #/40] Exp[-(# - 100)^2/(40)]/ Sqrt[2. \[Pi] (40)] &, n]; First@Timing[steps = NestList[step, \[Psi]0, p = 1000]] (*8.469*) someSteps = Abs /@ steps[[;; ;; Floor[p/200]]]; First@Timing[ anim = ListAnimate[ frames = ListPlot[{#, k ArrayPad[V, -1]}, Joined -> True, ColorFunction -> Automatic, PlotRange -> 0.1] & /@ someSteps, AnimationRunning -> False, DefaultDuration -> 13]] anim
,а на основе этой одномерной -- двухмерную (с "переменными направлениями"): (Оффтоп)
Код: MakeSchrodingerTimeStep[V_, m_, \[CapitalDelta]t_, \[CapitalDelta]x_] := Module[{a, b, tmp}, a = \[HBar]/(4 m \[CapitalDelta]x^2); b = V/\[HBar] + 2 a - I/\[CapitalDelta]t; tmp = Array[0 &, {n, n}]; Function[{\[Psi]}, Do[tmp[[i]] = LineTMA[\[Psi][[i]], a, b[[i]], \[CapitalDelta]t], {i, 1, n}]; Do[tmp[[All, i]] = LineTMA[tmp[[All, i]], a, b[[All, i]], \[CapitalDelta]t], {i, 1, n}]; tmp]]
LineTMA := Module[{P, Q, d, ans}, Function[{\[Psi], a, b, \[CapitalDelta]t}, d = ListConvolve[{1, -2, 1}, \[Psi]]; PrependTo[d, d[[1]]]; AppendTo[d, d[[-1]]]; d = I \[Psi]/\[CapitalDelta]t - a d; P = Array[0 &, n]; Q = P; ans = Array[0 &, n + 1]; P[[1]] = a/b[[1]]; Q[[1]] = -d[[1]]/b[[1]]; Do[P[[i]] = a/(b[[i]] - a P[[i - 1]]), {i, 2, n - 1}]; Do[Q[[i]] = (a Q[[i - 1]] - d[[i]])/(b[[i]] - a P[[i - 1]]), {i, 2, n}]; Do[ans[[i]] = P[[i]] ans[[i + 1]] + Q[[i]], {i, n, 1, -1}]; Most[ans]]]
\[HBar] = 1.; n = 100; V = Array[0 &, {n, n}]; step = MakeSchrodingerTimeStep[V, 100., 1., .1]; \[Sigma] = 1.5; p0 = .75; \[Psi]0 = Array[0.5 Exp[ I p0 #2/\[HBar] - ((#1 - 50)^2 + (#2 - 25)^2)/ 4/\[Sigma]^2]/(2 \[Pi] \[Sigma]^2)^(1/4) &, {n, n}]; First@Timing[steps = NestList[step, \[Psi]0, p = 100]] (*8.469*) someSteps = steps[[;; ;; Ceiling[p/100]]]; Norm[Flatten[#]] & /@ {\[Psi]0, Last@steps}
AmplitudeCF[zoom_] := Module[{f}, f = Compile[{{z, _Complex}}, Block[{absz = Abs[z] 1./zoom}, {Arg[z]/6.283185307179586`, 1 - Tanh[0.5 absz], Tanh[2 absz]}]]; Hue @@ f[#] &]
First@Timing[ anim = ListAnimate[ frames = ArrayPlot[#, ColorFunction -> AmplitudeCF[.1], ColorFunctionScaling -> False] & /@ someSteps, AnimationRunning -> False, DefaultDuration -> 7]] anim
Разные начальные условия и вид потенциала: Код: V = Array[0 &, {n, n}];(*Array[0&,{n,n}];*) (*Array[If[((#1-50)^2+(#2-50)^2)<25^2,0,5]&,{n,n}];*)(*Array[0.002((#\ 1-50)^2+(#2-50)^2)&,{n,n}];*)(*5(Array[If[49<#2<52,1,0]&,{n,n}]-\ ArrayPad[{{1,1},{1,1},{1,1},{0,0},{0,0},{0,0},{0,0},{1,1},{1,1},{1,1}}\ ,{{n/2-5},{n/2-1}}]);*) (*Array[If[n/2<#<n/2+5,1.4,0]&,n+2];*)(*5(Array[If[49<#2<52,1,0]&,{n,\ n}]-ArrayPad[{{1,1},{1,1}(*,{1,1},{1,1},{1,1},{1,1}*)},{{n/2-1},{n/2-\ 1}}]);*)
\[Psi]0 = Array[Exp[I 1 #2] + Exp[-I 1 #2] &, {n, n}];(*Array[wk/.{x\[Rule]#2,y\[Rule]#1}&,{n,n}];*)(*Array[Exp[I 2 \ \[Pi] 3 #2/40] Exp[-((#1-50)^2+(#2-50)^2)/(2 20)]/Sqrt[2. \[Pi] \ (20)]&,{n,n}];*) (*Array[0.5Exp[I p0 #2/\[HBar]-((#1-50)^2+(#2-25)^2)/4/\[Sigma]^2]/(2\ \[Pi] \[Sigma]^2)^(1/4)&,{n,n}];*)
Последняя, как предполагалось, считает дольше, но может можно код как-то оптимизировать, например, через функцию Compile, с ней я не очень разобрался. Картинки выложу чуть позже.
|