using DFTK using LinearAlgebra struct ElementCustomPotential <: DFTK.Element pot_real::Function # Real potential pot_fourier::Function # Fourier potential end function DFTK.local_potential_fourier(el::ElementCustomPotential, q::Real) return el.pot_fourier(q) end function DFTK.local_potential_real(el::ElementCustomPotential, r::Real) return el.pot_real(r) end a = 10 lattice = a .* [[1 0 0.]; [0 0 0]; [0 0 0]]; x1 = 0.2 x2 = 0.8; L = 0.5; pot_real(x) = exp(-(x/L)^2) pot_fourier(q::T) where {T <: Real} = exp(- (q*L)^2 / 4); nucleus = ElementCustomPotential(pot_real, pot_fourier) atoms = [nucleus => [x1*[1,0,0], x2*[1,0,0]]]; C = 1.0 α = 2; n_electrons = 1 # Increase this for fun terms = [Kinetic(), AtomicLocal(), PowerNonlinearity(C, α), ] model = Model(lattice; atoms=atoms, n_electrons=n_electrons, terms=terms, spin_polarization=:spinless); # use "spinless electrons" basis = PlaneWaveBasis(model; Ecut=500, kgrid=(1, 1, 1)) ρ = zeros(eltype(basis), basis.fft_size..., 1) scfres = self_consistent_field(basis, tol=1e-8, ρ=ρ) scfres.energies hcat(compute_forces(scfres)...) tot_local_pot = DFTK.total_local_potential(scfres.ham)[:, 1, 1]; # use only dimension 1 ρ = scfres.ρ[:, 1, 1, 1] # converged density, first spin component ψ_fourier = scfres.ψ[1][:, 1]; # first kpoint, all G components, first eigenvector ψ = G_to_r(basis, basis.kpoints[1], ψ_fourier)[:, 1, 1] ψ /= (ψ[div(end, 2)] / abs(ψ[div(end, 2)])); using Plots x = a * vec(first.(DFTK.r_vectors(basis))) p = plot(x, real.(ψ), label="real(ψ)") plot!(p, x, imag.(ψ), label="imag(ψ)") plot!(p, x, ρ, label="ρ") plot!(p, x, tot_local_pot, label="tot local pot")