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.397792788160 -0.90 5.5 27.9ms
2 -8.400244155508 -2.61 -1.74 1.0 20.0ms
3 -8.400406826641 -3.79 -2.96 1.5 20.4ms
4 -8.400428741956 -4.66 -2.99 3.2 33.8ms
5 -8.400428849800 -6.97 -3.09 1.0 19.5ms
6 -8.400429019032 -6.77 -4.89 1.0 19.5ms
7 -8.400429024083 -8.30 -4.48 3.2 26.2ms
8 -8.400429024399 -9.50 -5.28 1.0 26.5ms
9 -8.400429024418 -10.72 -6.53 1.2 20.3ms
Potential-based SCF
scfres_scfv = DFTK.scf_potential_mixing(basis; tol);
n Energy log10(ΔE) log10(Δρ) α Diag Δtime
--- --------------- --------- --------- ---- ---- ------
1 -8.397858236010 -0.90 5.2 32.9ms
2 -8.400386738238 -2.60 -1.79 0.80 2.0 19.2ms
3 -8.400423676335 -4.43 -3.02 0.80 1.0 16.0ms
4 -8.400428977728 -5.28 -3.42 0.80 2.5 20.3ms
5 -8.400429022180 -7.35 -4.40 0.80 1.2 16.7ms
6 -8.400429024358 -8.66 -5.32 0.80 2.0 18.9ms
7 -8.400429024419 -10.21 -6.21 0.80 1.8 24.6ms
Direct minimization
scfres_dm = direct_minimization(basis; tol);
n Energy log10(ΔE) log10(Δρ) Δtime
--- --------------- --------- --------- ------
1 +1.487530978831 -0.99 52.2ms
2 -0.899226592009 0.38 -0.64 29.1ms
3 -3.422398950364 0.40 -0.40 44.7ms
4 -3.650528180984 -0.64 -0.48 40.2ms
5 -5.741740944573 0.32 -0.47 44.4ms
6 -6.247592878073 -0.30 -0.67 39.4ms
7 -7.497558506948 0.10 -0.75 39.3ms
8 -7.851986451043 -0.45 -1.26 45.4ms
9 -8.043179728424 -0.72 -1.52 30.0ms
10 -8.113910476602 -1.15 -1.75 29.5ms
11 -8.190931774790 -1.11 -2.05 33.9ms
12 -8.263397132377 -1.14 -1.97 29.7ms
13 -8.272990384024 -2.02 -1.87 29.4ms
14 -8.278327282764 -2.27 -2.10 29.1ms
15 -8.299401395769 -1.68 -1.69 44.6ms
16 -8.310726924435 -1.95 -1.90 39.7ms
17 -8.341283528175 -1.51 -2.32 29.2ms
18 -8.353516248182 -1.91 -2.60 34.5ms
19 -8.370340665279 -1.77 -2.37 29.3ms
20 -8.386115724579 -1.80 -2.60 29.4ms
21 -8.394812949280 -2.06 -2.56 33.7ms
22 -8.398944649780 -2.38 -2.68 29.4ms
23 -8.399924689066 -3.01 -3.03 29.3ms
24 -8.400152447377 -3.64 -3.49 29.1ms
25 -8.400333546687 -3.74 -3.86 34.5ms
26 -8.400378982171 -4.34 -3.77 29.2ms
27 -8.400414561334 -4.45 -4.30 29.0ms
28 -8.400421618345 -5.15 -4.07 29.3ms
29 -8.400425941080 -5.36 -4.44 34.0ms
30 -8.400427777407 -5.74 -4.65 29.3ms
31 -8.400428518403 -6.13 -4.64 29.1ms
32 -8.400428809793 -6.54 -4.88 29.2ms
33 -8.400428928075 -6.93 -5.06 35.4ms
34 -8.400429000826 -7.14 -5.30 29.7ms
35 -8.400429012871 -7.92 -5.50 29.7ms
36 -8.400429019942 -8.15 -5.51 34.4ms
37 -8.400429021560 -8.79 -6.23 30.1ms
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.397824312158 -0.90 5.2 27.7ms
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.400428845395 -1.78 587ms
2 -8.400429024420 -6.75 -4.02 374ms
3 -8.400429024420 -14.75 -7.81 115ms
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.3863623422489796e-6
|ρ_newton - ρ_scfv| = 3.616324255835933e-7
|ρ_newton - ρ_dm| = 2.2201950055443067e-6