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.397804294746 -0.90 5.0 28.0ms
2 -8.400236263940 -2.61 -1.73 1.0 20.6ms
3 -8.400403544526 -3.78 -2.93 1.8 22.0ms
4 -8.400427804522 -4.62 -2.92 3.2 26.9ms
5 -8.400427956381 -6.82 -3.04 1.0 20.2ms
6 -8.400428150139 -6.71 -4.82 1.0 20.3ms
7 -8.400428155906 -8.24 -4.46 3.2 27.2ms
8 -8.400428156254 -9.46 -5.13 1.0 21.1ms
9 -8.400428156275 -10.68 -6.18 1.0 21.0ms
Potential-based SCF
scfres_scfv = DFTK.scf_potential_mixing(basis; tol);
n Energy log10(ΔE) log10(Δρ) α Diag Δtime
--- --------------- --------- --------- ---- ---- ------
1 -8.397835747985 -0.90 5.2 28.5ms
2 -8.400383872644 -2.59 -1.78 0.80 2.0 19.6ms
3 -8.400422528331 -4.41 -2.99 0.80 1.0 16.5ms
4 -8.400428103260 -5.25 -3.42 0.80 2.2 21.2ms
5 -8.400428152263 -7.31 -4.65 0.80 1.0 17.0ms
6 -8.400428156252 -8.40 -5.43 0.80 2.8 22.6ms
7 -8.400428156276 -10.62 -6.24 0.80 2.2 21.6ms
Direct minimization
scfres_dm = direct_minimization(basis; tol);
n Energy log10(ΔE) log10(Δρ) Δtime
--- --------------- --------- --------- ------
1 +0.875313784281 -1.11 54.2ms
2 -1.507011198566 0.38 -0.73 30.7ms
3 -3.988180372354 0.39 -0.46 45.0ms
4 -4.656650066036 -0.17 -0.56 50.1ms
5 -6.696928969909 0.31 -0.62 50.2ms
6 -7.452578318315 -0.12 -0.96 50.1ms
7 -7.713772444409 -0.58 -1.31 36.4ms
8 -8.032409515056 -0.50 -1.70 56.5ms
9 -8.115298047215 -1.08 -1.74 30.2ms
10 -8.225126914766 -0.96 -1.86 29.9ms
11 -8.288751488375 -1.20 -2.07 29.9ms
12 -8.326773040912 -1.42 -2.00 29.5ms
13 -8.362730530823 -1.44 -1.76 29.6ms
14 -8.377107010263 -1.84 -2.44 29.7ms
15 -8.389983472872 -1.89 -3.23 29.7ms
16 -8.393568369042 -2.45 -2.82 29.9ms
17 -8.398873032217 -2.28 -3.23 30.0ms
18 -8.399187738841 -3.50 -2.97 29.8ms
19 -8.400026244694 -3.08 -3.21 29.7ms
20 -8.400087606907 -4.21 -3.06 29.9ms
21 -8.400319032604 -3.64 -3.24 29.9ms
22 -8.400325497192 -5.19 -3.69 29.8ms
23 -8.400394943535 -4.16 -3.68 29.9ms
24 -8.400407153440 -4.91 -3.97 40.1ms
25 -8.400422250992 -4.82 -4.17 30.2ms
26 -8.400424443066 -5.66 -4.14 30.2ms
27 -8.400427133522 -5.57 -4.60 30.1ms
28 -8.400427348977 -6.67 -4.59 29.9ms
29 -8.400427938729 -6.23 -4.90 30.0ms
30 -8.400428015238 -7.12 -5.18 30.2ms
31 -8.400428120431 -6.98 -5.53 30.6ms
32 -8.400428132801 -7.91 -5.16 30.1ms
33 -8.400428150305 -7.76 -5.44 30.0ms
34 -8.400428152448 -8.67 -5.63 30.1ms
35 -8.400428155043 -8.59 -5.85 29.9ms
36 -8.400428155386 -9.47 -5.96 30.1ms
37 -8.400428156043 -9.18 -6.60 46.6ms
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.397802690572 -0.90 5.0 27.6ms
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.400427945539 -1.77 538ms
2 -8.400428156277 -6.68 -3.97 402ms
3 -8.400428156277 -14.15 -7.73 114ms
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.1775454389753843e-6
|ρ_newton - ρ_scfv| = 3.334668414959783e-7
|ρ_newton - ρ_dm| = 2.3348590710568234e-6