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

system = attach_psp(bulk(:Si); Si="hgh/lda/Si-q4")
model  = model_DFT(system; functionals=PBEsol())
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   -7.844854079310                   -0.70    4.5   32.9ms
  2   -7.848889916730       -2.39       -1.53    1.0   22.7ms
  3   -7.849103116539       -3.67       -2.49    1.5   24.0ms
  4   -7.849135141387       -4.49       -2.80    2.2   27.2ms
  5   -7.849135786450       -6.19       -3.02    1.0   22.5ms
  6   -7.849136042943       -6.59       -4.04    1.0   22.5ms
  7   -7.849136053996       -7.96       -4.71    1.8   25.5ms
  8   -7.849136054365       -9.43       -5.23    1.5   25.0ms
  9   -7.849136054391      -10.58       -5.87    1.5   24.6ms
 10   -7.849136054392      -11.79       -6.98    1.8   25.2ms

Potential-based SCF

scfres_scfv = DFTK.scf_potential_mixing(basis; tol);
n     Energy            log10(ΔE)   log10(Δρ)   α      Diag   Δtime
---   ---------------   ---------   ---------   ----   ----   ------
  1   -7.844860932941                   -0.71           4.5   32.4ms
  2   -7.849061120600       -2.38       -1.65   0.80    2.2   23.9ms
  3   -7.849130024556       -4.16       -2.75   0.80    1.0   19.2ms
  4   -7.849135905358       -5.23       -3.32   0.80    1.8   22.7ms
  5   -7.849136045735       -6.85       -4.37   0.80    1.8   21.7ms
  6   -7.849136054307       -8.07       -5.03   0.80    2.2   24.3ms
  7   -7.849136054388      -10.09       -5.57   0.80    1.2   20.5ms
  8   -7.849136054392      -11.44       -6.58   0.80    1.5   21.2ms

Direct minimization

scfres_dm = direct_minimization(basis; tol);
n     Energy            log10(ΔE)   log10(Δρ)   Δtime
---   ---------------   ---------   ---------   ------
  1   +1.505037091176                   -0.97   68.4ms
  2   -1.734460128162        0.51       -0.75   43.5ms
  3   -3.728855616682        0.30       -0.46   86.5ms
  4   -4.908276172778        0.07       -0.59   49.1ms
  5   -6.586999893947        0.22       -0.69   49.1ms
  6   -7.304325093490       -0.14       -1.09   49.0ms
  7   -7.554989648191       -0.60       -1.38   36.3ms
  8   -7.630549333544       -1.12       -1.73   35.9ms
  9   -7.659649357154       -1.54       -2.10   36.1ms
 10   -7.690865928891       -1.51       -1.91   36.0ms
 11   -7.702959887071       -1.92       -1.81   48.3ms
 12   -7.718953030361       -1.80       -2.15   48.5ms
 13   -7.750408112618       -1.50       -2.45   48.4ms
 14   -7.760431831604       -2.00       -2.29   35.8ms
 15   -7.790606600313       -1.52       -2.66   36.0ms
 16   -7.798112673770       -2.12       -2.69   36.0ms
 17   -7.816870130746       -1.73       -2.94   35.9ms
 18   -7.827746403272       -1.96       -2.70   35.6ms
 19   -7.841074443501       -1.88       -2.41   36.7ms
 20   -7.845903212507       -2.32       -2.70   40.9ms
 21   -7.848111992392       -2.66       -2.89   42.6ms
 22   -7.848968482542       -3.07       -3.18   42.5ms
 23   -7.849084232257       -3.94       -3.90   42.5ms
 24   -7.849117077970       -4.48       -4.21   42.3ms
 25   -7.849130778122       -4.86       -4.33   41.9ms
 26   -7.849134051770       -5.48       -4.74   36.1ms
 27   -7.849135388577       -5.87       -4.90   36.1ms
 28   -7.849135879871       -6.31       -5.44   36.3ms
 29   -7.849135989216       -6.96       -5.34   36.6ms
 30   -7.849136031512       -7.37       -5.57   36.0ms
 31   -7.849136044956       -7.87       -5.98   35.9ms
 32   -7.849136050579       -8.25       -5.86   35.8ms
 33   -7.849136053240       -8.58       -6.07   36.0ms

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   -7.844878866373                   -0.71    4.8   33.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   -7.849135378826                   -1.65    510ms
  2   -7.849136054392       -6.17       -3.72    383ms
  3   -7.849136054393      -13.24       -7.22    152ms

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.084936328419631e-7
|ρ_newton - ρ_scfv| = 4.2278999501898224e-7
|ρ_newton - ρ_dm|   = 2.156356993353712e-6