A self-consistent Kohn-Sham Density Functional Theory (DFT) solver for atomic systems, implementing the Local Density Approximation (LDA) with Perdew-Zunger exchange-correlation functionals.
- Self-consistent Field (SCF) Calculation: Iterative solution of Kohn-Sham equations until convergence
- Numerov Method: High-accuracy numerical integration on logarithmic grid for radial Schrödinger equations
- LDA Exchange-Correlation: Perdew-Zunger parametrization of Ceperley-Alder QMC data
- Hartree Potential: Self-consistent solution via Newton's method on Poisson equation
- Atomic Systems: Supports elements from H to Ca (Z=1 to Z=20)
- Logarithmic Grid: Efficient sampling near nucleus with exponential grid spacing
- Accurate Node Counting: Bisection method with proper quantum number validation
The solver implements the radial Kohn-Sham equations in atomic units:
where:
-
$u_{nl}(r) = r R_{nl}(r)$ is the radial wavefunction -
$V_{\text{eff}} = V_{\text{Hartree}} + V_{\text{xc}} - \frac{Z}{r}$ is the effective Kohn-Sham potential -
$V_{\text{xc}}$ uses LDA with Perdew-Zunger parametrization - Boundary conditions:
$u_{nl}(0) = 0$ ,$u_{nl}(\infty) = 0$
- Numerov Algorithm: 4th-order accurate finite difference method on logarithmic grid
- Bisection Method: Energy eigenvalue search with node counting for proper quantum states
- Simpson's Rule: Numerical integration for charge densities and total energies
- Newton's Method: Iterative solution of Poisson equation for Hartree potential
- Density Mixing: 50% linear mixing for stable SCF convergence
- C++11 or later compiler (g++, clang++)
- Eigen3 - Linear algebra library (v3.3+)
- Standard C++ libraries
- Linux/Unix/MacOS
- 4GB RAM minimum (8GB recommended for heavier atoms)
- ~100MB disk space
git clone https://github.com/yourusername/KS-DFT-Solver.git
cd KS-DFT-SolverUbuntu/Debian:
sudo apt-get update
sudo apt-get install libeigen3-devMacOS (Homebrew):
brew install eigenArch Linux:
sudo pacman -S eigenFedora/RHEL:
sudo dnf install eigen3-develStandard compilation:
g++ -O2 -I./include src/KS_solver.cpp -o KS_solverWith explicit Eigen path (if needed):
g++ -O2 -I./include -I/usr/include/eigen3 src/KS_solver.cpp -o KS_solverFor maximum optimization:
g++ -O3 -march=native -I./include src/KS_solver.cpp -o KS_solver./KS_solverThe program will prompt you to enter an atom name:
Enter atom name (H ~ Ca): Li
Selected atom: Li Ntot = 3
Enter atom name (H ~ Ca): C
Selected atom: C Ntot = 6
------Starting Main Loop Iteration = 0
[✔] Done: Schrodinger converged via Bisection Numerov!
iter = 18 E = -1.13254e+01 n = 1 l = 0 ...
------Done: Main Loop Iteration = 1 Total Energy = -3.75426e+01
...
Converged! Writing wavefunction unl ...
All job done! Final atomic config:
n = 1 l = 0 Occupancy = 2 Enl = -1.13254e+01
n = 2 l = 0 Occupancy = 2 Enl = -5.73421e-01
n = 2 l = 1 Occupancy = 2 Enl = -3.45123e-01
The solver generates wavefunction files:
- Format:
{atom}_n{n}l{l}_nodes{nodes}.dat - Example:
C_n1l0_nodes0.dat,C_n2l0_nodes1.dat - Two-column format:
r(Bohr) andu_nl(r)
Python example:
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('C_n1l0_nodes0.dat')
r, u = data[:, 0], data[:, 1]
plt.plot(r, u)
plt.xlabel('r (Bohr)')
plt.ylabel('u_nl(r)')
plt.title('Carbon 1s Wavefunction')
plt.grid(True)
plt.show()Key adjustable parameters in src/KS_solver.cpp:
// Grid parameters
const double rmin = 1E-12; // Minimum radius
const double rmax = 30.0; // Maximum radius
const int Nx = 20000; // Number of grid points
// Convergence parameters
const int Iter_max = 100; // Maximum SCF iterations
const double E_converge = 1E-5; // Energy convergence thresholdAll atoms from H (Z=1) to Ca (Z=20):
| Period 1 | Period 2 | Period 3 | Period 4 |
|---|---|---|---|
| H, He | Li, Be, B, C, N, O, F, Ne | Na, Mg, Al, Si, P, S, Cl, Ar | K, Ca |
- Initialize: Start with trial electron density
- Hartree Potential: Solve Poisson equation
- XC Potential: Calculate from LDA functional
- Solve KS Equations: Find eigenvalues/eigenfunctions
- Update Density: Construct new density from wavefunctions
- Mix Densities: Stabilize convergence
- Check Convergence: Repeat until converged
g++ -O2 -I./include -I/usr/include/eigen3 src/KS_solver.cpp -o KS_solverAdjust E_start in main() or increase rmax and Nx
Increase density mixing (change 0.5 to 0.3 in line 566)
MIT License - see LICENSE file for details.
Yuewen Sun (sunyw@shanghaitech.edu.cn)
Note: Educational/research code. For production, use ABINIT, Quantum ESPRESSO, or GPAW.