The point is to solve the eigensystem of the given Hamiltonian.
I tried ParametricNDSolve
combined with FindRoot
to search for eigenvalues as xslittlegrass did in his post Find eigen energies of time-independent Schrödinger equation in the first place. It gave almost perfect results,but then I found it very inconvenient for large amounts of eigenstate as xslittlegrass did.
Apparently some of the methods used in xslittlegrass's post won't work here directly. My potential is not a polynomial. I'm trying to adjust their methods but so far no luck.
I tried different approaches, including using the radial wavefunction of hydrogen atom as basis and change the Hamiltonian into a matrix, using finite difference method to convert it into a eigenvalue problem and so on. I then found out the new version of Mathematica added a new function called NDEigensystem
.
I tried those all and the outcome was just far away from what I expected. The closest one was the radial wavefunction of hydrogen atom, and it had about 10% error. The others didn't give me a proper result, not even close. As for NDEigensystem
, I don't know how to apply a Neumann condition to it. For harmonic oscillator, NDEigensystem
seems fine, but when I applied it to Coulomb potential, the results were terribly wrong. I supposed it's because of the improper boundary, I only attached a DirichletCondition
to it. But I couldn't add a Neumann condition.
Here's some details (with Jens' help, I've been able to apply NDEigensystem
to this, and I'm very grateful for that):
My potential is:
V[r_] = -(1/r) - (1.0415223038416566` E^(-0.9990999998788636` r))/r
Using the radial function of hydrogen atom, I wrote the following code:
a = 1; l = 0; nmax = 20; R[n_, r_] = FullSimplify[ 2/(a^(3/2) n^2 (2 l + 1)!) Sqrt[(n + l)!/(n - l - 1)!] E^(-1/2 (2 r)/(n a)) ((2 r)/(n a))^l Hypergeometric1F1[-n + l + 1, 2 l + 2, (2 r)/(n a)]] u[n_, r_] = r R[n, r] HMax = ParallelTable[NIntegrate[u[n, r] (-α^-1 \!\( \*SubscriptBox[\(∂\), \(r, r\)]\((u[i, r])\)\) + V[r] u[i, r]), {r, 0, ∞}, AccuracyGoal -> ∞, WorkingPrecision -> 30, PrecisionGoal -> 6], {n, 1, nmax}, {i, 1, nmax}]; N[Eigenvalues[HMax], 6]
And the results:
$$ \small\begin{array}{lllll}\{&-1.00113,& -0.15272,& -0.0619985, &-0.0336547, &-0.0211352,\\ &-0.0145071,& -0.0105749,& -0.00805096,& -0.00633443, &-0.00511407,\\ &-0.00421542, &-0.00353452,& -0.00300626,& -0.00258818, &-0.00225162,\\ &-0.00197665, &-0.0017491, &-0.00155863, &-0.00139753,& -0.00125987\quad\}\end{array}$$
The results,as mentioned above,were not so good.
This is the code using
NDEigensystem
as Jens showed (I'm only interested in eigenvalues,so I replacedNDEigensystem
withNDEigenvalues
, and I modified it a little to increase accuracy):AbsoluteTiming[ With[{shift = 10, d = 500, n = 20}, ev = NDEigenvalues[{shift f[r] + V[r] f[r] - 1/2 f''[r](*+NeumannValue[0,r\[Equal]d]*), DirichletCondition[f[r] == 0, True]}, f[r], {r, 0, d}, n, Method -> {"SpatialDiscretization" -> {"FiniteElement", \ {"MeshOptions" -> {"MaxCellMeasure" -> 0.001}}}, "Eigensystem" -> {"Arnoldi", MaxIterations -> Infinity}}]; evShifted = ev - shift]]
It took me
2540.17s
to complete the calculation.$$\small\begin{array}{lllll}\{&-1.33732, &-0.186434, &-0.0710575,& -0.0374072, &-0.023051, \\&-0.0156184, &-0.0112778, &-0.00852433, &-0.00666881, &-0.00535929,\\ &-0.0044008, &-0.00367822, &-0.00312003, &-0.00267982,& -0.0023228,\\ &-0.00199518, &-0.00162513, &-0.0011884, &-0.000689036,& -0.000132268\quad\}\end{array}$$
As I mentioned in the comments,in low energy levels, the results are good,but when it comes to higher levels, the accuracy drops rapidly. The accuracy only increased with
d
andMaxCellMeasure
, and the code becomes less efficient in the meantime.Oh, BTW, a
MaxCellMeasure
up to0.001
could be unnecessary. When I change it to0.01
, and increaseb
to1000
, I spent1511.33s
and have a much better result. For error tolerance only at 10E-7, I suppose biggerMaxCellMeasure
would be better.
And here's the binding energy I obtained from the NDSolve
& FindRoot
approach
$$\small\begin{array}{cccc} n & \text{energy} & n & \text{energy} \\ 1S & 1.33732 & 6S & 0.0156184 \\ 2S & 0.186434 & \dots & \\ 3S & 0.0710575 & 10S & 0.00535929 \\ 4S & 0.0374072 & 20S & 0.0012937 \\ 5S & 0.023051\end{array}$$
It's very kind of Jens to modify this table for me, which was so crude in the first place. The eigenvalue should be like that, but in low energy states, my results are far from what it should be. I don't know where this error is coming from, and if there is a better way to do this.
If this problem can be fixed, I'd be very grateful for that.
Solving Coulomb Potential using Jens' variable substitution method
I'm going to save myself some trouble, just post my code and result here:
code which is basically copy from Jens':
V[r_] = -14.3996448504451555789912633575295935414`6.88249108029756/r;
α = 0.26246843532124502683678435500618410715`6.076375074285658;
radialEq = V[r] f[r] - f''[r]/α;
radialξ =
Simplify[radialEq /. f -> (ψ[ArcTan[#]] &) /. r -> (Tan[ξ]),
Pi/2 > ξ > 0]
With[{max = 20, shift = 10}, {ev, ef} =
NDEigensystem[{radialξ + shift ψ[ξ],
DirichletCondition[ψ[ξ] == 0,
True]}, ψ[ξ], {ξ, 0, Pi/2}, max,
Method -> {"SpatialDiscretization" -> {"FiniteElement", \
{"MeshOptions" -> {"MaxCellMeasure" -> 0.001}}},
"Eigensystem" -> {"Arnoldi", MaxIterations -> 40000}}];
evNew = ev - shift]
And results:
$$\small\begin{array}{lllll} &-13.6057,& -3.40142,& -1.51174, &-0.850356,& -0.544228, \\&-0.377936, & -0.277667, &-0.212588, &-0.167969, &-0.13605,\\& -0.112427, &-0.0944449, \ & -0.0804237, &-0.0692623, &-0.0601369, \\&-0.0524875, &-0.0468007, \ & -0.0402104, &-0.0350137, &-0.0310644\end{array}$$
And the real energy:
Ehydrogen =
Table[-QuantityMagnitude[UnitConvert[Quantity[1, "Rydbergs"], "eV"]]/
n^2, {n, 20}]
$$\small\begin{array}{lllll}&-13.60569,& -3.401423, &-1.511744, &-0.850356, &-0.5442277, \\&-0.3779359, \ &-0.2776672, &-0.2125889,& -0.1679715, &-0.1360569,\\& -0.1124437, \ &-0.0944840, &-0.0805071, &-0.06941680,& -0.06046974, \\&-0.05314724, \ &-0.04707852, &-0.04199288, &-0.03768890, &-0.03401423\end{array}$$
The error:
$$\small\begin{array}{lllll}&-2.72446*10^{-8}, &-6.8044*10^{-9}, &-2.97381*10^{-9}, &-7.99033*10^{-10}, & 6.76493*10^{-9},\\& 4.52332*10^{-8}, &2.05556*10^{-7}, &7.58432*10^{-7}, & 2.39862*10^{-6}, &6.70562*10^{-6}, \\&0.0000169127, &0.0000390625, &0.0000833608, \ & 0.000154477,& 0.000332808,\\& 0.000659734,& 0.00027787,& 0.00178247, \ & 0.00267516,& 0.00294987\end{array}$$
When I increase the MaxCellMeasure
to 0.0001, the error decrease a lot:
$$\small\begin{array}{lllll}&-2.75312*10^{-8}, &-6.81183*10^{-9}, &-3.03523*10^{-9}, &-1.70471*10^{-9}, \ &-1.08962*10^{-9}, \\&-7.52408*10^{-10}, &-5.35404*10^{-10}, &-3.49364*10^{-10}, \ &-9.34864*10^{-11},& 4.12964*10^{-10}, \\&1.53102*10^{-9}, &3.96303*10^{-9}, \ &9.01172*10^{-9},& 1.89823*10^{-8}, &3.77832*10^{-8}, \\&7.17968*10^{-8}, \ &1.31103*10^{-7},& 2.31154*10^{-7}, &3.9495*10^{-7},& 6.58026*10^{-7}\end{array}$$
Alpha
is undefined. Where did you get the values in the last table? $\endgroup$alpha
is a pre-defined value,actually it's the schroedinger constant.Here it's value is2.
.I'm terribly sorry that you have to find out this on your own.And thank you very much for your tutorial inNDEigensystem
. $\endgroup$