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.oncvpsp3.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.397836896156 -0.90 5.2 36.0ms
2 -8.400252748251 -2.62 -1.74 1.0 24.9ms
3 -8.400400135389 -3.83 -2.94 1.2 27.2ms
4 -8.400428595710 -4.55 -2.91 3.2 24.7ms
5 -8.400428745668 -6.82 -2.98 1.0 18.5ms
6 -8.400429017443 -6.57 -4.71 1.0 18.6ms
7 -8.400429023933 -8.19 -4.40 3.0 30.6ms
8 -8.400429024391 -9.34 -5.11 1.0 19.4ms
9 -8.400429024418 -10.57 -6.27 1.0 18.9ms
Potential-based SCF
scfres_scfv = DFTK.scf_potential_mixing(basis; tol);
n Energy log10(ΔE) log10(Δρ) α Diag Δtime
--- --------------- --------- --------- ---- ---- ------
1 -8.397773014239 -0.90 5.2 26.5ms
2 -8.400382928736 -2.58 -1.79 0.80 2.2 18.9ms
3 -8.400423178463 -4.40 -3.01 0.80 1.0 15.4ms
4 -8.400428967159 -5.24 -3.38 0.80 2.8 20.2ms
5 -8.400429021308 -7.27 -4.44 0.80 1.2 16.5ms
6 -8.400429024370 -8.51 -5.58 0.80 2.2 25.2ms
7 -8.400429024420 -10.31 -6.03 0.80 2.8 20.8ms
Direct minimization
scfres_dm = direct_minimization(basis; tol);
n Energy log10(ΔE) log10(Δρ) Δtime
--- --------------- --------- --------- ------
1 +0.934356000086 -1.08 52.0ms
2 -1.829151898816 0.44 -0.65 34.2ms
3 -3.691492741717 0.27 -0.37 39.2ms
4 -4.597929108750 -0.04 -0.42 39.1ms
5 -6.341671948801 0.24 -0.43 43.4ms
6 -7.252268521930 -0.04 -0.56 38.9ms
7 -7.995470135500 -0.13 -0.90 44.1ms
8 -8.162544937083 -0.78 -1.44 29.0ms
9 -8.228101894488 -1.18 -1.77 28.8ms
10 -8.274853831208 -1.33 -2.03 28.7ms
11 -8.300492431911 -1.59 -2.17 33.7ms
12 -8.326197509491 -1.59 -2.07 29.4ms
13 -8.353735859756 -1.56 -1.95 29.0ms
14 -8.378155204297 -1.61 -1.94 33.1ms
15 -8.390554005365 -1.91 -2.67 29.2ms
16 -8.396026008886 -2.26 -2.44 28.7ms
17 -8.398297519344 -2.64 -3.09 28.6ms
18 -8.399528339438 -2.91 -2.85 34.0ms
19 -8.400111466114 -3.23 -3.26 29.2ms
20 -8.400289393872 -3.75 -3.43 33.7ms
21 -8.400371604633 -4.09 -3.74 29.5ms
22 -8.400393272690 -4.66 -3.74 33.2ms
23 -8.400418724903 -4.59 -4.18 28.9ms
24 -8.400423927409 -5.28 -4.45 28.8ms
25 -8.400426877138 -5.53 -4.22 28.7ms
26 -8.400427808527 -6.03 -4.66 33.9ms
27 -8.400428589852 -6.11 -4.53 28.8ms
28 -8.400428792591 -6.69 -4.78 28.6ms
29 -8.400428937052 -6.84 -4.89 33.1ms
30 -8.400428968561 -7.50 -5.22 29.2ms
31 -8.400428995853 -7.56 -5.17 29.1ms
32 -8.400429007153 -7.95 -5.33 29.0ms
33 -8.400429017351 -7.99 -5.50 33.7ms
34 -8.400429021261 -8.41 -5.63 29.1ms
35 -8.400429023092 -8.74 -5.95 28.7ms
36 -8.400429023858 -9.12 -5.92 28.7ms
37 -8.400429024187 -9.48 -6.18 33.3ms
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.397850966313 -0.90 5.2 30.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.400428849711 -1.78 529ms
2 -8.400429024420 -6.76 -4.02 348ms
3 -8.400429024420 -14.45 -7.82 94.2ms
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| = 1.3082743108085614e-6
|ρ_newton - ρ_scfv| = 2.5126585093097167e-7
|ρ_newton - ρ_dm| = 1.507832152650422e-6