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.397494083412 -0.90 5.2 26.8ms
2 -8.400181282264 -2.57 -1.72 1.0 18.6ms
3 -8.400394186450 -3.67 -3.03 1.5 19.4ms
4 -8.400427804963 -4.47 -2.96 3.2 24.9ms
5 -8.400428101041 -6.53 -3.43 1.0 70.5ms
6 -8.400428149938 -7.31 -4.89 1.0 19.2ms
7 -8.400428152086 -8.67 -4.80 2.8 23.8ms
8 -8.400428152189 -9.99 -5.18 1.0 19.3ms
9 -8.400428152208 -10.73 -6.19 1.0 19.7ms
Potential-based SCF
scfres_scfv = DFTK.scf_potential_mixing(basis; tol);n Energy log10(ΔE) log10(Δρ) α Diag Δtime
--- --------------- --------- --------- ---- ---- ------
1 -8.397614434192 -0.90 5.2 1.82s
2 -8.400385117274 -2.56 -1.79 0.80 2.0 519ms
3 -8.400423340454 -4.42 -2.97 0.80 1.0 232ms
4 -8.400428112150 -5.32 -3.48 0.80 2.5 21.6ms
5 -8.400428148744 -7.44 -4.79 0.80 1.2 18.6ms
6 -8.400428152193 -8.46 -6.11 0.80 3.0 22.9ms
Direct 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 +1.016762316222 -1.09 3.63s
2 -1.867629350370 0.46 -0.65 157ms
3 -4.631248220240 0.44 -0.36 44.9ms
4 -6.221877940494 0.20 -0.43 45.1ms
5 -7.597854008489 0.14 -0.68 86.7ms
6 -7.942135844718 -0.46 -1.28 33.3ms
7 -8.156467047149 -0.67 -1.58 32.8ms
8 -8.189350420834 -1.48 -1.73 33.0ms
9 -8.191057833656 -2.77 -1.80 32.9ms
10 -8.256275235509 -1.19 -1.72 43.9ms
11 -8.310929517139 -1.26 -1.66 79.4ms
12 -8.347110265224 -1.44 -2.53 32.7ms
13 -8.358724876381 -1.93 -2.73 32.7ms
14 -8.375997923764 -1.76 -2.29 32.8ms
15 -8.388726543813 -1.90 -2.20 32.8ms
16 -8.392429851825 -2.43 -2.60 39.8ms
17 -8.397895573741 -2.26 -3.00 33.0ms
18 -8.398634068414 -3.13 -3.37 32.8ms
19 -8.399836694417 -2.92 -3.33 33.7ms
20 -8.400091384066 -3.59 -3.34 34.2ms
21 -8.400323832786 -3.63 -3.72 39.8ms
22 -8.400357080776 -4.48 -3.90 33.4ms
23 -8.400404641319 -4.32 -3.88 33.4ms
24 -8.400409775657 -5.29 -4.15 33.5ms
25 -8.400420891757 -4.95 -4.74 33.3ms
26 -8.400424327836 -5.46 -4.45 40.3ms
27 -8.400426911289 -5.59 -5.06 33.3ms
28 -8.400427524161 -6.21 -4.83 33.1ms
29 -8.400427959990 -6.36 -5.39 33.2ms
30 -8.400428016384 -7.25 -5.28 33.1ms
31 -8.400428114063 -7.01 -6.04 39.5ms
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.397448065425 -0.90 5.0 27.1ms
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.400427942983 -1.78 12.0s
2 -8.400428152209 -6.68 -3.98 3.85s
3 -8.400428152209 -14.45 -7.75 91.6ms
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| = 6.053924158844756e-7
|ρ_newton - ρ_scfv| = 3.754686729521315e-6
|ρ_newton - ρ_dm| = 7.685142693483296e-6