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.397850840534 -0.90 5.2 26.9ms
2 -8.400238865929 -2.62 -1.74 1.0 19.1ms
3 -8.400406299385 -3.78 -2.99 1.5 31.2ms
4 -8.400427840485 -4.67 -2.99 3.0 24.0ms
5 -8.400427964063 -6.91 -3.08 1.0 19.1ms
6 -8.400428145362 -6.74 -4.59 1.0 19.1ms
7 -8.400428151835 -8.19 -4.49 2.5 23.5ms
8 -8.400428152181 -9.46 -5.10 1.0 19.3ms
9 -8.400428152207 -10.58 -6.66 1.0 29.0ms
Potential-based SCF
scfres_scfv = DFTK.scf_potential_mixing(basis; tol);
n Energy log10(ΔE) log10(Δρ) α Diag Δtime
--- --------------- --------- --------- ---- ---- ------
1 -8.397824602190 -0.90 5.5 27.5ms
2 -8.400385172332 -2.59 -1.79 0.80 2.0 19.7ms
3 -8.400422888817 -4.42 -3.00 0.80 1.0 17.0ms
4 -8.400428103020 -5.28 -3.42 0.80 2.2 20.7ms
5 -8.400428149004 -7.34 -4.55 0.80 1.2 17.6ms
6 -8.400428152179 -8.50 -5.76 0.80 2.5 20.8ms
7 -8.400428152209 -10.52 -6.31 0.80 3.0 31.7ms
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/7krni/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/7krni/src/types.jl:120
n Energy log10(ΔE) log10(Δρ) Δtime
--- --------------- --------- --------- ------
1 +0.441868345458 -1.09 57.9ms
2 -1.835008751893 0.36 -0.68 32.4ms
3 -4.825976714005 0.48 -0.40 43.5ms
4 -6.411520373505 0.20 -0.49 50.8ms
5 -7.752873286620 0.13 -0.79 43.6ms
6 -8.122412381647 -0.43 -1.33 32.2ms
7 -8.249151470917 -0.90 -1.57 32.2ms
8 -8.306972391537 -1.24 -1.83 32.1ms
9 -8.348288316082 -1.38 -2.15 32.0ms
10 -8.370405984660 -1.66 -2.34 38.0ms
11 -8.387410960860 -1.77 -2.28 32.3ms
12 -8.394825059432 -2.13 -2.54 31.9ms
13 -8.398661408926 -2.42 -2.96 32.3ms
14 -8.399665611902 -3.00 -3.21 32.0ms
15 -8.400157320591 -3.31 -3.12 32.3ms
16 -8.400280750884 -3.91 -3.54 39.1ms
17 -8.400376743234 -4.02 -3.40 32.3ms
18 -8.400402667041 -4.59 -3.97 32.2ms
19 -8.400418052491 -4.81 -3.97 32.2ms
20 -8.400423579308 -5.26 -4.16 32.3ms
21 -8.400425960583 -5.62 -4.51 32.1ms
22 -8.400427143737 -5.93 -4.55 38.2ms
23 -8.400427777539 -6.20 -4.73 32.2ms
24 -8.400427985709 -6.68 -5.07 32.2ms
25 -8.400428099345 -6.94 -5.10 32.1ms
26 -8.400428131166 -7.50 -5.19 32.1ms
27 -8.400428144888 -7.86 -5.67 32.0ms
28 -8.400428149396 -8.35 -5.73 39.1ms
29 -8.400428151122 -8.76 -6.26 32.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.397798577809 -0.90 4.8 26.0ms
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.400427969307 -1.78 576ms
2 -8.400428152209 -6.74 -4.01 399ms
3 -8.400428152209 -14.45 -7.80 118ms
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| = 2.8917263727095035e-7
|ρ_newton - ρ_scfv| = 3.5798138102439843e-7
|ρ_newton - ρ_dm| = 2.2752778931026034e-6