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-61.0e-6Density-based self-consistent field
scfres_scf = self_consistent_field(basis; tol);n Energy log10(ΔE) log10(Δρ) Diag Δtime
--- --------------- --------- --------- ---- ------
1 -8.397801087242 -0.90 5.0 26.8ms
2 -8.400224467530 -2.62 -1.74 1.0 19.2ms
3 -8.400404064260 -3.75 -2.98 1.5 20.3ms
4 -8.400427856890 -4.62 -2.98 3.2 25.8ms
5 -8.400427945768 -7.05 -3.06 1.0 29.0ms
6 -8.400428145960 -6.70 -4.60 1.0 19.5ms
7 -8.400428151747 -8.24 -4.43 2.5 23.4ms
8 -8.400428152163 -9.38 -4.97 1.0 19.4ms
9 -8.400428152207 -10.35 -6.38 1.0 19.3msPotential-based SCF
scfres_scfv = DFTK.scf_potential_mixing(basis; tol);n Energy log10(ΔE) log10(Δρ) α Diag Δtime
--- --------------- --------- --------- ---- ---- ------
1 -8.397824725821 -0.90 5.2 27.5ms
2 -8.400386017017 -2.59 -1.79 0.80 2.0 19.6ms
3 -8.400423136524 -4.43 -2.99 0.80 1.0 16.7ms
4 -8.400428112254 -5.30 -3.46 0.80 2.8 21.4ms
5 -8.400428150826 -7.41 -4.55 0.80 1.5 18.2ms
6 -8.400428152187 -8.87 -6.20 0.80 2.0 19.3msDirect minimization
scfres_dm = direct_minimization(basis; tol);┌ Warning: x_tol is deprecated. Use x_abstol or x_reltol instead. The provided value (-1) will be used as x_abstol.
└ @ Optim ~/.julia/packages/Optim/gmigl/src/types.jl:110
┌ Warning: f_tol is deprecated. Use f_abstol or f_reltol instead. The provided value (-1) will be used as f_reltol.
└ @ Optim ~/.julia/packages/Optim/gmigl/src/types.jl:120
n Energy log10(ΔE) log10(Δρ) Δtime
--- --------------- --------- --------- ------
1 +0.865595046922 -1.06 64.5ms
2 -1.997999666647 0.46 -0.68 32.6ms
3 -4.636607285953 0.42 -0.44 43.7ms
4 -6.373948030885 0.24 -0.57 43.7ms
5 -7.699573113249 0.12 -0.83 43.4ms
6 -8.063858902257 -0.44 -1.26 38.8ms
7 -8.230025841563 -0.78 -1.53 32.3ms
8 -8.298568922229 -1.16 -1.88 32.3ms
9 -8.338241603154 -1.40 -2.21 33.0ms
10 -8.359060102912 -1.68 -2.38 32.2ms
11 -8.377527875036 -1.73 -2.37 32.1ms
12 -8.388036236656 -1.98 -2.39 38.7ms
13 -8.392624872114 -2.34 -2.75 32.6ms
14 -8.396130105406 -2.46 -2.81 32.4ms
15 -8.398077576684 -2.71 -2.84 32.6ms
16 -8.399164770762 -2.96 -2.97 32.1ms
17 -8.399845822868 -3.17 -3.53 32.1ms
18 -8.400113502639 -3.57 -3.47 38.9ms
19 -8.400310964347 -3.70 -3.61 32.7ms
20 -8.400375314637 -4.19 -4.11 32.8ms
21 -8.400410183363 -4.46 -3.85 32.7ms
22 -8.400416588566 -5.19 -4.18 32.2ms
23 -8.400424088653 -5.12 -4.64 32.4ms
24 -8.400426106147 -5.70 -4.56 38.5ms
25 -8.400427386736 -5.89 -5.27 32.2ms
26 -8.400427714006 -6.49 -5.19 32.3ms
27 -8.400428019180 -6.52 -5.24 32.4ms
28 -8.400428079654 -7.22 -5.21 32.2ms
29 -8.400428126907 -7.33 -5.89 32.3ms
30 -8.400428137434 -7.98 -5.64 38.9ms
31 -8.400428146349 -8.05 -6.26 32.8msNewton 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.397859840876 -0.90 5.0 26.6msRemove 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.400427990966 -1.79 593ms
2 -8.400428152209 -6.79 -4.04 401ms
3 -8.400428152209 -14.75 -7.86 100msComparison 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| = 4.090741530237962e-7
|ρ_newton - ρ_scfv| = 4.120697582631537e-6
|ρ_newton - ρ_dm| = 2.635327211071386e-6