mirror of
https://github.com/nwchemgit/nwchem.git
synced 2026-07-21 06:25:21 -04:00
522 lines
24 KiB
TeX
522 lines
24 KiB
TeX
\documentstyle{article}
|
|
\begin{document}
|
|
|
|
\title{API for plane-waves in NWChem}
|
|
|
|
\author{Arthur Smith}
|
|
|
|
\date{\today}
|
|
\maketitle
|
|
|
|
\section{General outline}
|
|
There are two general features of plane-wave basis sets which justify
|
|
a substantially different treatment from, for example, Gaussian basis
|
|
sets. First, the basis set is not linked to the actual atomic positions,
|
|
other than to the size of the periodic cell in which the atoms are contained,
|
|
(in fact, for plane waves each individual basis element extends throughout
|
|
this cell). Second, the basis sets tend to be very large while calculations
|
|
involving a single basis element (overlaps for example) are essentially
|
|
trivial, so the computational challenges differ considerably. For plane-wave
|
|
density-functional theory with separable non-local pseudopotentials,
|
|
all calculations can be accomplished in a time linear (or $N \log(N)$) in
|
|
the basis-set size (there are further dependences on the number of atoms
|
|
and orbitals, of course).
|
|
|
|
Both of these features (independence of atomic positions, and large
|
|
size with mostly trivial overlaps) can also be said to apply to
|
|
other types of basis sets that we may wish to implement in the future:
|
|
pure real-space grid methods (the plane-wave technique already does
|
|
much of the computation on a real-space grid), multi-grid methods,
|
|
mixed-basis techniques, or even wavelets. I believe the API should
|
|
be designed in such a way that programmers will need to make only minimal
|
|
modifications to a higher-level application code in order to utilize
|
|
a new basis set when/if one becomes available.
|
|
|
|
\section{Pre-requisites}
|
|
|
|
Plane-wave basis sets are only directly applicable to periodic systems -
|
|
solids in particular, although other systems can be readily treated
|
|
by super-cell methods. Thus the application must have previously
|
|
specified a periodically repeated cell of some sort.
|
|
|
|
In addition,
|
|
particularly for relative small periodic cells, a collection of
|
|
special {\bf k}-points must be specified (selected according to the
|
|
cell symmetry) which will be used to approximate the integration of
|
|
quantities over the Brillouin zone of the cell with a weighted sum
|
|
over these {\bf k}-points.
|
|
|
|
For large systems or for molecules/clusters treated in the supercell
|
|
approximation, it is often appropriate to just use the single point
|
|
{\bf k = 0}. In any case, the code should assume the {\bf k}-points
|
|
have been previously specified.
|
|
|
|
\section{Handling the basis sets}
|
|
|
|
There is then a slightly different plane-wave basis set for each
|
|
{\bf k}-point, and another (usually larger one) for the charge density.
|
|
These are specified by the dimensions of the periodic
|
|
cell of the system, and by some sort of cutoff - generally the requirement
|
|
that:
|
|
\begin{equation}
|
|
\hbar^2|{\bf k + G}|^2/2m < E_{cut}
|
|
\end{equation}
|
|
for the wavefunction basis sets and:
|
|
\begin{equation}
|
|
\hbar^2 |{\bf G}|^2/2m < d \cdot E_{cut}
|
|
\end{equation}
|
|
for the charge density, where the parameter $d$ is between 1 and 4 and
|
|
determines the degree to which the charge density completely reproduces
|
|
all oscillations in the wavefunctions.
|
|
|
|
The reciprocal lattice vectors {\bf G} are simply integer linear combinations
|
|
\begin{equation}
|
|
{\bf G}^{\alpha} = n^{\alpha}_1 {\bf b}_1 + n^{\alpha}_2 {\bf b}_2 +
|
|
n^{\alpha}_3 {\bf b}_3
|
|
\end{equation}
|
|
of the fundamental reciprocal lattice vectors ${\bf b}_i$, which satisfy
|
|
\begin{equation}
|
|
{\bf b}_i \cdot {\bf a}_j = 2 \pi \delta_{ij}
|
|
\end{equation}
|
|
and where the ${\bf a}_j$ are the fundamental lattice vectors specifying
|
|
the periodic cell of the system.
|
|
|
|
The {\bf G} values used (and the corresponding $n^{\alpha}_i$ triplets)
|
|
are specified by spherical (ellipsoidal) regions surrounding the origin for
|
|
the charge density and {\bf k = 0} wavefunctions, or by similar regions
|
|
surrounding points close to the origin for ${\bf k} \neq {\bf 0}$.
|
|
|
|
In order to apply Fast-Fourier-Transform (FFT) techniques to allow
|
|
transformations between the plane-wave basis set and a real-space grid on
|
|
which charge density and potential calculations are performed,
|
|
the triplets $n^{\alpha}_i$ must be mapped to corresponding points in
|
|
a three-dimensional integer rectangular grid $N_1 \times N_2 \times N_3$.
|
|
Each of the $N_i$ must be greater than twice the largest absolute value
|
|
of all the $n_i$, and for most library FFTs must be a power of two. After
|
|
applying the FFT, the resulting data is associated with a real-space grid
|
|
at the points:
|
|
\begin{equation}
|
|
{\bf r}_{ijk} = {i \over N_1} {\bf a}_1 + {j \over N_2} {\bf a}_2 +
|
|
{k \over N_3} {\bf a}_3
|
|
\end{equation}
|
|
|
|
Note that the point i, j, k in the $N_1 \times N_2 \times N_3$ reciprocal
|
|
space array is associated with a triplet $n^{\alpha}_l$ close to the
|
|
origin as follows:
|
|
\begin{equation}
|
|
{\rm if\ \ } i < N_1/2 {\rm\ \ then\ \ } n^{\alpha}_1 = i
|
|
\end{equation}
|
|
\begin{equation}
|
|
{\rm if\ \ } i > N_1/2 {\rm\ \ then\ \ } n^{\alpha}_1 = i - N_1
|
|
\end{equation}
|
|
and similarly for j and k.
|
|
|
|
|
|
\subsection{Data distribution}
|
|
Utilizing these FFT methods, the application of the Hamiltonian to
|
|
a wavefunction involves diagonal operators or products of diagonal
|
|
operators (see the section on applying H to $\psi_i$ below). One
|
|
nice aspect of a diagonal operator on a parallel computer is that
|
|
however the vectors involved are distributed on the machine, application
|
|
of the operator involves no communication (as long as the components
|
|
of the operator itself are either distributed in the same way as the
|
|
vectors, or are calculated when needed). In other words, calculation of
|
|
\begin{equation}
|
|
g_i ({\bf r}) = f({\bf r}) \psi_i({\bf r})
|
|
\end{equation}
|
|
is a local operation, no matter where the components $\psi_i({\bf r})$
|
|
actually reside.
|
|
|
|
However, communication {\it is}\ required during the FFT operations
|
|
if $\psi_i({\bf r})/\psi_i({\bf G})$ is distributed in {\bf r}/{\bf G},
|
|
and extensive communication
|
|
is also required during orthogonalization and similar inner-product
|
|
operations if $\psi_i({\bf r})/\psi_i({\bf G})$ is distributed in the
|
|
index $i$. In addition, since we are thinking of data-decomposition and not
|
|
task-decomposition here, steps must be taken to ensure that every
|
|
process carries roughly the same number of coefficients $\psi_i({\bf G})$,
|
|
which is best accomplished by some form of interleaving. Note that
|
|
$\psi_i({\bf r})$ will naturally be evenly distributed in {\bf r} under most
|
|
decompositions because the {\bf r} lie on a rectangular grid, while
|
|
the relevant {\bf G} values lie within a sphere, for which block
|
|
decompositions may leave some processors with few or no {\bf G}-vectors.
|
|
|
|
A further complication in the {\bf k = 0} situation is that the
|
|
coefficients for {\bf G} and {\bf -G} are complex conjugates, and therefore
|
|
nearly a factor of two in memory and speed can be gained by keeping only
|
|
one of the two coefficients. But that means in the data decomposition,
|
|
{\bf G} and {\bf -G} should be covered by the same process, requiring
|
|
a reversed interleaving for negative values of the $n_i$.
|
|
|
|
\subsection{The initialization API}
|
|
Thus the fundamental information needed to initialize a particular plane-wave
|
|
basis set is:
|
|
\begin{enumerate}
|
|
\item The periodic cell vectors ${\bf a}_i$
|
|
\item The {\bf k}-vectors used.
|
|
\item The energy cutoff $E_{cut}$
|
|
\item The charge density basis parameter $d$.
|
|
\item Some information about number of processes, preferred data
|
|
decomposition, and possibly process communication topology, in order
|
|
to determine the distribution of G and R vectors among nodes.
|
|
\item Preferred values of $N_1, N_2, N_3$ (optional)
|
|
\item The vectors ${\bf b}_i$ (optional - might be useful
|
|
for modularization).
|
|
\end{enumerate}
|
|
|
|
Returned from the initialization will be:
|
|
\begin{enumerate}
|
|
\item The size of the basis set for each k-point, and for the charge
|
|
density, including total size, and number allocated to this process.
|
|
\item Some form of listing of the G-vectors: at least the $n^{\alpha}_i$,
|
|
preferably also the actual vectors {\bf G} and their (squared?) magnitudes.
|
|
\item The output values of $N_1, N_2, N_3$ for the whole space and
|
|
for the sub-blocks (or other arrangement) allocated to this process.
|
|
\item Optionally, the ${\bf b}_i$ vectors.
|
|
\end{enumerate}
|
|
|
|
\subsection{The allocation API}
|
|
Typically, we'll be allocating some number $n_{orbitals}$ of
|
|
complex coefficients of the $ng({\bf k})$ plane waves for each of
|
|
the {\bf k}. In addition, there will be several auxiliary arrays
|
|
individually of approximate size $ng$, including arrays to handle
|
|
the charge density and components of the potential. And we also need
|
|
a few complex and real arrays on the $N_1\times N_2 \times N_3$
|
|
real-space grid.
|
|
|
|
These would presumably be allocated with GA routines or something
|
|
similar - for example in our hybrid decomposition approach, the first
|
|
set of coefficient arrays would be distributed across all the processors. The
|
|
second set, of auxiliary arrays, would be distributed across the processors
|
|
within a group (the spatial decomposition subgroups) but duplicated (sometimes
|
|
with identical data) in all such groups, in order to eliminate all
|
|
communications except during FFT and orthogonalization (and global operation)
|
|
routines.
|
|
|
|
Inputs then to an allocator would be:
|
|
\begin{enumerate}
|
|
\item A tag specifying the basis set (previously initialized).
|
|
\item The data type of the coefficients (real or complex, or something else?)
|
|
\item The number of ($ng$ arrays) of this type to be
|
|
allocated ($n_{orbitals}$ for example.
|
|
\item Optionally: A flag indicating whether the data should be
|
|
initialized with random values or with zeroes.
|
|
\end{enumerate}
|
|
|
|
Output would be a tag specifying the coefficient matrix, similar to
|
|
GA matrix allocation, maybe?
|
|
|
|
\subsection{API for basis set operations}
|
|
|
|
Once we have the basis set specifications, there are a number of
|
|
operations we'll need to do anything with them:
|
|
\begin{enumerate}
|
|
\item Copy
|
|
\item Scale or AXPY
|
|
\item application of a diagonal operator (GBMV?)
|
|
\item Inner product
|
|
\item Send and receive, or get and put to a different process
|
|
\item Transformation between basis sets
|
|
\item Computation of basis set overlaps for different basis sets
|
|
\end{enumerate}
|
|
|
|
Most of these are straightforward: probably only the last two
|
|
will require much thought. We'll want to do more complicated
|
|
things with the charge density (at least in calculation of
|
|
the exchange-correlation energy), but that is probably a special
|
|
case that can be dealt with separately.
|
|
|
|
There are a couple of transformations between basis sets we
|
|
might want to consider implementing initially: within a G-space
|
|
representation, changing form one cutoff energy to a different
|
|
one is trivial in principle (just chop, or zero-pad) but
|
|
not necessarily in practice where reading in a starting configuration
|
|
from an old basis set may misplace coefficients if you are not
|
|
careful (we have not yet successfully implemented this using
|
|
our current code, for example). Transformations between G-space and
|
|
real-space are essential to computation of the charge density and
|
|
evaluation of the real-space potentials, and this can be viewed
|
|
as one kind of general basis-set transformation (implemented
|
|
through fast Fourier transforms).
|
|
|
|
I think computation of overlaps will not be necessary until
|
|
mixed Gaussian and plane-wave bases are being considered, but
|
|
it might be worth-while thinking about how to do it now.
|
|
|
|
\section{Applying H to $\psi_i$}
|
|
|
|
We can use various minimization techniques to isolate the
|
|
lowest $n_{occupied}$ eigenstates of H. Because $ng$ is so much
|
|
larger, we never want to construct the full $ng\times ng$ matrix,
|
|
so most of these techniques start from the residual
|
|
\begin{equation}
|
|
H \psi_i - \epsilon_i \psi_i.
|
|
\end{equation}
|
|
and the most computationally intensive part of the code is
|
|
going to be evaluation of the Hamiltonian-vector product H$\psi_i$.
|
|
|
|
\subsection{Kinetic energy}
|
|
|
|
The kinetic energy operator is evaluated in the reciprocal space
|
|
representation:
|
|
\begin{equation}
|
|
T \psi_i({\bf G}) = {\hbar^2|{\bf k + G}|^2 \over 2m} \psi_i({\bf G})
|
|
\end{equation}
|
|
|
|
The values of $|{\bf k + G}|^2$ should be pre-stored (possibly
|
|
returned from the initialization routine above) and so this is
|
|
a straightforward operation. However, since this is peculiar to
|
|
the plane-wave basis, it might be a good idea to define a kinetic
|
|
energy API (for example, for pure real-space grids, the kinetic energy
|
|
could be evaluated using finite-difference techniques). For such
|
|
an API the input is a basis-set specifier and the coefficient matrix
|
|
(with an integer specifying how many orbitals to work on at once)
|
|
and output is the matrix of result vectors (placed in a work area provided).
|
|
|
|
\subsection{The real-space potentials}
|
|
|
|
These are comprised of the local pseudopotential, the Hartree
|
|
(electron-electron Coulomb) potential and the exchange-correlation potential.
|
|
The potentials themselves are evaluated as follows:
|
|
\begin{equation}
|
|
V_{local}({\bf G}) = \sum_{is} u_{is}({\bf G}) S_{is}({\bf G})
|
|
\end{equation}
|
|
where $is$ is an index counting the atomic species in the system,
|
|
$u_{is}$ is the potential from a single atom of this species, and
|
|
$S_{is}$ is a structure factor for the species:
|
|
\begin{equation}
|
|
S_{is}({\bf G}) = \sum_{ia} \exp(i {\bf G}\cdot {\bf r}_{ia})
|
|
\end{equation}
|
|
where $ia$ runs over all atoms of species $is$. $u_{is}$ and $S_{is}$
|
|
would be distributed in the same fashion as the {\bf G}'s, but with
|
|
all species $is$ together (not distributed), and so duplicated
|
|
in the same fashion as $V_{local}({\bf G})$ itself: among processes with the
|
|
same {\bf G}'s but different collections of orbitals. So this computation
|
|
involves no communication, except for the FFT required in the end
|
|
to produce a real-space potential.
|
|
|
|
The electron-electron direct Coulomb interaction is easily evaluated:
|
|
\begin{equation}
|
|
V_{Hartree}({\bf G}) = 4\pi \rho(G)/G^2
|
|
\end{equation}
|
|
except for ${\bf G} = {\bf 0}$ where the corresponding term is
|
|
a constant that is added to the constant electrostatic energy of the
|
|
periodic system usually evaluated by Ewald summation. Similarly, the
|
|
only communication required here is the final FFT, although there
|
|
will be duplication if the orbitals are distributed.
|
|
|
|
Both $V_{local}$ and $V_{Hartree}$ are then FFT'd to real space, and
|
|
can be added to the exchange correlation potential:
|
|
\begin{equation}
|
|
V_{xc}({\bf r}) = V_{xc}(\rho({\bf r}), \nabla \rho({\bf r}), ...)
|
|
\end{equation}
|
|
which requires no communication at all, except in the
|
|
evaluation of the charge density and gradients:
|
|
|
|
The charge density $\rho({\bf r})$ is calculated as the sum
|
|
\begin{equation}
|
|
\rho({\bf r}) = \sum_{i} |\psi_i({\bf r})|^2
|
|
\end{equation}
|
|
and the gradient is:
|
|
\begin{equation}
|
|
\nabla\rho({\bf r}) = FFT \bigl\{ i {\bf G} \rho({\bf G}) \bigr\}
|
|
\end{equation}
|
|
and similarly for higher derivatives.
|
|
|
|
The duplication discussed could be eliminated at the expense of
|
|
more communication: we should probably study this at some point. In
|
|
particular since the gradient-dependent exchange correlation potential
|
|
cannot be done by table-lookup (because it depends on more than one
|
|
parameter, unlike the LDA) the computation involved may be sufficient
|
|
to justify distributing it.
|
|
|
|
An API for a set of subroutine calls to evaluate these potentials
|
|
seems appropriate - what is needed on input is quite a variety of
|
|
things: for the charge density calculation we probably want to
|
|
pass the basis set information and the G-space coefficient matrix,
|
|
and the output would be either the charge density on the real-space
|
|
grid, or else the fitted charge-density in G-space (or both).
|
|
For the local potential we need to pass in geometry information and
|
|
information about the pseudopotential, as well as the basis set - output
|
|
is the G-space representation of that potential. For the Hartree potential
|
|
we pass in the charge density and basis set info, output is the G-space
|
|
potential. For the gradients calculation pass in the G-space charge
|
|
density, return the real-space charge density and gradients to be
|
|
passed to an exchange-correlation subroutine, or else just return the
|
|
real-space exchange-correlation potential.
|
|
|
|
We also need an initialization API for the pseudopotential to
|
|
generate the $u_{is}({\bf G})$, and
|
|
for the exchange-correlation potentials (at least to allow
|
|
choices between the possibilities, and also possibly to allow
|
|
setting some of their parameters). More on the pseudopotential below...
|
|
|
|
\subsection{The non-local pseudopotential}
|
|
Using the Kleinman-Bylander separable decomposition, the non-local
|
|
pseudopotential (for each species $is$!) can be evaluated in
|
|
reciprocal space as follows (from memory, so bear with me if I
|
|
missed a minus sign or something):
|
|
\begin{eqnarray}
|
|
V_{nl}^{lm} \psi_i ({\bf G}) = C^l
|
|
&\sum_{ia} U_{nl}^l({\bf k+G})Y_{lm}^*({\bf k + G})
|
|
\exp(i {\bf G}\cdot{\bf r}_{ia}) \cdot \cr
|
|
&\sum_{{\bf G}'} U_{nl}^l({\bf k + G}')Y_{lm}({\bf k + G}')
|
|
\exp(-i {\bf G}'\cdot{\bf r}_{ia})
|
|
\psi_i({\bf G}')\cr
|
|
\end{eqnarray}
|
|
where $ia$ is an index over all the atoms of species $is$, and $l$, $m$ are
|
|
standard angular momentum quantum numbers. The $U_{nl}^l$ and $Y_{lm}$
|
|
can be computed at initialization and are $O(N)$ in size so not too bad.
|
|
This would then be summed over $l$, $m$, and species $is$.
|
|
|
|
One big potential problem data and
|
|
communication-wise here is the $\exp(i {\bf G}\cdot {\bf r}_{ia})$ matrix,
|
|
which if precomputed and stored is $O(N^2)$ in size, and yet needs to be present
|
|
for {\bf all} the orbitals (note that non-local calculation is an $O(N^3)$
|
|
operation and thus one of the major time-consuming parts of the computation
|
|
for large systems). What we do is evaluate the matrix only for {\bf G}
|
|
vectors along the principal axes ${\bf b}_i$, and then compute the product
|
|
of three complex numbers to get the final value when needed - this means
|
|
we need to only store a matrix $O(N^{4/3})$ in size, but we need to
|
|
ensure the correct sort of data-locality for that matrix.
|
|
|
|
There are other ways of doing the nonlocal pseudopotentials: real-space only
|
|
evaluations for example, or taking advantage of possible redundancy if a part
|
|
of the system has a shorter periodicity (for example, the bulk portion of
|
|
a surface problem) or other symmetry, or using complicated hybrids like
|
|
the ultra-soft Vanderbilt pseudopotentials, and presumably other methods
|
|
will come along.
|
|
|
|
So I think two (or possibly three) subroutine calls would be involved
|
|
that could be standardized on: initialization of the pseudopotential
|
|
(calculation of the $U_{nl}({\bf k+ G})$ and local $u({\bf G})$ values)
|
|
and of other needed quantities ($Y_{lm}({\bf k + G})$ and the
|
|
$\exp(i {\bf G}\cdot {\bf r}_{ia})$ matrix); and application of
|
|
the pseudopotential to a set of orbitals (either with an ion force
|
|
calculation, or with forces calculated separately).
|
|
|
|
\subsection{Dealing with the pseudopotentials}
|
|
|
|
There may be several types of pseudopotentials we would want to
|
|
handle - for example, it might be worth testing the Gaussian-derived
|
|
ECP's with plane waves (maybe not?) Anyway, we must initially
|
|
read in some representation of the pseudopotentials about each species
|
|
of atom in the system, and the input format we currently use most
|
|
often is a simple radial grid. These then need to be converted to
|
|
the local $u({\bf G})$ and nonlocal $U_{nl}({\bf k+G})$ forms needed in
|
|
the actual application of the pseudopotentials.
|
|
|
|
Thus there needs to be some specification of the input representation
|
|
of the pseudopotentials, and an initialization routine for converting
|
|
that representation to one appropriate for the basis set. The associated
|
|
API would have as input the input representation and specification
|
|
of the (plane-wave) basis set, and as output the converted pseudopotential
|
|
values.
|
|
|
|
\section{Achieving self-consistency}
|
|
|
|
With plane-wave basis sets the central problem of converging to
|
|
a self-consistent charge-density (represented by a collection of
|
|
occupied Kohn-Sham eigenfunctions) is fundamentally the same as for
|
|
density functional theory with other basis sets. However, the principal
|
|
constraint imposed by the large size of the plane-wave basis set is
|
|
that we never know the full matrix $H$, only matrix-vector products
|
|
$H \psi_i$, meaning that direct diagonalization cannot be performed,
|
|
and instead iterative approaches are needed. In addition, of course,
|
|
$H$ itself changes with each iteration because the charge density
|
|
is changing. Among a wide variety of possibilities there are basically
|
|
two iterative schemes that have become adopted in plane-wave basis-set
|
|
methods: Car-Parrinello ``molecular-dynamics'' type iterations, and
|
|
Teter-Payne-Allen preconditioned gradient iterations (often
|
|
misnamed ``conjugate gradient'' iterations because the first implementation
|
|
happened to use a multiple conjugate gradients updating scheme that
|
|
has since proved inefficient compared to just using a single preconditioned
|
|
gradient).
|
|
|
|
The Car-Parrinello approach is to treat the energy gradient $H\psi$ as
|
|
a force on the coefficients of $\psi$, so that in a ``time-step'' $\tau$,
|
|
\begin{equation}
|
|
\psi_i(t + \tau) = \psi_i(\tau) - {\tau^2 \over 2 m_{eff}} H\psi_i(tau),
|
|
\end{equation}
|
|
after which the new $\psi_i$ are orthogonalized to one another.
|
|
When doing real dynamics a velocity term may also be included - as stated
|
|
this is effectively just a steepest-descents algorithm. As such it
|
|
is simple but rather inefficient for getting self-consistency, but
|
|
on the other hand it is rather robust (always converging to the lowest
|
|
occupied subspace, if you wait long enough) and in fact when coupled
|
|
with atomic dynamics can be competitive with the Born-Oppenheimer
|
|
approach required when using the preconditioned gradient methods.
|
|
|
|
The preconditioned gradient methods have the following iterative step:
|
|
\begin{enumerate}
|
|
\item Generate residual vectors: $ R_i = (H - \epsilon_i) \psi_i$
|
|
\item Apply a preconditioner: $B_i = P R_i$. As with the
|
|
Davidson method, the preconditioner should be close to an inverse
|
|
of the Hamiltonian. In practice, a rational function of the kinetic
|
|
energy (approaching 1/K.E. for high energy) works well with a
|
|
plane-wave basis set.
|
|
\item Orthogonalize the $B$'s to one another and to the $\psi's$.
|
|
\item Generate $ H B_i $ and the subspace matrix $ <V_i|H|V_j>$ where
|
|
$V_i$ is $\psi_i$ for $i < n$ and $B_{i - n}$ for $i >= n$.
|
|
\item Diagonalize within the subspace, and let the new $\psi$ vectors
|
|
be the lowest $n$ eigenvectors.
|
|
\item Generate the new charge density (generally by mixing in some
|
|
of the old, otherwise instabilities arise) and the resulting new
|
|
Hamiltonian, and repeat.
|
|
\end{enumerate}
|
|
These methods (there are variants based on whether you let $n = 1$ and
|
|
have an outer loop over bands, or else let $n =$ all states, or else
|
|
with different preconditioners) tend to be much faster than the
|
|
steepest-descent approach to obtain a self-consistent set of electronic
|
|
states. On the other hand they require more computation per step
|
|
(twice as many Hamiltonian-vector operations, for example) and experience
|
|
shows they tend to be less robust.
|
|
|
|
Both methods could be implemented with no knowledge of the
|
|
underlying basis sets or data decomposition, as long as the
|
|
following subroutine calls were available:
|
|
\begin{enumerate}
|
|
\item Application of $H$ to $\psi$-type vectors
|
|
\item Application of a preconditioner to $\psi$-type vectors
|
|
\item AXPY operations on $\psi$-type vectors and $\rho$-type vectors
|
|
\item Inner products on $\psi$-type vectors (at least for
|
|
generating the $<V|H|V>$ matrix, possibly also for orthogonalization unless
|
|
that was a separate subroutine call)
|
|
\item Generating $\rho$ from $\psi_i$, and modifying $V_{xc}$ and $V_{Hartree}$
|
|
accordingly, to complete the self-consistent loop.
|
|
\end{enumerate}
|
|
In addition, a diagonalization routine for $2 n\times 2 n$ matrices is
|
|
needed, and probably should be done in parallel in accordance with
|
|
the orbital decomposition of the data.
|
|
|
|
\section{Energy and forces}
|
|
|
|
At the highest level, an API that calls on the electronic
|
|
energy minimization to generate the energy and forces for a particular
|
|
configuration of atoms might be workable, and would certainly be
|
|
useful. This would facilitate rapid comparison of different methods
|
|
for a particular problem, in addition to providing a natural interface
|
|
for standard molecular dynamics codes.
|
|
|
|
Input to such a high level API would include:
|
|
\begin{enumerate}
|
|
\item Geometry - atomic configuration
|
|
\item Basis set, pseudopotential specifications (data decomp?)
|
|
\item (Optionally) Trial set of orbitals
|
|
\item Convergence parameters: iteration method, maximum number of
|
|
iterations, tolerance on the final numbers
|
|
\end{enumerate}
|
|
|
|
Output would of course be energy and forces, as well as
|
|
(optionally) a final set of orbitals for restarting, and a flag
|
|
specifying whether the convergence tolerance was actually reached.
|
|
|
|
In addition, I think it would be important to have callable
|
|
routines that estimate (or at least keep track of) memory usage
|
|
and time per iteration, to allow analysis of resource utilization
|
|
by the calling program. To do the estimate means having some kind
|
|
of performance model of the code - we do already have such a thing
|
|
for the memory usage, but have never tried it for timing...
|
|
|
|
\end{document}
|
|
\bye
|