New AtomicPotentials.jl + PseudoPotentialIO.jl backend #877
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This draft replaces the existing pseudopotential framework in
pseudos
with the packagesAtomicPotentials.jl
which implements numerical pseudopotentials and the existing analyticalElement
types under a common interface.PseudoPotentialIOExperimental.jl
which removes all pseudopotential evaluation code fromPseudoPotentialIO.jl
and instead focuses only on parsing pseudopotential file formats.Ideally, this refactor aims to
AtomicLocal
,AtomicNonlocal
,PspCorrection
, andXc
) which willThere's a lot to this PR, so it will take a while to write up, but here are the key
Progress points
All
Element
subtypes are gone, replaced byElement(symbol, potential)
All
pseudos
code is gone, replaced byAtomicPotentials.jl
Loading pseudopotentials is done by
load_psp
, which supports the DFTK"hgh/.../..."
syntax as well as"/path/to/file"
and the PseudoLibrary ("family", "filename")Form factor calculation is centralized in
form_factors.jl
: angular + radial partsInterpolations.jl
(GPU-supported)Structure factor and structure factor gradients are centralized in
structure_factors.jl
Projection vector construction is centralized in
projection_vectors.jl
Local atomic superposition (i.e. valence density, core density, and local potential) construction and force calculations (for
AtomicLocal
andXc
terms) are centralized inatomic_superposition.jl
Density guess code is refactored and much much shorter (using
atomic_superposition.jl
)New orbital guess code is in
orbitals.jl
, using UPF'sPSWFC
Construction of all the affected Hamiltonian terms with HGH, UPF, and PSP8 pseudopotentials is working
Total energies, forces, and stresses (with AD) are working and agree for at least
silicon.jl
PlaneWaveBasis
construction time is 5~20x faster depending on the discretization parameters, system size, pseudopotential type, interpolation method, quadrature method, ....compute_forces
andcompute_stresses
also see a good speedupguess_density
is faster, but it was never slowA non-zero amount of effort has been put in to get pseudos-on-GPU working: radial Fourier transforms, interpolation, etc. can all be done on GPU. Some deep sleuthing will need to be done to make the code compile with CUDA though (I get all sorts of invalid IR problems, mostly to do with
compute_angular_form_factors
andcompute_radial_form_factors
for the moment).Pain points
AtomsBase
support is broken; need to think about how to serialize theElement
s with their potentials. The potentials have the file content hash and DFTK identifier / filepath / PseudoLibrary identifier from loading, which should be enough.In-depth discussion
Summary
This draft replaces the existing framework for (pseudo-)atomic potentials with the packages
AtomicPotentials.jl
andPseudoPotentialIOExperimental.jl
.Previous implementation
Proposed impelmentation
Loading pseudopotentials / construction atomic potentials
For pseudopotentials, the target interface is:
Internally,
load_psp
determines whether the string is a DFTK-style identifier or not; it then resolves the identifier to a file path or (family, file) pair and callsload_psp_file
fromPseudoPotentialIO.jl
. The resultingPsPFile
is then loaded into anAtomicPotential
byAtomicPotentials.jl
.For arbitrary potentials, the interface is:
Make-up and functionality of atomic potentials
Currently
AtomicPotential
s can hold all relevant quantities for separable norm-conserving and ultrasoft pseudopotentials:It keeps track of the evaluation space of all its component quantities and provides some convenience functions for accessing quantities and their metadata and for transforming the potential as a whole.
Quantities
Quantities can exist in real or Fourier space, and be flagged as analytical or numerical. Both these flags affect how the quantity is evaluated and Fourier transformed.
Real-space and Fourier-space
These flags are used to dispatch on evaluation functions for analytical potentials.
Numerical and Analytical
These flags are used to dispatch on radial Fourier transform functions; either using numerical integration or for simply swapping the RealSpace/FourierSpace type parameter so that evaluation dispatches to the appropriate method.
Efficient evaluation
One of, if not the, most expensive part of using numerical pseudo-potentials is computing the radial Fourier transform
AtomicPotentials.jl
provides the functionrft
to evaluate this transform using a variety of quadrature methods. It also provides a variety of interpolation methods so that the transform can be evaluated on a selected set of points and then interpolated onto, e.g., the full G-vector grid of a plane-wave basis.Efficient and reusable code in DFTK
Fourier transforms of atomic quantities
Local quantities, e.g. core/valence charge density or local potential, all behave in similar ways and are used in similar ways in DFTK.
Building density guesses, and instantiating the
AtomicLocalPotential
andXc
terms share a common motif:Non-local quantities, e.g. Kleinman-Bylander projectors or (pseudo-)atomic orbitals, behave in a slightly different way in that their form-factor has an additional angular part:
An obvious method for reducing code complexity here is to have a minimal set of functions which are shared:
form_factor_radial
is particularly expensive due to it being a radial Fourier transform of a real-space function. Therefore, in practice,form_factor_radial
is used as follows.Numerical quantities are radial Fourier transformed before the inner loops described below. They are evaluated on a uniform mesh of points taken as input to the
PlaneWaveBasis
using a quadrature method also taken as input. The resulting Fourier-space quantity is interpolated using a method taken as input by thePlaneWaveBasis
. The resulting interpolator is then passed toform_factor_radial
which evaluates it.Analytical quantities are passed around with no changes. If they are in Fourier space,
form_factor_radial
simply evaluates them. If they are in Real space, it first callsrft
to retrieve a copy of the quantity with theEvaluationSpace
type parameter changed. Then it evaluates the quantity as above.Computing each of these terms for all G-vectors$Q$ and all of the various indices becomes increasingly expensive, so minimizing or removing repeated calculations is important. Therefore, each term is calculated separately only for indices and arguments on which it actually depends. A mostly true-to-life example for building projection vectors for the non-local potential is shown below: