Comparison of DFT solvers
We compare four different approaches for solving the DFT minimisation problem, namely a density-based SCF, a potential-based SCF, direct minimisation and Newton.
First we setup our problem
using AtomsBuilder
using DFTK
using LinearAlgebra
using PseudoPotentialData
pseudopotentials = PseudoFamily("dojo.nc.sr.pbesol.v0_4_1.standard.upf")
model = model_DFT(bulk(:Si); functionals=PBEsol(), pseudopotentials)
basis = PlaneWaveBasis(model; Ecut=5, kgrid=[3, 3, 3])
# Convergence we desire in the density
tol = 1e-6
1.0e-6
Density-based self-consistent field
scfres_scf = self_consistent_field(basis; tol);
n Energy log10(ΔE) log10(Δρ) Diag Δtime
--- --------------- --------- --------- ---- ------
1 -8.397846879200 -0.90 5.5 27.9ms
2 -8.400252852220 -2.62 -1.74 1.0 19.5ms
3 -8.400398155760 -3.84 -2.94 1.2 19.8ms
4 -8.400427774730 -4.53 -2.91 3.2 34.3ms
5 -8.400427903971 -6.89 -2.99 1.0 19.2ms
6 -8.400428149098 -6.61 -5.00 1.0 19.0ms
7 -8.400428155753 -8.18 -4.36 3.5 26.5ms
8 -8.400428156237 -9.32 -5.05 1.2 19.9ms
9 -8.400428156274 -10.43 -5.94 1.0 25.4ms
10 -8.400428156276 -11.56 -5.94 2.0 22.2ms
11 -8.400428156277 -12.61 -6.81 1.0 19.4ms
Potential-based SCF
scfres_scfv = DFTK.scf_potential_mixing(basis; tol);
n Energy log10(ΔE) log10(Δρ) α Diag Δtime
--- --------------- --------- --------- ---- ---- ------
1 -8.397845642657 -0.90 5.5 33.2ms
2 -8.400383915525 -2.60 -1.79 0.80 2.0 18.8ms
3 -8.400422652342 -4.41 -3.01 0.80 1.2 16.1ms
4 -8.400428104402 -5.26 -3.43 0.80 2.5 19.8ms
5 -8.400428154154 -7.30 -4.61 0.80 1.2 16.5ms
6 -8.400428156249 -8.68 -6.09 0.80 2.5 19.9ms
Direct minimization
scfres_dm = direct_minimization(basis; tol);
n Energy log10(ΔE) log10(Δρ) Δtime
--- --------------- --------- --------- ------
1 +1.359177533015 -1.09 58.0ms
2 -1.293394058816 0.42 -0.67 29.0ms
3 -3.665976947168 0.38 -0.41 39.7ms
4 -4.457951506555 -0.10 -0.51 45.9ms
5 -6.494527136139 0.31 -0.57 39.1ms
6 -7.246752334556 -0.12 -0.87 39.0ms
7 -7.498629649210 -0.60 -1.23 33.9ms
8 -7.914327629359 -0.38 -1.47 28.9ms
9 -7.985405714064 -1.15 -1.46 28.8ms
10 -8.119665574510 -0.87 -1.29 39.1ms
11 -8.182217915813 -1.20 -1.51 56.2ms
12 -8.208404125764 -1.58 -1.92 39.2ms
13 -8.278121600492 -1.16 -1.78 39.1ms
14 -8.303636209860 -1.59 -1.85 54.5ms
15 -8.364906661510 -1.21 -2.09 29.0ms
16 -8.385118848588 -1.69 -2.60 28.8ms
17 -8.393654699717 -2.07 -2.33 28.9ms
18 -8.396192966943 -2.60 -2.45 33.8ms
19 -8.398937507512 -2.56 -2.91 28.9ms
20 -8.399782161125 -3.07 -2.74 28.7ms
21 -8.400145925577 -3.44 -3.09 28.8ms
22 -8.400205597100 -4.22 -3.15 33.9ms
23 -8.400337597211 -3.88 -3.35 29.0ms
24 -8.400390860627 -4.27 -3.65 28.8ms
25 -8.400411869696 -4.68 -4.23 28.8ms
26 -8.400420706640 -5.05 -4.06 34.2ms
27 -8.400425234126 -5.34 -4.78 29.0ms
28 -8.400426515553 -5.89 -4.22 28.8ms
29 -8.400427606322 -5.96 -4.84 29.0ms
30 -8.400427856860 -6.60 -4.67 29.3ms
31 -8.400427982382 -6.90 -5.18 34.1ms
32 -8.400428066899 -7.07 -5.14 29.0ms
33 -8.400428117767 -7.29 -5.54 28.8ms
34 -8.400428147546 -7.53 -5.54 29.3ms
35 -8.400428153076 -8.26 -5.58 38.2ms
36 -8.400428155063 -8.70 -5.92 29.0ms
37 -8.400428155503 -9.36 -5.93 29.0ms
38 -8.400428155975 -9.33 -6.11 28.7ms
Newton algorithm
Start not too far from the solution to ensure convergence: We run first a very crude SCF to get close and then switch to Newton.
scfres_start = self_consistent_field(basis; tol=0.5);
n Energy log10(ΔE) log10(Δρ) Diag Δtime
--- --------------- --------- --------- ---- ------
1 -8.397881970538 -0.90 5.0 32.4ms
Remove the virtual orbitals (which Newton cannot treat yet)
ψ = DFTK.select_occupied_orbitals(basis, scfres_start.ψ, scfres_start.occupation).ψ
scfres_newton = newton(basis, ψ; tol);
n Energy log10(ΔE) log10(Δρ) Δtime
--- --------------- --------- --------- ------
1 -8.400427946340 -1.77 542ms
2 -8.400428156277 -6.68 -3.97 368ms
3 -8.400428156277 -14.27 -7.73 110ms
Comparison of results
println("|ρ_newton - ρ_scf| = ", norm(scfres_newton.ρ - scfres_scf.ρ))
println("|ρ_newton - ρ_scfv| = ", norm(scfres_newton.ρ - scfres_scfv.ρ))
println("|ρ_newton - ρ_dm| = ", norm(scfres_newton.ρ - scfres_dm.ρ))
|ρ_newton - ρ_scf| = 2.2078565037565425e-7
|ρ_newton - ρ_scfv| = 3.945019700244033e-6
|ρ_newton - ρ_dm| = 9.051430392926838e-7