As usual, here is the program in action:
It displays the quantum dot ‘orbitals’ with VTK volume rendering. Do not assign much physical reality to individual orbitals (the total density is another matter) or energy levels (but for the last see Koopmans’ theorem).
This project is based on this lecture, already mentioned on this blog:
You might also want to look over this: New Algebraic Formulation of Density Functional Calculation2 and the lecture support files: Tomas Arias lectures support files3. Some DFT theory was exposed in the last post, so there is enough theory to allow one to understand the program.
I usually list some more important code in the posts, but I won’t do that here. I will only point where to look in the project1 instead. Besides, if you want to understand the code, the best way is to first watch the lectures, read the paper2 and solve the assignments in Matlab or Octave or SciLab but the last one might miss some functions you’ll need so you’ll have to implement them yourself. Of course you could also use another language like python but the Tomas Arias lectures support files3 already contains some skeleton m files and some helper code that will shorten the development time.
This project1 corresponds to the third assignment (without the last part, which is easy). If you know Matlab a little, it shouldn’t take you long to solve the first three assignments, then understanding the C++ code should be much easier.
I re-implemented the Poisson solver (already described here for another project) in the DFT solver class, this time using the notation from the lectures. The reason for the more complex code is to allow changing it to use another basis set very easily. You might want to look into the Poisson project to see it implemented in a simpler manner. I also reused the FFT classes used in the NMRI project.
Everything related with the DFT computations is in the
DFT namespace. You’ll see in there the
ReciprocalSpaceCell classes which have little changes (if any, I don’t recall if I changed them or not) from the last project. The
QuantumDot class hopefully has a suggestive naming, is very simple and it just initializes the potential in the constructor. The potential can be harmonic (as in the assignment) or linear. The most important DFT class is
DFTSolver which allows using different exchange-correlations by using a template parameter. For the assignments, the Vosko-Wilk-Nusair is already provided. I implemented it in C++ and tested the project with it, but I did not provide that class on GitHub. Instead I put in the project the
ChachiyoExchCor class, which as the name says, implements the Chachiyo correlation4. It’s simpler to implement and should be good enough for the purpose of this blog.
The classes for minimum finding are in the
DFT::SolutionFinders namespace. I abused a little templates in there, but that allowed me to have a single implementation for
Descend method (except for
SteepestDescent) and just plug in the different code for each minimum finding method. It’s probably far from being the best way. Anyway, with the help of the lectures the code should not be hard to understand. Here are some additional Wikipedia pages: Gradient descent, Preconditioning, Conjugate-gradient methods, Nonlinear Conjugate-gradient method. In addition, this paper (referenced on Wikipedia page) should be better than what I would have patience to write here: An Introduction to the Conjugate Gradient Method Without the Agonizing Pain5.
You might also want to look into the document class and view class, the later especially if you want to figure out the VTK code. The view code is a little more complex than it should because on my video card I had an issue which I tried to alleviate by hiding the warning/error VTK window (and logging in a file instead) and I also added some recovery code (which usually works, but not always). Sometimes when changing the orbital the VTK library fails. I did not look much into it, I simply provided a workaround which will simply stay with the old orbital forcing you to retry to switch it.
That’s about it. I might implement another project for atoms/molecules next, but if you are impatient (or for the case I’ll decide not to implement it), you could implement it yourself, it’s quite easy using the code from this project. In fact, I already implemented it and tested some simple atoms/molecules but I removed the code from the project (later edit: now that code is also in the project, as an example of the solver usage).
- DFT Quantum Dot The DFT project on GitHub ↩ ↩ ↩
- New Algebraic Formulation of Density Functional Calculation Sohrab Ismail-Beigi, T. A. Arias ↩ ↩
- Tomas Arias lectures support files ↩ ↩
- Simple and accurate uniform electron gas correlation energy for the full range of densities by Teepanis Chachiyo ↩
- An Introduction to the Conjugate Gradient Method Without the Agonizing Pain by Jonathan Richard Shewchuk ↩
- VTK The Visualization Toolkit Library ↩
- FFTW The Fast Fourier Transform library. ↩
- Eigen The matrix library. ↩