using DFTK using LinearAlgebra using Statistics function run_scf(; a=5.0, Ecut, nkpt, tol) atoms = [ElementPsp(:Pt, psp = load_psp("hgh/lda/Pt-q10"))] position = [zeros(3)] lattice = a * Matrix(I, 3, 3) model = model_LDA(lattice, atoms, position; temperature=1e-2) basis = PlaneWaveBasis(model; Ecut, kgrid=(nkpt, nkpt, nkpt)) println("nkpt = $nkpt Ecut = $Ecut") self_consistent_field(basis; is_converged=DFTK.ScfConvergenceEnergy(tol)) end; tol = 1e-2 # Tolerance to which we target to converge nkpts = 1:7 # K-point range checked for convergence Ecuts = 10:2:24; # Energy cutoff range checked for convergence function converge_kgrid(nkpts; Ecut, tol) energies = [run_scf(; nkpt, tol=tol/10, Ecut).energies.total for nkpt in nkpts] errors = abs.(energies[1:end-1] .- energies[end]) iconv = findfirst(errors .< tol) (; nkpts=nkpts[1:end-1], errors, nkpt_conv=nkpts[iconv]) end result = converge_kgrid(nkpts; Ecut=mean(Ecuts), tol) nkpt_conv = result.nkpt_conv using Plots plot(result.nkpts, result.errors, dpi=300, lw=3, m=:o, yaxis=:log, xlabel="k-grid", ylabel="energy absolute error") function converge_Ecut(Ecuts; nkpt, tol) energies = [run_scf(; nkpt, tol=tol/100, Ecut).energies.total for Ecut in Ecuts] errors = abs.(energies[1:end-1] .- energies[end]) iconv = findfirst(errors .< tol) (; Ecuts=Ecuts[1:end-1], errors, Ecut_conv=Ecuts[iconv]) end result = converge_Ecut(Ecuts; nkpt=nkpt_conv, tol) Ecut_conv = result.Ecut_conv plot(result.Ecuts, result.errors, dpi=300, lw=3, m=:o, yaxis=:log, xlabel="Ecut", ylabel="energy absolute error") tol = 1e-4 # Tolerance to which we target to converge nkpts = 1:20 # K-point range checked for convergence Ecuts = 20:1:50;