In my previous blog post, I had an introductory look at the problem of integrating the time-dependent Schrödinger equation (TDSE) numerically, plotting the wave function at each time step, and creating an animation of the result. In this post I will describe how to solve the TDSE in more detail.
Recall the TDSE for a spinless particle in a potential :
We need to do two things;
- Evaluate the Hamiltonian acting on the wave function,
- Integrate the TDSE itself.
The Hamiltonian consists of two parts; the kinetic energy operator (which is proportional to the Laplacian) and the potential operator. Both of these act on the wave function, producing new fields of complex numbers ( and ). The potential term is easy; at every point on our grid we simply multiply the wave function with the potential. The kinetic term requires us to evaluate the action of the Laplacian on the wave function, and we need to come up with a numerical scheme for this.
The Laplacian is the sum of the (unmixed) second partial derivatives. Since we are considering a 2D space, we have:
In order to evaluate the kinetic term, therefore, we must evaluate the second derivative with respect to and . For a good introduction to spatial derivatives in finite-difference schemes, see this Wikipedia page. A popular choice is the central difference scheme:
where is the grid spacing. A second order version also exists:
but I get better (more stable) results by simply applying the first order method twice. Assuming we pick the second order method, we end up with the following expression:
Boundary conditions probably deserve a few dedicated blog posts; I will not go into them very deeply here, because in all of the videos I am presenting here, the wave function remains more or less localized in the middle of the screen, barely touching the edges. Suffice it to say for now that there are different options; one can have reflecting boundaries (so that the entire wave function remains in our simulation volume) or absorbing boundaries (so that (parts of) the wave function can propagate out of our simulation volume). Note that in the second case, the wave functions norm will generally not be preserved!
In the code I am describing in these blog posts, I use a crude scheme where I simply set to zero at the boundary after each step, and only evaluate the Laplacian in the innermost region of the simulation volume (excluding a boundary zone one with a thickness of one grid point). This is not a proper implementation of boundary conditions, and I will have to revisit this issue at a later date.
Integrating the TDSE
In my previous post I mentioned the simplest possible explicit integration scheme for the TDSE: the forward Euler method. It works as follows:
While this method is easy to implement, it is a first order scheme, and the error per step is proportional to the square of the step size. This means that unless the step size is extremely small (in which case we need many integration steps, which is computationally expensive), the solution quickly becomes unstable and ‘blows up’. We therefore use the 4th order Runge-Kutta method (abbreviated RK4), which is much more stable. For more detailed information about integration schemes, I recommend the excellent Wikipedia articles on the Euler method and Runge-Kutta methods.
Let’s write out the RK4 integration scheme for the TDSE explicitly. In this scheme, the new wave function depends not only on the current wave function , but also on four ‘intermediate’ wave functions which must be computed in order:
Having obtained the intermediate wave functions, we then compute the new wave function as follows:
That’s all I wanted to say about evaluating the action of the Hamiltonian on the wave function. In the next blog post, we’ll focus on implementing the equations discussed so far in C++, and look at some examples and plots to make things more clear. If you have any questions, don’t hesitate to post a comment and ask them!