\chapter{Calculation of Electron Density}\index{DENSITY!program|ff}
\index{Electron!density}
\section{Theory}
First of all, let us understand what is meant in this Chapter by electron
density.
\index{Density matrix}
A density matrix is generated during a SCF calculation.  This density matrix
represents the distribution of electrons in atomic orbitals; thus, for H$_2$,
the density matrix would be:
\[
\left | \begin{array}{cc} 1.0 & 1.0 \\ 1.0 & 1.0 \end{array} \right |
\]
This particular matrix indicates that there is one electron on each of atomic
orbitals $\varphi_1$ and $\varphi_2$, and that this density is modified by 1.0
times the product of $\varphi_1\varphi_2$.

In this Chapter we will be concerned, not with the density matrix {\em per se},
but with the electron density.  Electron density is the density of electrons in
electrons per cubic \AA ngstrom at a defined point in space.  In order to be
useful,  a surface of constant electron density, or a cross-section through a
system, will usually be generated.

\index{Eigenvectors}
The density matrix arises from the normalized eigenvectors.  These, in turn,
are generated by diagonalizing the Fock matrix in the eigenvalue equation.  In
NDDO \index{NDDO} methods, the assumption of Neglect of Diatomic Differential
Overlap is made. This assumption is not valid when electron density plots are
being generated.

\paragraph*{Failure of NDDO Approximation}
Before going on to calculate  electron density, let us examine the reason for
the breakdown of the NDDO approximation when electron density is being
calculated.

Consider again the H$_2$ system.  The bonding M.O.\  is $\psi =
1/\sqrt{2}(\varphi_1 + \varphi_2)$, which is   the M.O.\ which gives rise to the
density matrix shown above.

Consider what would happen if the electron density were to be calculated using
this density matrix.  For each point in space there would be a density, $\rho(x,y,z)$,
which would arise from:
$$
\rho(x,y,z) = 1.0\varphi_1(x,y,z)^2 + 1.0\varphi_2(x,y,z)^2 + 2.0\varphi_1(x,y,z)\varphi_2(x,y,z)
$$
Now, the integral of this function over all space would equal the number of electrons
in H$_2$:
$$
 N_e = \int_{-\infty}^{+\infty}\int_{-\infty}^{+\infty}\int_{-\infty}^{+\infty}\rho(x,y,z)dx\,dy\,dz
$$
 The integral over all space of a normalized atomic orbital is 1.00; therefore,
$$
N_e = 1.0 + 1.0 + 2<\varphi_1\varphi_2> \neq 2,
$$

In other words, the total number of electrons in H$_2$, assuming the NDDO
approximation,  is greater than 2.0.  The extra density comes from the product
$ 2.0\varphi_1(x,y,z)\varphi_2(x,y,z)$, which must not be neglected.  If it
were to be neglected, then all phenomena such as bonds and lone pairs could not
be modeled.

Another way of looking at this is to recognize that, in H$_2$, electron density
between the atoms is greater when a bond exists than when it does not exist.
Given this, it follows that, in order to ensure that the total number of
electrons in the system remains constant when a bond forms, at some other point
in space the electron density must be less when a bond exists than when it does
not exist.  In other words, if density builds up in some region of space, then
it must become less somewhere else in order that the total number of electrons
would remain constant.

\paragraph*{Starting M.O.s}

Because of the failure of the NDDO approximation, the M.O.s must be re-normalized
before the density is calculated.  This is most easily done by performing the
operation
$$
  \psi = S^{-1/2}\psi'S^{-1/2},
$$
where $\psi'$ is the original NDDO molecular orbital, and $S$ is the overlap matrix over atomic orbitals.
In practice, it is easier to matrix-multiply $\Psi =  S^{-1/2}\Psi'S^{-1/2}
$, as this generates all the M.O.s in one operation.
From these re-normalized M.O.s, a re-normalized density matrix can
be calculated in the normal way:
$$
 P'_{\lambda\sigma}=2\sum_i^{occ}c_{\lambda i} c_{\sigma i}.
$$
\paragraph*{Calculation of Electron Density}
In order to calculate electron density for any given point, the value of
each atomic orbital must be calculated.  Atomic orbitals, as Slaters, are
of form
$$
\varphi = Nf_rf_{\theta\phi},
$$
in which $N=c\frac{(2\xi)^{n+1/2}}{(2n)!2\sqrt{\pi}}$, where $\xi$ is the orbital
exponent, $n$ is the principal quantum number, and $c=1$ for $s$ orbitals,
$\sqrt{3}$ for $p$ orbitals, and $\sqrt{15}$ for $d$ orbitals.
At any given point, the value of $\varphi$ is given as the product of the
normalization constant, the radial term, and the angular component.  The
radial term is simply $f_r=r^{n-1}e^{-\xi r}$, where $r$ is the distance
from the point under study to the atomic center.
The angular terms are more complicated.  For a $s$-$p$-$d$ basis set, the
value of $\varphi$ is
\begin{eqnarray}
\varphi       _s          &=& Nf_r \nonumber  \\
\varphi       _{p_x}       &=& Nf_rx \nonumber  \\
\varphi       _{p_y}       &=& Nf_ry \nonumber  \\
\varphi       _{p_z}       &=& Nf_rz\nonumber  \\
\varphi       _{d_{x^2-y^2}}&=& Nf_r\frac{1}{2}(x^2-y^2)\nonumber  \\
\varphi       _{d_{xz}}     &=& Nf_rxz \nonumber \\
\varphi       _{d_{z^2}   } &=& Nf_r\frac{1}{\sqrt{12}}(2z^2-x^2-y^2)\nonumber  \\
\varphi       _{d_{yz }   } &=& Nf_ryz         \nonumber   \\
\varphi       _{d_{xy }   } &=& Nf_rxy         \nonumber
\end{eqnarray}
where $x$, $y$, and $z$ are the normalized direction components.
\paragraph*{Electron density}

The density at a point is then simply
$$
\rho(x,y,z) = \sum_{\lambda}\sum_{\sigma}
\varphi_{\lambda}(x,y,z)P_{\lambda\sigma}'\varphi_{\sigma}(x,y,z).
$$
This function is everywhere positive, although it may become vanishingly small.
\paragraph*{Molecular Orbitals}

Molecular orbitals can be generated by calculating the function
$$
\psi_i(x,y,z) = \sum_{\lambda}c_{\lambda i}\varphi_{\lambda}(x,y,z).
$$
Note that molecular orbitals are expressed in intensity, not density.
The intensity of a M.O.\ is its instantaneous value.  This should not
be confused with, e.g., electrons per cubic \AA ngstrom.

Except for very simple cases, such as the bonding M.O.\ in H$_2$, this function
will have both positive and negative regions.

\paragraph*{Bonds}
Bonds can be modeled by generating a difference map.  The density due to
the atoms can be subtracted from the density arising from the density matrix.
The density due to the atoms is that given by MOPAC: i.e., using the
un-re-normalized M.O.s, but spherically averaged before use, thus:
\begin{eqnarray}
P^{\dagger}_{ss}& =& P_{ss} \nonumber \\
P^{\dagger}_{p_xp_x}= P^{\dagger}_{p_yp_y}=P^{\dagger}_{p_zp_z}& =&\frac{1}{3}(P_{p_xp_x}+P_{p_yp_y}+P_{p_zp_z})\nonumber \\
P^{\dagger}_{d_{x^2-y^2}d_{x^2-y^2}}=P^{\dagger}_{d_{xz}d_{xz}} &=&\nonumber \\
P^{\dagger}_{d_{z^2}d_{z^2}}= P^{\dagger}_{d_{yz }d_{yz }}=P^{\dagger}_{d_{xy }d_{xy }}&=&\frac{1}{5}(P_{d_{x^2-y^2}d_{x^2-y^2}} +P_{d_{xz}d_{xz}} +P_{d_{z^2}d_{z^2}} +
P_{d_{yz }d_{yz }}+P_{d_{xy }d_{xy }}) \nonumber
\end{eqnarray}
Using this re-normalized, isotropic, density matrix the difference map can now be
calculated:
$$
\rho(x,y,z) = \sum_{\lambda}\sum_{\sigma}
\varphi_{\lambda}(x,y,z)P_{\lambda\sigma}^{\dagger}\varphi_{\sigma}(x,y,z) -\sum_{\lambda}
P^{\dagger}_{\lambda\lambda}(\varphi_{\lambda}(x,y,z))^2
$$
This map is the most informative, but is somewhat difficult to see when first used.

The difference map will {\em always} have both positive and negative regions in
space.  For most, but not all systems, bonding is indicated by a build-up of
density between two atoms.  Exceptions are, for example, F$_2$ and Cl$_2$.

\section{Program DENSITY}
% 139 lines, including this one
%\setlength{\unitlength}{0.07cm}

\begin{figure}
\begin{makeimage}
\end{makeimage}
\index{Benzene!DENSITY plot}
\index{Bonds!Density plot}
\index{GRID!DENSITY plot}
\begin{center}
\includegraphics{benzene2} \\~\\
\begin{latexonly}
\parbox{30em}{Keywords used are:

\comp{CENTER=(0.7,1.2,0) LINE=(0.0,0.0,1.0) EDGE=6.0}

Atom C$_1$ is at the origin, C$_2$ is at coordinates (0.0,1.39,0),
and C$_3$ is at (2.09,1.20,0).
Note that, because the atomic orbitals of carbon have a node at the
nucleus, the electron density at every carbon nucleus is almost
zero.}
\end{latexonly}
\begin{htmlonly}
Keywords used are:

\comp{CENTER=(0.7,1.2,0) LINE=(0.0,0.0,1.0) EDGE=6.0}

Atom C$_1$ is at the origin, C$_2$ is at coordinates (0.0,1.39,0),
and C$_3$ is at (2.09,1.20,0).
Note that, because the atomic orbitals of carbon have a node at the
nucleus, the electron density at every carbon nucleus is almost
zero.
\end{htmlonly}
\end{center}
\caption{\label{d_mol}Total electron density map for benzene}
\end{figure}

\begin{figure}
\begin{makeimage}
\end{makeimage}
\begin{center}
\includegraphics{benzene3} \\~\\
\begin{latexonly}
\parbox{30em}{Keywords used:

\comp{CENTER=(0.7,1.2,0) LINE=(0.0,0.0,1.0) EDGE=6.0 BONDS}

Note the build-up of density {\em between} all bonded pairs of atoms.

The six roughly triangular regions represent the loss of electron density,
as do the six egg-shaped lobes on the hydrogens.  In the center of the
benzene ring, there is no significant gain or loss of electron density.}
\end{latexonly}
\begin{htmlonly}
Keywords used:

\comp{CENTER=(0.7,1.2,0) LINE=(0.0,0.0,1.0) EDGE=6.0 BONDS}

Note the build-up of density {\em between} all bonded pairs of atoms.

The six roughly triangular regions represent the loss of electron density,
as do the six egg-shaped lobes on the hydrogens.  In the center of the
benzene ring, there is no significant gain or loss of electron density.
\end{htmlonly}
\end{center}
\caption{\label{d_mol1}Bonds map for benzene}
\end{figure}

\begin{figure}
\begin{makeimage}
\end{makeimage}
\begin{center}
\includegraphics{benzene} \\~\\
\begin{latexonly}
\parbox{30em}{Keywords used:

\comp{MULT=1 CENTER=(-0.27,-0.5,0) LINE=(0,0,1) EDGE=3 AXIS=.4 GRID NO-CONTOURS}

This type of plot is best viewed with the contours added in, but for the
sake of clarity they have been omitted from this picture.}
\end{latexonly}
\begin{htmlonly}
Keywords used:

\comp{MULT=1 CENTER=(-0.27,-0.5,0) LINE=(0,0,1) EDGE=3 AXIS=.4 GRID NO-CONTOURS}

This type of plot is best viewed with the contours added in, but for the
sake of clarity they have been omitted from this picture.
\end{htmlonly}
\end{center}
\caption{Detail of C-H bond in benzene}
\end{figure}

% 21 lines, including this one
% \setlength{\unitlength}{0.06cm}
\begin{figure}
\begin{makeimage}
\end{makeimage}
\index{Polyacetylene!DENSITY plot}
\index{Graphite!DENSITY plot}
\begin{center}
\includegraphics{polyacetylene_total} \\~\\
\begin{latexonly}
\parbox{30em}{Keywords used are:

\comp{CENTER=(0.0,0.0,0.0) LINE=(0,0,1) EDGE=7.0}

The picture is centered on atom C$_1$, and shows the `join' of the central
unit cell with the adjacent unit cell.  Note that the `join' is quite
invisible.}
\end{latexonly}
\begin{htmlonly}
Keywords used are:

\comp{CENTER=(0.0,0.0,0.0) LINE=(0,0,1) EDGE=7.0}

The picture is centered on atom C$_1$, and shows the `join' of the central
unit cell with the adjacent unit cell.  Note that the `join' is quite
invisible.
\end{htmlonly}
\end{center}
\caption{\label{d_solids}Total electron density map for polyacetylene}
\end{figure}

\begin{figure}
\begin{makeimage}
\end{makeimage}
\begin{center}
\includegraphics{polyacetylene_pi} \\~\\
\begin{latexonly}
\parbox{30em}{Keywords used:

\comp{CENTER=(0.0,0.0,0.6) LINE=(0,0,1) EDGE=7.0 BONDS}

As with benzene, note the build-up of density {\em between} all
bonded pairs of atoms.  In order to show the strong $\pi$-bond, the
center of the plot has been raised 0.6\AA\ above the backbone chain.}
\end{latexonly}
\begin{htmlonly}
Keywords used:

\comp{CENTER=(0.0,0.0,0.6) LINE=(0,0,1) EDGE=7.0 BONDS}

As with benzene, note the build-up of density {\em between} all
bonded pairs of atoms.  In order to show the strong $\pi$-bond, the
center of the plot has been raised 0.6\AA\ above the backbone chain.
\end{htmlonly}
\end{center}
\caption{\label{d_solids1}Bonds map for polyacetylene}
\end{figure}

\begin{figure}
\begin{makeimage}
\end{makeimage}
\begin{center}
\includegraphics{graphite001} \\~\\
\begin{latexonly}
\parbox{30em}{Keywords used:

\comp{CENTER=(0.0,0.0,0.0) LINE=(0,0,1) EDGE=4.0}

The center of the plot is at C$_{1,1}$ in a 5 $\times$ 5 array of atoms.
The picture therefore shows the `join' of four unit cells, cells (0,0),
(0,-1), (-1,0), and (-1,-1).  As with polyacetylene, the `join' is
invisible.}
\end{latexonly}
\begin{htmlonly}
Keywords used:

\comp{CENTER=(0.0,0.0,0.0) LINE=(0,0,1) EDGE=4.0}

The center of the plot is at C$_{1,1}$ in a 5 $\times$ 5 array of atoms.
The picture therefore shows the `join' of four unit cells, cells (0,0),
(0,-1), (-1,0), and (-1,-1).  As with polyacetylene, the `join' is
invisible.
\end{htmlonly}
\end{center}
\caption{\label{d_solids2}Graphite, Total Electron Density}
\end{figure}

The program DENSITY is designed to generate  maps of electron density
distribution and molecular orbital intensity within molecules
(Figure~\ref{d_mol}) and solids (Figure~\ref{d_solids}). Two main modes of
operation are provided: manual data input, which is a ``stand-alone'' mode, and
normal input, which assumes the existence of large unformatted data-files
produced  by, e.g.\ MOPAC.

\index{GRAPH!use in DENSITY} To generate the large unformatted data-file, MOPAC
should be run using the key-word \comp{GRAPH}. At present, MOPAC can only
produce graphics files in the RHF mode, the UHF capability having not yet being
written.

Although DENSITY has a very simple data-input, users are warned that care is
needed in precisely wording a request. As an example, in learning how to use
DENSITY a user might want to plot the highest-filled $\pi$ orbital in benzene,
and choose the plane to be that of the carbon atoms. At first sight this
appears reasonable, but when one recalls that the $\pi$ system has a node in
this plane, another choice of plane is seen to be essential. A better choice of
plane would be one parallel to the plane of the carbon  atoms, but 0.5 to 1.0
\AA ngstroms above it.

Similarly, if only a detail of the molecule is to be studied, it is wasteful to
plot the whole molecule. The picture is essentially made up of 2,500 pixels, so
fine detail can very easily be lost if the whole molecule is used.

With one important exception the whole program is written using the FORTRAN-77
standard, so translation to allow DENSITY to run on different machines should
not be difficult. FORTRAN-77 does not support graphical functions, and an
interface, designed to allow users to easily write their own interfaces, has
been written.  This interface is, of course, machine-dependent.

\section{Data}
Rather than fully define the input, a worked example will be given
(Figure~\ref{d_c2h4}) and other data-files can then be generated by analogy.

\subsection{Example of Data: Ethylene}
\index{Ethylene! $\pi$-density in}
For this example we will use the $\pi$ system in ethylene. Two pictures are to
be drawn based on the results from an earlier MOPAC calculation.  The first
plot is in the plane parallel  to the plane of the molecule, the second one is
in the plane perpendicular to the C-C axis.  DENSITY data-files should have the
suffix \comp{.gra}.
\begin{figure}
\begin{makeimage}
\end{makeimage}
\begin{verbatim}
Line 1 :  DEBUG
Line 2 :  Ethylene pi system
Line 3a:  CENTER=(0.7,0.0,0.5) LINE=(0.0,0.0,1.0) EDGE=2.0 HOMO
Line 3b:  CENTER=(0.7,0.0,0.5) LINE=2 EDGE=2.0 HOMO
Line 4 :
\end{verbatim}
\caption{\label{d_c2h4} DENSITY data-set for Ethylene}
\end{figure}

\begin{description}
\item[Line 1:] First set of key-words.  These  control the mode of operation.
\item[Line 2:] Title of plot. Up to 79 characters can be used.
\item[Line 3a:] Second set of key-words. A full list of key-words, and
their definitions, is given in the next Section.
\item[Line 3b:] Key-words for the second picture.
\item[Line 4:] End the input with a blank line.
\end{description}

\subsection{Keywords}
Two sets of key-words are provided. At the start of a run the user must provide
information about the source of the molecular data. At present, this data can
come from one of two sources. These are (a) off the data-file itself, which is
the \comp{MANUAL} mode, and (b) from a disk or restart-type file, which was
created by an earlier run using MOPAC.

\subsection{Definitions of First set of Key-Words}
\begin{description}
\item[\comp{DEBUG}] Print part of working of DENSITY.
\item[\comp{DMAT}] Lower half triangle of density matrix to be read in (Used
with \comp{MANUAL} only)
\item[\comp{MANUAL}] Stand-alone  mode. All data supplied from datafile.
\item[\comp{M.O.}] A molecular orbital to be used as source of density matrix.
(Used with \comp{MANUAL} only)
\end{description}

\subsubsection*{\comp{DEBUG}}\index{DEBUG!use in DENSITY}
The density matrix or molecular orbital used by the density calculation will be
printed if \comp{DEBUG} is specified.

\subsubsection*{\comp{DMAT}}
To be used only if \comp{MANUAL} is also specified. \comp{DMAT} specifies that
the lower-half of the density matrix, in free-format, is read in. There would
be (NORBS$\times$(NORBS+1))/2 of these numbers.

\subsubsection*{\comp{MANUAL}}\index{MANUAL}
This word was used in the writing and de-bugging of DENSITY,  but now is only
intended for testing and demonstration purposes.

When \comp{MANUAL} is specified, either \comp{DMAT} or \comp{M.O.} must be
specified on the same line as \comp{MANUAL}.

If \comp{MANUAL} is specified, the following data must be supplied on the next
few lines:
\begin{enumerate}
\item Number of atoms, orbitals, and electrons (NATOMS, NORBS, NELECS).
One line, free format, integer.
\item Cartesian coordinates for each atom, one atom per line, free format,
real, in order x, y, z. There will be NATOMS of these.
\item Labels for all atoms. For example, all carbon atoms might be called
``1'', all hydrogen atoms ``2'', etc. Free format, integer. There will be NATOMS
of these numbers. The numbers must be 1 to NUNI, NUNI being the number
of unique atom-types in the molecule.

\begin{tabular}{llc|llllll|l} \hline
   Compound   &   Atom Labels       &NUNI &  \multicolumn{6}{c}{Line would read} & \\ \hline
  Methane     & C: 1,   H: 2        & 2 & 1 & 2 & 2 & 2 & 2 &       &   CH4  \\
  Formic Acid & H: 1,   C: 2,  O: 3 & 3 & 1 & 2 & 3 & 3 & 1 &        &  HCOOH  \\
  Thiomethanol& C: 1,   H: 2,  S: 3 & 3 & 1 & 2 & 2 & 2 & 3 & 2     &   CH3SH  \\ \hline
\end{tabular}

\item Atomic Numbers for all unique atoms. Free format, integer. There are
NUNI of these numbers. If atom of type 1 is a carbon atom, then the
corresponding atomic number would be 6. Using the examples above, we have:

\begin{tabular}{ll|lll} \hline
&                 Atomic Numbers & \multicolumn{3}{c}{Line would read}  \\
     Compound     &  Unique atom: &  1 &  2 &  \ 3 \\\hline
     Methane      &          &       6  & 1 & \\
     Formic Acid  &           &      1  & 6 & \  8 \\
     Thiomethanol &           &      6  & 1 & 16 \\ \hline
\end{tabular}

\item Principal Quantum numbers. Free format, integer. There are
NUNI of these numbers.

\begin{tabular}{ll|lll}
\hline
  & Principal Quantum Numbers  & \multicolumn{3}{c}{Line would read}  \\
     Compound &  Unique atom: & 1 & 2 & 3
\\ \hline
     Methane  &               & 2 & 1 &    \\
     Formic Acid  &           & 1 & 2 & 2    \\
     Thiomethanol &           & 1 & 2 & 3    \\
\end{tabular}

\item Number of orbitals for all unique atoms. Free format, integer, there are
NUNI of these numbers.

\begin{tabular}{ll|lll}
\hline
&            Number of Orbitals  & \multicolumn{3}{c}{Line would read} \\
     Compound &  Unique atom: & 1 & 2 & 3  \\
               \hline
     Methane  &                4 & 1  \\
     Formic Acid  &            1 & 4 & 4  \\
     Thiomethanol &            1 & 4 & 9  \\
\hline
\end{tabular}

\item Orbital exponents for all unique atoms, format is 3F10, three numbers
per atom (one each for $s$, $p$, and $d$ orbital exponents); if $p$ or $d$ is
absent, these can be left blank.

\begin{tabular}{lc|lll} \hline
 Compound & Unique atom &  \multicolumn{3}{c}{Line would read} \\ \hline
     Methane       &      1      & 1.78  &    1.78  \\
                   &      2      & 1.3&  \\
     Thiomethanol  &      1      & 1.78  &    1.78  \\
                   &      2      & 1.&  \\
                   &      3      & 2.4   &    2.1   &    1.0  \\ \hline
\end{tabular}

\item If M.O.\  is specified, the eigenvector coefficients are read in
at this point. Free format, there
are NORBS of these. Otherwise, if DMAT specified, the lower-half
of the density matrix, in free-format, is read in. There would be
(NORBS$\times$(NORBS+1))/2 of these numbers.
\end{enumerate}

\begin{figure}
\begin{makeimage}
\end{makeimage}
\compresstable
\begin{verbatim}
Line  1:      MANUAL       M.O.                   (Key-words
Line  2:      FORMIC ACID                         (Title
Line  3:      5  14 18                            (NATOMS, NORBS, NELECS
Line  4:   0.0000    0.0000    0.0000             (Cartesian coordinates
Line  5:   1.2270    0.0000    0.0000
Line  6:   1.9164    1.1676    0.0000
Line  7:   1.3973    1.9625    0.0000
Line  8:   1.8882   -0.8836    0.0000
Line  9:    1 2 1 3 3                             (Labels
Line 10:    8 6 1                                 (Atomic Numbers
Line 11:    2 2 1                                 (Princ. Quant. Nos.
Line 12:    4 4 1                                 (Orbitals per atom
Line 13:   2.699905  2.699905                     (Exponents
Line 14:   1.787537  1.787537
Line 15:   1.331967                    (below: eigenvector coefficients
Line 16:   -0.1616  0.4769  -0.0514   0.0000  -0.0628  -0.3488  -0.0032
Line 17:    0.0000  0.2634   0.6282  -0.0893   0.0000  -0.2925  -0.2457
Line 18:    CENTER=2 LINE=(0,0,1) EDGE=4          (Rest of data
\end{verbatim}
\caption{\label{d_hcooh} Full Example of Manual Data for Formic Acid}
\end{figure}

\subsubsection*{\comp{M.O.}}
This keyword is to be used only when \comp{MANUAL} is also specified. A
molecular orbital to be used as source of density matrix.  The M.O.\ comes
after the other data required by \comp{MANUAL} as a set of free-format
coefficients. After all these data are read in, the program continues as usual,
but many limitations apply. For example, if \comp{M.O.} was used, then the
key-words  \comp{PSI=$n$}, \comp{HOMO} and \comp{LUMO} would all give the same
result. These limitations are due to the absence of other data. The second set
of key-words defines the type of plot to be drawn; much of this data is
obligatory in that there are no defaults for certain data. The user must
supply:
\begin{itemize}
\item A definition of the center of the plot.
\item A definition for the axis of the vector perpendicular to the plot.
\item A length, in \AA ngstroms, of the edge of the plot.
\end{itemize}
Other data, which are mutually exclusive, are:
\begin{itemize}
\item A molecular orbital number, given by \comp{PSI=$n$}, or
\item A highest-occupied molecular orbital, defined by the key-word
 \comp{HOMO}, or
\item A lowest-unoccupied molecular orbital, defined by the
key-word \comp{LUMO}, or
\item The explicit molecular-orbital occupancy, see key-word \comp{OCCUPANCY}, or
\item The normal electron density of the molecule. This is specified by
the absence of the other key-words; i.e., this is the default.
\end{itemize}
If a full electron density map is specified. (That is, if the last option
above is taken), then another key-word, \comp{BONDS}, can be used. \comp{BONDS}
will remove the electron density due to the atom from the plot. The effect of
this is to  generate a plot showing where the charge build-up in the bonds
occurs. Note: Ionic separations are not shown by \comp{BONDS}.

\subsection{Definitions of Second set of Key-Words}
\begin{description}
\item[\comp{ADD}] The current plot is to be added to the next plot.
\item[\comp{AXIS=$n.nn$}] Angle of plane of plotted square to viewer's eye.
\item[\comp{BONDS}] Subtract the electron density due to the atoms.
\item[\comp{CENTER}] Used to define the center of the plot.
\item[\comp{EDGE=$n.nn$}] Definition of the length of one side of the plot.
\item[\comp{FINE}] Produce four times the default number of contours.
\item[\comp{GRID}] Overlay x-y grid onto plot. Used with AXIS.
\item[\comp{HOMO}] Plot the highest occupied M.O.
\item[\comp{LINE}] Used to define the axis perpendicular to the plot.
\item[\comp{LUMO}] Plot the lowest unoccupied M.O.
\item[\comp{MULT=$n.nn$}] Multiply vertical relief by specified amount.
\item[\comp{OCCUPANCY}] Used to allow the individual M.O.\ populations to be specified.
\item[\comp{PSI=$n$}] Plot a specific M.O.
\item[\comp{PHASE}] Multiply the current plot by a constant.
\end{description}

\subsubsection*{\comp{ADD}\index{ADD}}
When two or more pictures are to be added together to form a single picture,
\comp{ADD} must be used. For example, a user might want to add or subtract
two M.O.s to see the effect. Thus if M.O.\ 2 and M.O.\ 3 were to be
added together, the data for such a calculation could be:
\begin{verbatim}
Line 1:
Line 2:   FORMALDEHYDE
Line 3: CENTER=2 LINE=(0,0,1) EDGE=2 PSI=2 ADD
Line 4: CENTER=2 LINE=(0,0,1) EDGE=2 PSI=3
Line 5:
\end{verbatim}
See also \comp{PHASE}.

\subsubsection*{\comp{AXIS=$n.nn$}\index{AXIS}}
A square plot is drawn by default. If the user wants to show the
three-dimensional nature of the contour map a facility exists to tilt the plot
so that a foreshortened and rotated plot is drawn. Of course, the degree of
tilt depends very much on the system; there is no facility in DENSITY to
eliminate ``hidden lines'', so the tilt should not be so great that hidden
lines would show. The range of $n.nn$ in  \comp{AXIS=$n.nn$} is 1.0 to 0.0. 1.0
(the default) would give a square plot, as if the user was viewing the plot
from directly overhead looking straight down; 0.0 gives a view of the plot as
if the user was looking at it from the horizon, looking horizontally. Clearly,
\comp{AXIS=1.0} would not show the relief. If \comp{GRID} were used only a
perfectly featureless square grid would be seen. Conversely, \comp{AXIS=0.0}
would show the contours as perfectly flat, straight lines. Therefore, a better
choice would be \comp{AXIS=0.6}.

\subsubsection*{\comp{BONDS}\index{BONDS!use in DENSITY}}
Not to be used in conjunction with \comp{HOMO}, \comp{LUMO},
\comp{PSI=$n$}, or \comp{OCCUPANCY}.
\comp{BONDS} calculates the average atomic orbital occupancy of each atom,  and
subtracts that number from the density matrix. The result is a plot whose
average value is zero, and which shows where the electrons have come from and
gone to when the bonds are formed.

\subsubsection*{\comp{CENTER}\index{CENTER}}
This key-word is essential. It defines the center of the plot (see
Section~\ref{area}). Two formats are provided to define the center: (a) an atom
number can be used, and (b) an absolute Cartesian coordinate  can be specified.

\begin{description}
\item[Definition by atom number]~\\
Format: \comp{CENTER=$n$}  The location of atom $n$ is defined as the center
of  the plot. Thus if atom $n$ has Cartesian coordinates (x=0.5, y=1.4, z=-0.8)
then the center of the plot is (x=0.5, y=1.4, z=-0.8). Dummy atoms are not
counted, so if any dummy atoms were used in the definition of the geometry,
they must be ignored when considering the atom number. In other words, only a
real atom can be used to define a point in the molecule.

\item[Definition by absolute Cartesian coordinate]~\\
Format: \comp{CENTER=($n.nn$,$n.nn$,$n.nn$)} The location of the  center of the
plot is defined as ($n.nn$,$n.nn$,$n.nn$). Of course, before such a center can
be defined, the user must know the Cartesian coordinates of the atoms in the
molecule.
\end{description}

Regardless of which option is used, the center of the plot will be converted
internally into absolute Cartesian coordinates.

\subsubsection*{\comp{FINE}}
Normally, between 10 and 25 contours are plotted. In order to increase this
number, \comp{FINE} can be used, in which case 40 to 100 contours will be
generated.

\subsubsection*{\comp{EDGE=$n.nn$}\index{EDGE}}
The length of one side of the graph-plot is defined as being $n.nn$  \AA ngstroms.

\subsubsection*{\comp{GRID}\index{GRID!use in DENSITY}}
\comp{GRID} can be used to enhance the legibility of a plot. It draws a regular
mesh of lines across the plot, with the same relief as the contours.
\comp{GRID} should only be used with an \comp{AXIS} which is not 1.0.

\subsubsection*{\comp{HOMO}\index{HOMO!use in DENSITY}}
For closed-shell systems with non-degenerate highest occupied molecular
orbitals, the key-word \comp{HOMO} can be used to produce an intensity map of
the highest occupied molecular orbital. For other systems, the key-word
\comp{PSI=$n$} should be used.

\subsubsection*{\comp{LINE}\index{LINE}}
This key-word is essential. It defines the vector perpendicular to the plane
of the plot, see Section~\ref{area}. Two formats are provided to define the axis
perpendicular to the plane of the plot; these formats use radically different
concepts, so users are cautioned to verify that they understand both
definitions and the distinction between them.
(a) an atom number can be used, and (b) an absolute Cartesian coordinate
can be specified.

\begin{description}
\item[Definition by atom number]~\\
Format: \comp{LINE=$n$}  The axis of the plot is defined  by the vector drawn
from  atom $n$ to the defined center of the plot. Thus if atom $n$ has
Cartesian coordinates (x=0.5, y=1.4, z=0.2) and the center of the plot is at
point (x=0.5, y=1.4, z=-0.8) then the axis of the plot is (0.0, 0.0, 1.0).
Dummy atoms are not counted, so if any dummy atoms were used in the definition
of the geometry, they must be ignored when considering the atom number. In
other words, only a real atom can be used to define the axis of the graph.

\item[Definition by absolute Cartesian coordinate]~\\
The vector need not be  normalized, but must not be of zero length.

Format: \comp{LINE=($n.nn$,$n.nn$,$n.nn$)} The axis of a  line perpendicular to
the plane of the plot is ($n.nn$,$n.nn$,$n.nn$). This axis need not be
normalized, but must be finite; that is, the only axis not allowed is (0,0,0).
\end{description}

Irrespective of which option is used, the axis of the plot will be converted
internally into a unit vector in Cartesian coordinates.

\subsubsection*{\comp{LUMO}\index{LUMO!use in DENSITY}}
For closed-shell systems with non-degenerate lowest unoccupied molecular
orbitals, the key-word \comp{LUMO} can be used to produce an intensity map of
the lowest unoccupied molecular orbital. For other systems, the key-word
\comp{PSI=$n$} should be used.

\subsubsection*{\comp{MULT=$n.nn$}\index{MULT}}
There is a default scale for the relief of a plot, when viewed as a 3-D
structure. If this default is not suitable, say the plot is too flat, then
\comp{MULT=$n.nn$} can be used to change the vertical scale.  \comp{MULT=1.0}
will do nothing, \comp{MULT=2.0} will increase the vertical relief.

\subsubsection*{\comp{OCCUPANCY}\index{OCCUPANCY}}
When the user wants to explicitly define an electronic configuration for a
system, \comp{OCCUPANCY} is used. This key-word requires the explicit occupancy
of the M.O.s to be defined on the next line, in I1 format. For example, to
define methane with one electron in each of the three triply-degenerate levels,
the lines
\begin{verbatim}
Line 1:CENTER=1 LINE=(0.0,0.0,1.0) OCCUPANCY EDGE=2.0
Line 2:2111
\end{verbatim}
could be used. Similarly, if an excited ethoxy radical were to be specified,
the following definition could be used:
\begin{verbatim}
Line 1:CENTER=(0.7,0.0,0.0) LINE=(0.0,0.0,1.0) OCCUPANCY EDGE=2.0
Line 2:22222201
\end{verbatim}

\subsubsection*{\comp{PHASE}\index{PHASE}}
Two formats for this are possible. If \comp{PHASE} is specified, the data being
added to the plot is multiplied by -1, i.e.\ negated.  If \comp{PHASE=$n.nnnn$}
is used, the data are multiplied by $n.nnnn$. For example, to form the
normalized M.O.\ of formaldehyde resulting from equal and opposite amounts of
the second and third M.O.s, i.e.\ 0.7071(M.O.2 $-$ M.O.3), the following  data
could be used.
\begin{verbatim}
Line 1:
Line 2:   FORMALDEHYDE
Line 3: CENTER=2 LINE=(0,0,1) EDGE=1 PSI=2 PHASE=0.7071 ADD
Line 4: CENTER=2 LINE=(0,0,1) EDGE=1 PSI=3 PHASE=-0.7071
Line 5:
\end{verbatim}
Note that the first phase is positive. It is not the plot that is reversed,
only the data going in to the plot, so that the data arising from line 4 are to
be multiplied by -0.7071 before being added to the plot.

\subsubsection*{\comp{PSI=$n$}}
A specified molecular orbital is to be plotted. Note that degenerate M.O.s
cannot be unambiguously represented, as they are ill-defined by a random
unitary transform. To plot degenerate M.O.s the user should be prepared to use
\comp{PHASE} and \comp{ADD}.

\subsection{Calculation of Excited State Density}
Excited states can be represented by a linear combination of Slater
determinants.  As far as electron density is concerned, each determinant, or
{\em microstate}, can be represented by a set of molecular orbital occupancies,
without regard for spin.  By use of \comp{OCCUPANCY}, any spin-free microstate
can be defined.  These facts can be used in the calculation of state densities.

State densities can be calculated by adding together the densities arising from
various microstates, weighted by their contribution to the overall state.
The weight is given simply by the square of the coefficient of the microstate
in the state.

As an example, consider the state density arising from the fourth state in
formaldehyde.  Keywords used in MOPAC would be:\\ \comp{LARGE MECI PRECISE
GRADIENTS C.I.=2  ROOT=4 GRAPH} \\ and the microstates used in the MECI
calculation are shown in Figure~\ref{fourth}. In this system, the HOMO is
molecular orbital 6, and the LUMO is molecular orbital 7.

\begin{figure}
\begin{makeimage}
\end{makeimage}
\begin{center}
\input{pic_ci2}
\end{center}
\caption{\label{fourth}Configurations used with C.I.=2}
\end{figure}

The linear combinations of microstates in the state functions are given in the
output, as shown in Figure~\ref{ci_output}.

\begin{figure}
\begin{makeimage}
\end{makeimage}
\begin{verbatim}
   Root No.    1       2       3       4

              1 A1    1 A2    2 A2    2 A1

               0.0     2.5     2.9     7.5

         1  0.9997  0.0000  0.0000  0.0256
         2  0.0000  0.7071 -0.7071  0.0000
         3  0.0000  0.7071  0.7071  0.0000
         4 -0.0256  0.0000  0.0000  0.9997
\end{verbatim}
\caption{\label{ci_output}State functions in Formaldehyde arising from C.I.=2}
\end{figure}

The electron density contour map for the fourth state can be generated by use
of \comp{OCCUPANCY}, \comp{ADD}, and \comp{MULT}, thus:
\compresstable
\begin{verbatim}
   Formaldehyde, Electron Density for the fourth state
CENTER=(0.7,0.0,0.1) LINE=(0.0,0.0,1.0) EDGE=3.0 OCCUPANCY PHASE=0.000655 add
2222220
CENTER=(0.7,0.0,0.1) LINE=(0.0,0.0,1.0) EDGE=3.0 OCCUPANCY PHASE=0.999400
2222202
\end{verbatim}
\normalsize
The corresponding data set for DENSITY for the third state would be:
\compresstable
\begin{verbatim}
   Formaldehyde, Electron Density for the third state
CENTER=(0.7,0.0,0.1) LINE=(0.0,0.0,1.0) EDGE=3.0 OCCUPANCY PHASE=0.500000 add
2222211
CENTER=(0.7,0.0,0.1) LINE=(0.0,0.0,1.0) EDGE=3.0 OCCUPANCY PHASE=0.500000
2222211
\end{verbatim}
\normalsize
However, because the electron density arising from microstates 2 and 3 is the
same, this data set could be written in a more compact form, thus:
\compresstable
\begin{verbatim}
   Formaldehyde, Electron Density for the third State
CENTER=(0.7,0.0,0.1) LINE=(0.0,0.0,1.0) EDGE=3.0 OCCUPANCY
2222211
\end{verbatim}
\normalsize
Finally, note that the electron density distribution for the second and third
states are the same.  With \comp{C.I.=2}, the first excited state, a triplet,
and the second excited state, the first excited singlet, have the same electron
density everywhere.

\subsection{Definition of the area of the graph plot}\label{area}
The graph plot is a square, which represents a slice or cut through the volume
of a molecule. To define a square, seven numbers are needed. In order, these
are:
\begin{itemize}
\item Three numbers to define the position of the center of the square.
\item Three numbers to define an axis perpendicular to the surface of the square.
\item One number to define the length of the edge of the square.
\end{itemize}
To specify the center of the square, the key-word \comp{CENTER} is  provided.
\comp{CENTER} can be either an atom number, e.g.\ \comp{CENTER=4}, or an
absolute Cartesian  coordinate, e.g.\ \comp{CENTER=(0.6,0.5,2.4)}. If an atom
is used, the absolute Cartesian coordinates of that atom are used to define the
center of the square. In either case, the center of the square, i.e.\ the
intersection of the two diagonals of the square, is defined by the resulting
absolute Cartesian coordinate.

Examples:
\begin{itemize}
\item Methane, center of plot to be on one of the hydrogen atoms, these
being atoms 1, 3, 4, and 5. Use \comp{CENTER=1} or \comp{CENTER=3} etc.; as an
alternative, assuming the first atom is at the origin,
\comp{CENTER=(0.0,0.0,0.0)} could be used.
\item Benzene, given Cartesian coordinates as follows:
\begin{verbatim}
             X         Y         Z
  C1       0.0000    0.0000    0.0000
  C2       1.4066    0.0000    0.0000
  C3       2.1099    1.2182    0.0000
  C4       1.4066    2.4363    0.0000
  C5       0.0000    2.4363    0.0000
  C6      -0.7033    1.2182    0.0000
  H1      -0.5451   -0.9442    0.0000
  H2      -0.5451    3.3805    0.0000
  H3       1.9517   -0.9442    0.0000
  H4      -1.7935    1.2182    0.0000
  H5       3.2002    1.2182    0.0000
  H6       1.9517    3.3805    0.0000
\end{verbatim}
Then, if a plot of benzene with the center of the molecule at the middle
of the picture, \comp{CENTER=(0.7,1.2,0.0)} could be used.
\item Benzene, $\pi$-system. Using the above Cartesian coordinates for the
benzene ring, the center of the plot must be above the plane of the
ring in order to avoid the nodes in the $\pi$-system. In this case
\comp{CENTER=(0.7,1.2,0.5)} would be appropriate.
\end{itemize}
 Once the center of the plot is defined, the orientation of the plane
of the plot needs to be specified. Thus if a plot of methane was wanted,
and the center of the plot was on the carbon atom, the following
cross-sections could be drawn:
\begin{itemize}
\item Four-fold symmetry: Plot is oriented in the reflection plane of the
S$_4$ symmetry operation. To specify this, absolute Cartesian
coordinates would need to be used.
\item Three-fold symmetry: Axis of plot is from carbon to any hydrogen.
To specify this, \comp{LINE=4} could be used.
\item Showing two C-H bonds: Given that the first three atoms are H, C, and
H, then the axis (0.0,0.0,1.0) would be perpendicular to the plane
of  these three atoms (assuming that all three atoms had the same z component).
\end{itemize}
 It might be helpful in visualizing the axis of the plot by imagining the plot
without the line specified. The center of the plot is already defined, but
the square is still free to rotate in all three dimensions, so only one
point in the square is defined. The plane of the plot is then
defined by \comp{LINE}.

The final unknown is the size of the plot. This is
specified by \comp{EDGE=$n.nn$}.
The length $n.nn$ defines the length, in \AA ngstroms, of the side of the plot.
Note that most molecules are bigger than their simple atomic coordinates
would suggest. As an example, to get a benzene ring to fit inside a plot,
\comp{EDGE=6.0} would be needed, even though the H-H distance across the ring is
only 4.8-5.0 \AA ngstroms.
\section{Details of Graph Plots}
\subsection{Contours}\index{Contours}
 There are normally between 10 and 25 contours. The contours are separated
by steps of size 1, 2.5, and 5 times 10 to some integer power. The most
common step sizes are:
\begin{verbatim}
 0.0010, 0.0025, 0.0050, 0.0100, 0.0250, 0.0500,
 0.1000, 0.2500, 0.5000, 1.0000, 2.5000, 5.0000
\end{verbatim}
in units of electrons per cubic \AA ngstrom, for electron density, and
the square root of these units for wave-functions.

 The flexible nature of the step size means that the user can expect to see
something in the picture, but close attention should be paid to the contour
interval. If the step size is excessively small, less than 0.00001,
the user will be warned, but the calculation will be continued.

\subsection{Density Around Atoms}
 All Slater atomic orbitals have a node at the nucleus, with the
important exception
of hydrogen. One result of this is that hydrogen is the only element whose
electron density has a maximum at the nucleus. All other atoms have an almost
zero electron density at their nucleus. This is usually disconcerting
at first sight,
but is a consequence of the behavior of Slater-type orbitals.
 For planar systems, it is a good idea to plot the density in the plane
a fraction of an \AA ngstrom above the plane of the molecule.
\subsection{Difference Maps}\index{Difference maps}
 A difference map shows where electron density builds up when bonds are
formed. It will NOT show ionic character. To form a \comp{BONDS} map
the electron density arising from the atoms is spherically averaged and
then subtracted from the density matrix. For example, suppose the atomic
orbital populations on an atom arising from the un-renormalized eigenvectors
are  1.0, 1.1, 1.2, and 1.3 for $s$, $p_x$, $p_y$, and $p_z$,
respectively. Then the
spherically averaged populations are 1.0, 1.2, 1.2, and 1.2 for these atomic
orbitals.
\subsection{Renormalization of Molecular Orbitals}
  All maps are calculated from data originally derived from the supplied
molecular orbitals. These M.O.s are presumed to be un-renormalized: that
is, the sum of the squares of the coefficients of the M.O.s add to unity.
The first step, therefore, is to re-normalize the M.O.s. This is done
by matrix multiplying the starting eigenvector matrix by the
inverse-square-root of the overlap matrix. This requires the presence of
the inverse-square-root of the overlap matrix, which must be supplied by
the MOPAC file. If re-normalization is not done, the total
electron density would be too large, and the difference maps would be
quite incorrect.

\section{Programming Considerations}
 DENSITY is not intended to be a ``stand-alone'' program. Its main purpose
is to be run using data generated by an earlier MOPAC calculation.
Results from DENSITY need some further processing before a hard-copy
graph-plot is obtained.
 In order, then, the unformatted data required from
a MOPAC type calculation to be used as auxiliary
data for DENSITY are as follows:

Record:

\begin{enumerate}
\item Number of Atoms, Number of Orbitals, Number of Electrons,
X-Cartesian coordinates for all atoms, Y-Cartesian coordinates for all atoms,
Z-Cartesian coordinates for all atoms.
\item Stopping and starting orbital counters for all atoms.
\item $s$-orbital exponents for all atoms, $p$-orbital exponents for all atoms,
$d$-orbital exponents for all atoms. Atomic numbers for all atoms.
\item All the un-renormalized eigenvectors, atomic orbital indices running
fastest.
\item Lower half triangle of the inverse-square-root of the overlap matrix.
\end{enumerate}
 DENSITY produces a default file suitable for a plotting program to use.
This file has the following format:

 Line 1: This line consists of the single, unchanging, message
\begin{verbatim}
                    NUMBER OF CONTOURS =  nn,
\end{verbatim}
with  $nn$  the actual number of different contours supplied. The programmer
can use this message to detect the start of a contouring file, and, if
desired, make use of the number nn to decide what action to take.

 Lines 2-4: Text. The programmer should print these lines without assuming
that the text makes any sense.

 Lines 5 on: The layout of these lines is as follows:
\begin{verbatim}
     <x-coordinate> <y-coordinate> <Pen code>  <Contour Height>
\end{verbatim}
As the whole plot is within the range 0.0 to 1.0, the x- and y-coordinates
are fractions of unity. The pen code is integer, 1 for pen up, 2 for pen down.
The contour height is real, and self-explanatory.

 Near to the end of the file is a single contour of height 99.999. This
 ``contour''
draws a box around the plot.

 Finally, the last few lines are the chemical symbols. These use the
same layout as Lines 5 on, but in place of the pen code, the chemical symbols
are present.
If this output is not
suitable, the programmer should modify subroutine PLOTGR.

\section{Description of Program}
\subsection{Fortran Files}
 DENSITY consists of several FORTRAN-77 files. These are:
\begin{description}
\item[CNTOUR] A general 2 or 3-dimensional contour-drawing subroutine.
\item[DRAW] A subroutine to draw one contour.
\item[EULER] Rotates a point in 3-D space.
\item[DATIN] Reads in data defining one particular picture.
\item[MAIN] Main segment; generates array for contouring.
\item[MAXMIN] Calculates highest and lowest points in the picture.
\item[PLOTGR] Interface between FORTRAN-77 and graphics routine.
\item[READIN] Gets in data defining molecule
\item[PLOTGR] Generates data for graph plotter.
\end{description}

\subsection{Description of FORTRAN Files}
\paragraph*{CNTOUR}\index{CNTOUR}
CNTOUR is a general contour-drawing routine. It calls subroutines
DRAW, EULER, and MAXMIN. The contour map can be tilted to show the
three-dimensional structure of the density map.

\paragraph*{DRAW}
 Draws a single contour, given a starting address. Called by CNTOUR
to allow users to rapidly write their own interfaces.

\paragraph*{EULER}\index{EULER}
 Performs a three-dimensional rotation on a three-dimensional
point provided; the resulting point is then used as a data
point for plotting.

\paragraph*{DATIN}
 All the user-supplied data defining a picture are read in in DATIN.
Some checking is done to ensure that the key-words provided are
compatible.

\paragraph*{MAIN}
 The main program, generates the wave-function in terms of atomic
orbitals, this is then used to calculate the pixel array, which in
turn is used by the contouring subroutine.

\paragraph*{MAXMIN}
 Prints the values and positions of the maxima and minima on the plot.
No data are altered by a call to MAXMIN.

\paragraph*{PLOTGR}\index{PLOTGR}
 The interface between FORTRAN-77 and the graphics routines is provided
by PLOTGR. Only very simple graphics commands are used, in order to
permit easy conversion of the program to run on other machines.
Programmers will need to change PLOTGR to suit local equipment.

\section{Installing Density}
DENSITY is distributed with MOPAC, and is normally written
to the sub-directories \comp{\ldots/density\_source/} and
\comp{\ldots/density\_examples}.

The parameter file SIZES should be read and, if necessary, modified before
\comp{Makefile} is run. The two parameters within SIZES that the user can
modify are MAXLIT and MAXHEV. MAXLIT is assigned a value equal to the largest
number of hydrogen atoms that a DENSITY job is expected to run, MAXHEV is
assigned the corresponding number of heavy (non-hydrogen) atoms.

Once you are satisfied with the contents of SIZES, compile DENSITY by issuing
the command `make'. Once this is complete, there is no  reason to keep the
object  files, and if space is at a premium these can be deleted at this time.
They should be kept if modifications are to be made to the program, in order to
allow rapid re-linking with the modified subroutines.

\section{Running DENSITY}
The command \comp{density} followed by a filename will start an on-line DENSITY
job.   E.g.\ \comp{density ethylene}, where \comp{ethylene.gra} is the data-set
for DENSITY, and a calculation of ethylene had been run earlier using MOPAC.

The main files that are required by DENSITY are:
\begin{center}
\begin{tabular}{ccl}
           File    &      Channel  &   Description \\ \hline
         \comp{$<$filename$>$.gpt}  &  13 &   MOPAC generated file. \\
         \comp{$<$filename$>$.gra}  &   5 &   User-generated data file \\
\end{tabular}
\end{center}
The main files that are produced are:
\begin{center}
\begin{tabular}{ccl}
           File     &    Channel &   Description  \\ \hline
        \comp{$<$filename$>$.out} &    6 &  Results  \\
        \comp{$<$filename$>$.tec} &   15 &  Formatted file of graph-plot \\
                                            for use by a graphics program. \\
\end{tabular}
\end{center}


The Wave Action Equation in Cartesian  (\ref{eq:bal_plane}) or spherical  (\ref{eq:bal_sphere}) coordinates is the basic
equations of the wave model. However, modified versions of these equations are
used in the model, where (a) they are solved on a variable wavenumber grid
(see below), where (b) modified versions of these equations are used to
properly describe dispersion for discretized equations in selected numerical
schemes (see \para\ref{sub:xy_prop}), and where (c) sub-grid obstacles such as
islands are considered (see \para\ref{sub:xy_prop}).

\vssub
\subsection{~Spectral discretization} \label{sec:basic_num}
\vsssub

If Eq. (\ref{eq:bal_plane}) or Eq. (\ref{eq:bal_sphere}) is solved directly, an
effective reduction of spectral resolution occurs in shallow water
\citep[see][]{tol:GAOS98b}. This loss of resolution can be avoided if the
equation is solved on a variable wavenumber grid, which implicitly
incorporates the kinematic wavenumber changes due to shoaling. Such a
wavenumber grid corresponds to a spatially and temporally invariant
grid in relative frequency \citep{tol:GAOS98b}. The corresponding local wavenumber grid can be
calculated directly from the invariant frequency grid and the dispersion
relation (\ref{eq:disp}), and hence becomes a function of the local depth
$d$. To accommodate economical calculations of $S_{nl}$ and allow a good separation of swell frequencies, a frequency discretization with
exponentially increasing increments is adopted, so that the varying frequency resolution is proportional to the local frequency,

%----------------------------%
% Exponential frequency grid %
%----------------------------%
% eq:sigma_grid

\begin{equation}
\sigma_{m+1} = X_\sigma \, \sigma_m \: , \label{eq:sigma_grid}
\end{equation}

\noindent
where $m$ is a discrete grid counter in $k$-space. $X_\sigma$ is defined by
the user in the input files of the program. Traditionally, in most
applications of third-generation models $X_\sigma \simeq 1.1$ is used.

The effects of a spatially varying grid will be discussed for the Cartesian
Eq. (\ref{eq:bal_plane}) only. Adaptation to the spherical grid is
trivial. Denoting the variable wavenumber grid with $\kappa$, the balance
equation becomes

%------------------------------%
% general equations kappa-grid %
%------------------------------%
% eq:bal_f_grid
% eq:sigma_dot

\begin{equation}
\frac{\p}{\p t} \frac{N}{c_g} +
\frac{\p}{\p x} \frac{\dot{x} N}{c_g} +
\frac{\p}{\p y} \frac{\dot{y} N}{c_g} +
\frac{\p}{\p \kappa} \frac{\dot{\kappa} N}{c_g} +
\frac{\p}{\p \theta} \frac{\dot{\theta} N}{c_g}  =
\frac{S}{\sigma c_g} \: , \label{eq:bal_f_grid} \end{equation} \begin{equation}
\dot{\kappa} \:\frac{\p k}{\p \kappa} =
     c_g^{-1} \frac{\p \sigma}{\p d} \left (
    \frac{\p d}{\p t} + {\bf U} \cdot \nabla_x d \: \right ) -
    {\bf k} \cdot \frac{\p {\bf U}}{\p s}
\: . \label{eq:sigma_dot}
\end{equation}

\noindent

\vssub
\subsection{~Splitting of the wave action equation} \label{sec:basic_num}
\vsssub

In \ws\, Eq. (\ref{eq:bal_f_grid}) is solved using a fractional step method.
The first step treats the temporal variations of
the depth, and corresponding changes in the wavenumber grid. As is discussed
by \cite{tol:GAOS98b}, this step can be invoked sparsely. By splitting off
effects of (temporal) water level variations, the grid becomes invariant, and
the depth becomes quasi-steady for the remaining fractional steps. Other
fractional steps consider spatial propagation, intra-spectral propagation and
source terms. Starting with version 5.10, the source term $S$ is further split into
non-ice $S_{no~ice}$ and ice $S_{ice}$ source term. For a single model grid, the following sequence of integration  is performed
by the {\code W3WAVE} routine:
\begin{itemize}
 \item[1.] Update of water level
 \item[2.] Intra-spectral part 1: integration over $\Delta t_g/2$ of  $\frac{\p}{\p t} \frac{N}{c_g} + \frac{\p}{\p \kappa} \frac{\dot{\kappa} N}{c_g} + \frac{\p}{\p \theta} \frac{\dot{\theta} N}{c_g}  =0 $
 \item[3.] Spatial propagation: integration over $\Delta t_g$ of $\frac{\p}{\p t} \frac{N}{c_g} +
\frac{\p}{\p x} \frac{\dot{x} N}{c_g} +
\frac{\p}{\p y} \frac{\dot{y} N}{c_g}  = 0$
 \item[4.] Intra-spectral part 2: integration over $\Delta t_g/2$ of  $\frac{\p}{\p t} \frac{N}{c_g} + \frac{\p}{\p \kappa} \frac{\dot{\kappa} N}{c_g} + \frac{\p}{\p \theta} \frac{\dot{\theta} N}{c_g}  =0 $
 \item[5.] Source term integration: integration over $\Delta t_g$ of $\frac{\p}{\p t} \frac{N}{c_g}   = \frac{S_{no~ice}}{\sigma c_g}$
 \item[6.] Ice source term integration: integration over $\Delta t_g$ of $\frac{\p}{\p t} \frac{N}{c_g}   = \frac{S_{ice}}{\sigma c_g}$
\end{itemize}
The succession of these 6 steps is, in the limit $\Delta t_g \rightarrow 0$, equivalent to the integration of Eq. (\ref{eq:bal_f_grid}) over a global
time step $\Delta t_g$.

This splitting in multiple steps allows an  efficient
vectorization and parallelization at the same time. The time splitting furthermore
allows for the use of separate partial or dynamically adjusted time steps in
the different fractional steps of the model. \ws\ makes a distinction between
4 different time steps. \label{dt_list}

\begin{list}{xx}{\itemsep 0mm \parsep 0mm \rightmargin 5mm}

\item[1)] The `global' time step $\Delta t_g$, is the common step of all the splitted sub-integrations. In that sense,
it is the smallest time step for which a physically meaningful solution can be obtained, because all terms in the equation have been
integrated. As a result, this is a possible time step for evaluating model output or coupling with other models,
and, in the case of a multi-grid system,  it is the time step at which communication
between grids is performed. In the case of a forced -- not coupled -- model, input winds and currents are
interpolated at this global step. This time step is provided by the user in the input file of {\code ww3\_grid}, but can be reduced
within the model to reach a requested input or output time.

\item[2)] The second time step is the time step for spatial propagation. This is not used for triangular-based
grids, for which the advection step is -- in the case of explicit schemes -- adjusted internally for each spectral component. For other grid types, the
user supplies a reference maximum propagation time step for the lowest model
frequency $\Delta t_{p,r}$, assuming no currents, and no grid motion. For the
frequency with counter $m$, the maximum time step $\Delta t_{p,m}$ is
calculated within the model as

%-------------------------%
% Time stepping equations %
%-------------------------%
% eq:dtpl

\begin{equation}
\Delta t_{p,m} = \frac{{\dot{x}}_{p,r}}{{\dot{x}}_{p,m}} \Delta t_{p,r}
\: , \label{eq:dtpl} \end{equation}

\noindent
where $\dot{x}_{p,r}$ is the maximum advection speed for the longest waves
without currents or grid motion, and $\dot{x}_{p,m}$ is the actual maximum
advection speed (including current) for frequency $m$. If the propagation time
step is smaller than the global time step, the propagation effects are
calculated with a number of successive smaller time steps. This generally
implies that several partial time steps are used for the lowest frequency, but
that the highest frequencies are propagated over the interval $\Delta t_g$
with a single calculation. The latter results in a significantly more
efficient model, particularly if higher-order accurate propagation schemes are
used. Note that $\Delta t_{p,m}$ may be defined bigger than $\Delta t_g$, and
that this has potential impact in model economy for cases with (strong)
currents.

\item[3)] The third time step is the time step for intra-spectral
propagation. For large-scale and deep-water grids this time step can generally
be taken equal to the global time step $\Delta t_g$. For shallow water grids,
smaller intra-spectral propagation time steps allow for larger effects of
refraction within the stability constraints of the scheme. Note that the order
of invoking spatial and intra-spectral propagation is alternated to enhance
numerical accuracy. If strong refraction of long period swells occur, this may
result in a notable undulation of mean wave parameters. This can be avoided by
setting this time step to an even integer fraction of $\Delta t_g$.

\item[4)] The final time step is the time step for the integration of the
source terms, which is dynamically adjusted for each separate grid point and
global time step $\Delta t_g$ (see \para~\ref{sub:source}). This results in
more accurate calculations for rapidly changing wind and wave conditions, and
a more economical integration for slowly varying conditions. In order to limit the
calculation time, a minimum time step is defined by the user.

\end{list}

\vspace{\baselineskip} \noindent

The following sections deal with the separate steps in the fractional step
method, and various subjects associated with this.  The main issue are covered
in \para\ref{sub:num_depth}, which addresses treatment of temporal variations
of the water depth, \para\ref{sub:xy_prop} which addresses spatial
propagation, \para\ref{sub:spec} which addresses intra-spectral propagation,
and Sections \ref{sub:source} and \ref{sub:icesource} which address the numerical
integration of non-icea and ice source
terms.  The other sections deal with additional
numerical approaches and techniques, covering the treatment of winds and
currents (\para\ref{sub:num_w_c}), including tides (\para\ref{sub:num_tide}), calculating space-time extremes (\para\ref{sub:space_time_ext}), treatment
of ice (\para\ref{sub:num_ice}), spectral partitioning and the corresponding
tracking of wave systems in space and time (Sections \ref{sub:num_part},
\ref{sub:num_track}), and nesting (\para\ref{sub:num_nest}).


\subsection{Deep learning models}
\label{proposed_approach}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
In this work, we developed two end-to-end deep learning models utilising full wavefield frames of Lamb wave propagation for delamination identification in CFRP materials as presented in Fig.~\ref{fig:proposed_models}.
The developed models have a scheme of many-to-one sequence prediction, which takes \(n\) number of frames representing the full wavefield propagation through time and their interaction with the delamination to extract the damage features, and finally predict the delamination location, shape, and size in a single output image.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure} [!h]
	\centering
	\begin{subfigure}[b]{0.49\textwidth}
		\centering
		\includegraphics[width=.2\textheight]{Fully_ConvLSTM2d_MODEL_updated.png}
		\caption{Model-\RNum{1}} % : Convolutional LSTM model.
		\label{fig:convlstm_model}
	\end{subfigure}
	\hfill
	\begin{subfigure}[b]{0.49\textwidth}
		\centering
		\includegraphics[width=.2\textheight]{RNN_LSTM_MODEL_updated.png}
		\caption{Model-\RNum{2}} % : Time distributed AE model.
		\label{fig:AE_convlstm}
	\end{subfigure}
	\caption{The architecture of the proposed deep learning models.}
	\label{fig:proposed_models}
\end{figure}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The first proposed model presented in Fig.~\ref{fig:convlstm_model}
consists of three ConvLSTM layers that can process time series and computer vision tasks.
The first ConvLSTM layer has \(12\) filters, second layer has \(6\) filters and third layer has \(12\) filters.
The kernel size of the ConvLSTM layers was set to (\(3\times3\)) with a stride of \(1\), padding was set to "same" which makes the output the same as the input in the case of stride \(1\).
Furthermore, a \(\tanh\) (the hyperbolic tangent) activation function was used within the ConvLSTM layers that output values in a range between (\(-1\) and \(1\)).
Moreover, we applied a Batch Normalization technique~\cite{Santurkar2018} after the first two ConvLSTM layers.

In the second model presented in Fig.~\ref{fig:AE_convlstm} we applied an autoencoder technique (AE) which is well-known for extracting spatial features.
The idea of AE is to compress the input data within the encoding process then learn how to reconstruct it back from the reduced encoded representation (latent space) to a representation that is as close to the original input as possible.
In this model, we have investigated the use of AE to process a sequence of input frames to perform image segmentation.
Therefore, a Time Distributed layer presented in Fig.~\ref{fig:TD} was introduced to the model, in which it distributes the input frames into the AE layers in order to process them independently.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}[!h]
	\centering
	\includegraphics[width=0.5\textwidth]{Time_ditributed_layer.png}
	\caption{Flow of input frames using Time distributed layer.}
	\label{fig:TD}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

In general, an AE consists of three parts: the encoder, the bottleneck, and the decoder.
The encoder is responsible for learning how to reduce the input dimensions and compress the input data into an encoded representation.
In Fig.~\ref{fig:AE_convlstm}, the encoder part consists of four levels of downsampling.
The purpose of having different scale levels is to extract feature maps from the input image at different scales.
Every level at the encoder consists of two 2D convolution operations followed by a Batch Normalization then a Dropout is applied.
Furthermore, at the end of each level a Maxpooling operation is applied to reduce the dimensionality of the inputs.
The bottleneck presented in Fig.~\ref{fig:AE_convlstm} has the lowest level of dimensions of the input data, further it consists of two 2D convolution operations followed by a Batch Normalization.
The decoder part presented in Fig.~\ref{fig:AE_convlstm}, is responsible for learning how to restore the original dimensions of the input.
The decoder part consists of two 2D convolutional operations followed by Batch Normalization and Dropout, and an upsampling operation is applied at the end of each decoder level to retrieve the dimensions of its inputs.
Skip connections linking the encoder with the corresponding decoder levels were added to enhance the features extraction process.
The outputs of the decoder were forwarded into the ConvLSTM2D layer to learn long-term spatiotemporal features.

In both models, we applied a 2D convolutional layer as the final output layer followed by a sigmoid activation function which outputs values in a range of \(0\) and \(1\) to indicate the delamination probability.
Consequently, a threshold value must be chosen to classify the output into a damaged (\(1\)) or undamaged (\(0\)).
Hence, we set the threshold value to (\(0.5\)).
The reason for selecting such threshold value to the sigmoid activation function is explained in our previous research work~\cite{Ijjeh2021}.
%Further, Adadelta~\cite{zeiler2012adadelta} optimization method with binary cross-entropy (BCE) was applied to the first model, whereas in the second model, Adam optimizer~\cite{Kingma2014} with BCE was applied.

For evaluating the performance of the proposed models, the mean
intersection over union \(IoU\) (Jaccard index) was applied as the accuracy metric.
\(IoU\) is estimated by determining the intersection
area between the ground truth and the predicted output.
Further, we have two output classes (damaged and undamaged), the \(IoU\) was calculated for the damaged class only.
Equation~(\ref{eqn:iou}) illustrated the \(IoU\) metric:
\begin{equation}
IoU=\frac{Intersection}{Union}=\frac{\hat{Y} \cap Y}{\hat{Y} \cup Y}
\label{eqn:iou}
\end{equation}
where \(\hat{Y}\) is the predicted output, and \(Y\) is the ground truth.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\begin{table}[]
%	\centering
%	\caption{Models parameters}
%	\label{tab:parmeters}
%	\begin{tabular}{ccc}
%		\hline
%		\multirow{2}{*}{Parameter} & \multicolumn{2}{c}{Model}
%		\\
%		\cline{2-3}
%		& 1  & 2
%		\\ \hline
%		Optimizer &	Adadelta~\cite{zeiler2012adadelta} &  Adam~\cite{Kingma2014}
%		\\
%		Batch size & 2  & 1
%		\\
%		Dropout  & 0.0  & 0.2
%		\\
%		Learning rate & 1.0 & 0.01
%		\\
%		Loss function  & \multicolumn{2}{c}{Binary cross entropy}
%		\\ \hline
%	\end{tabular}
%\end{table}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\subsubsection{\stid{3.12} Sub-project: hypre}

\paragraph{Overview}
The {\sl hypre} software library \cite{hypre:homepage,hypre_design_impl_2006} provides high performance preconditioners and solvers for the solution of large sparse linear systems on massively parallel computers, with particular focus on algebraic multigrid solvers. One of {\sl hypre}’s unique features is the provision of a (semi)-structured interface, in addition to a traditional linear-algebra based interface. The semi-structured interface is appropriate for applications whose grids are mostly structured, but with some unstructured features. Examples include block-structured grids, composite grids in structured adaptive mesh refinement (AMR) applications, and overset grids. These interfaces give application users a more natural means for describing their linear systems, and provide access to methods such as structured multigrid solvers, which can take advantage of the additional information beyond just the matrix. Since current architecture trends are favoring regular compute patterns to achieve high performance, the ability to express structure has become much more important. The {\sl hypre} library provides both unstructured and structured multigrid solvers, which have shown excellent scalability on a variety of high performance computers, e.g Blue Gene systems (unstructured solver BoomerAMG has scaled up to 1.25 million MPI cores with a total of 4.5 million hardware threads). It is used by many ECP application teams, including ExaAM, Subsurface, ExaWind, CEED, and more. It requires a C compiler and an MPI implementation, but it also runs in an OpenMP environment. It also has GPU capabilities.

\paragraph{Key  Challenges}

While {\sl hypre}'s solvers contain much parallelism, their main focus is the solution of sparse linear systems, leading to  very large demands on memory bandwidth. In addition, the use of multiple levels, while greatly aiding convergence of the solvers, leads to decreasing systems sizes, number of operations and parallel efficiencies on coarser levels. Particularly the unstructured algebraic multigrid solver BoomerAMG\cite{HeYa2002}, which is {\sl hypre}'s most often used preconditioner, suffers from increasing communication complexities on coarser levels. Coarse grid operators are generated by multiplying three matrices leading to increasing numbers of nonzeroes per row in the resulting matrices and with it increasing numbers of neighbor processes. While BoomerAMG's solve phase mainly consists of matrix vector products and smoothing operations, which are fairly straight forward to parallelize, even on a GPU, its setup phase is highly complex, including many branches, a lot of integer operations as well as some sequential passages. Previous interpolation strategies that lead to best convergence and performance on distributed memory machines were not suitable for implementation on GPUs or similar architectures requiring extreme parallelism and required new algorithmic approaches. Since {\sl hypre} is a mature product with many solvers and interdependent features, any significant changes that affect the whole library, are tedious and require much testing to ensure that the library stays backward compatible and no features are broken.

\paragraph{Solution Strategy}

Since computer architectures continue to change rapidly, it was important to come up with strategies that will facilitate future porting of the software. Therefore we developed and implemented a new memory model that addresses the use of different memory locations.
Since the upcoming computer architectures are heterogeneous with accelerators, we focus on enabling {\sl hypre} for GPUs. We have looked into various options, such as the use of CUDA, OpenMP 4.5, as well as RAJA and Kokkos. We limited the latter three options to the structured interface and solvers which are more natural candidates for such an approach due to their use of macros, called BoxLoops, for loops. We adopted a modular approach for the unstructured interface, which relies on the restructuring the solver components to use smaller kernels that are and/or will be implemented in CUDA for Nvidia GPUs. Since hip is similar to CUDA, porting to AMD GPUs has been fairly straight forward. We are now investigating the use of a vendor conversion tool from CUDA to SYCL to port structured and unstructured solvers to upcoming exascale computers with Intel GPUs.

\paragraph{Recent Progress}

Previously we had enabled the structured interface and solvers, SMG and PFMG\cite{AsFa1996}, to completely run on GPUs, using CUDA, OpenMP4.5, RAJA and Kokkos, and have now also added hip to enable use on AMD GPUs.
For our unstructured AMG solver BoomerAMG, we had implemented suitable CUDA kernels for setup and solve phase, designed a new class of interpolation operators based on sparse matrix operations\cite{LiSY2020}, implemented it on GPUs and ported aggressive coarsening to the GPU. Recently, we added Umpire support for memory pooling on GPUs, which can significantly improve performance. We have enabled hypre's specialized solvers, including linear and eigensolvers for Maxwell problems and solvers for H-div problems, to run on Nvidia GPUs. Figure \ref{fig:AMS-PCG} shows some results for a Maxwell problem using finite elements of increasing order on 1 node of Lassen. We have ported many of the CUDA kernels and routines in the unstructured interface to hip to enable their use on AMD GPUs. We have also developed a new version of multipass interpolation based on matrix-matrix multiplications and implemented it in CUDA and hip. Multipass interpolation is a popular low-memory prolongation used with aggressive coarsening. Figure \ref{fig:Spock-AMG} shows a comparison of CPU and GPU runtimes on 2 nodes of Spock for a 3D diffusion problem with a 27-point stencil on a $n \times n \times n$ grid using AMG-PCG with aggressive coarsening on the first level for increasing $n$.

\begin{figure}[bth]
\centering
	\includegraphics[width=3.9in]{projects/2.3.3-MathLibs/2.3.3.12-SUNDIALS-hypre/AMS-PCG.png}
	%\includegraphics[width=3in]{AMS-PCG.png}
	\caption{\label{fig:AMS-PCG} Solution of a simple 3D electromagnetic diffusion problem corresponding to the 2nd order definite Maxwell equation  $\nabla \times \nabla \times E + E = f$ using AMS-PCG on 1 node of Lassen (4 GPUs vs. 40 CPU cores) using finite elements of increasing order on a Fichera mesh.}

\end{figure}

\begin{figure}[bth]
\centering
	\includegraphics[width=3in]{projects/2.3.3-MathLibs/2.3.3.12-SUNDIALS-hypre/spock-AMG-PCG.png}
	%\includegraphics[width=3in]{spock-AMG-PCG.png}
	\caption{\label{fig:Spock-AMG} Total times (setup plus solve times) on 2 nodes of Spock using AMG-PCG with aggressive coarsening and multi-pass interpolation for a 3D diffusion problem with a 27-point stencil on a $n \times n \times n$ grid. The CPU runs were performed with 8 MPI tasks with 16 OpenMP threads per MPI task, the GPU runs were performed on 8 AMD MI100 GPUs.}

\end{figure}

\begin{figure}[bth]
\centering
	\includegraphics[width=5in]{projects/2.3.3-MathLibs/2.3.3.12-SUNDIALS-hypre/crusher-AMG-PCG.png}
	%\includegraphics[width=5in]{crusher-AMG-PCG.png}
	\caption{\label{fig:crusher-AMG} Setup, solve times and Speedups of GPU over CPU performance on 1 node of Crusher using AMG-PCG with three different settings for a 3D diffusion problem with a 27-point stencil on a $n \times n \times n$ grid. The CPU runs were performed with 64 MPI tasks, the GPU runs were performed on 8 AMD MI250 GPUs. Solid lines use the GPU default settings, whereas dashed and dotted lines use in addition one level of aggressive coarsening with two-stage and multipass interpolation, respectively.}

\end{figure}

\paragraph{Early Access System Experiences}

We have tested {\sl hypre} performance on both Spock, see Figure \ref{fig:Spock-AMG}, and Crusher.  Figure \ref{fig:crusher-AMG}
shows the Setup and Solve times for three different settings of AMG for increasing $n$ of a 3D diffusion problem on a $n \times n \times n$ grid. Both CPU and GPU runs use the same settings. Solid lines use the default AMG settings, whereas dashed and dotted lines use one level of aggressive coarsening with two-stage and multipass interpolation, respectively. While generally systems in application problems would be in the range of up to $n=300$, we here continue to increase the problem size until the GPU runs reach the memory limit to demonstrate memory usage for these different AMG settings. This is reached first for the default version, which requires a lot of memory, but also achieves the lowest number of iterations, followed by the use of aggressive coarsening with two-stage interpolation. The use of one level of aggressive coarsening combined with multipass interpolation allows solving the largest system illustrated using GPUs, since it has lower memory requirements at the cost of having the worst convergence.

{\sl Hypre} release v2.24.0 contains support for Intel GPUs for the structured interface and solvers via SYCL and Kokkos and for the solve phase of unstructured solvers via SYCL. All these features have been tested on Arcticus.

\paragraph{Next Steps}

We will pursue the following tasks:

\begin{itemize}
\item We will continue to add new GPU capabilities to {\sl hypre} and improve the performance of current capabilities. We will thoroughly investigate the performance on AMD GPUs and begin porting to Intel GPUs.
\item We will test and evaluate performance of important hypre solvers on AMD and Intel GPUs, improve their performance and port additional components if necessary.
\end{itemize}
In addition, we will work with ECP application teams who are using {\sl hypre}, such as ExaWind, ExaAM, AMReX,  to achieve best performance by tuning the solvers for them and potentially implementing suitable algorithmic changes.


\section{Reptation Monte Carlo}
\label{sec:rmc}
Like diffusion monte carlo, reptation monte carlo (RMC) is a projector based method, allowing us the ability to sample the fixed-node wavefunciton.  However, by exploiting the path-integral formulation of Schr\"{o}dinger's equation, the RMC algorithm can offer some advantages over traditional DMC, such as sampling both the mixed and pure fixed-node distributions in polynomial time, as well as not having population fluctuations and biases.  The current implementation does not work with T-moves.

There are two adjustable parameters that affect the quality of the RMC projection:  imaginary projection time $\beta$ of the sampling path (commonly called a ``reptile"), and the Trotter time step $\tau$.  $\beta$ must be chosen to be large enough such that $e^{-\beta \hat{H}}|\Psi_T\rangle \approx |\Phi_0\rangle$ for mixed observables, and $e^{-\frac{\beta}{2} \hat{H}}|\Psi_T\rangle \approx |\Phi_0\rangle$ for pure observables.  The reptile is discretized into $M=\beta/\tau$ beads at the cost of an $\mathcal{O}(\tau)$ time-step error for observables arising from the Trotter-Suzuki breakup of the short-time propagator.

The following table lists some of the more practical
\begin{table}[h]
\begin{center}
\begin{tabularx}{\textwidth}{l l l l l l }
\hline
\multicolumn{6}{l}{\texttt{vmc} method} \\
\hline
\multicolumn{2}{l}{parameters}  & \multicolumn{4}{l}{}\\
   &   \bfseries name     & \bfseries datatype & \bfseries values & \bfseries default   & \bfseries description \\
   &   \texttt{beta            } &  real  & $> 0$ & dep.   & reptile projection time $\beta$  \\
   &   \texttt{timestep            } &  real     & $> 0$ & 0.1 & Trotter time step $\tau$ for each electron move \\
   &   \texttt{beads           } &  int     & $> 0$ & 1 & Number of reptile beads $M=\beta/\tau$ \\
   &   \texttt{blocks              } &  integer  & $\ge 0$ & 1   & number of blocks            \\
   &   \texttt{steps               } &  integer  & $\ge 0$ & 1   & number of steps per block   \\
   &   \texttt{vmcpresteps        } &  integer  & $\ge 0$ & 0   & propagates reptile using VMC for given number of steps\\
   &   \texttt{warmupsteps         } &  integer  & $\ge 0$ & 0   & number of steps for warming up\\
   &   \texttt{MaxAge              }   & integer & $\ge 0 $   & 0   & force accept for stuck reptile if age exceeds MaxAge. \\
  \hline
\end{tabularx}
\end{center}
\end{table}

Additional information:

Because of the sampling differences between DMC ensembles of walkers and RMC reptiles, the RMC block should contain the following estimator declaration to ensure correct sampling:  \texttt{ <estimator name="RMC" hdf5="no">}.

\begin{itemize}
\item \texttt{beta} or \texttt{beads}?  One can specify one or the other, and from the Trotter time-step, the code will construct an appropriately sized reptile.  If both are given, \texttt{beta} overrides \texttt{beads}.

\item \textbf{Mixed vs. Pure observables?}  Configurations sampled by the endpoints of the reptile are distributed according to the mixed distribution $f(\mathbf{R})=\Psi_T(\mathbf{R})\Phi_0(\mathbf{R})$.  Any observable that is computable within DMC and is dumped to the scalar.dat file will likewise be found in the scalar.dat file generated by RMC, except there will be an appended \texttt{\_m} to alert the user that the observable was computed on the mixed distribution.  For pure observables, care must be taken in the interpretation.  If the observable is diagonal in the position basis (in layman's terms, if it is entirely computable from a single electron configuration $\mathbf{R}$, like the potential energy), and if the observable does not have an explicit dependence on the trial wavefunction (for example, the local energy has an explicit dependence on the trial wavefunction from the kinetic energy term), then pure estimates will be correctly computed.  These observables will be found in either the scalar.dat file, where they will be appended with a \texttt{\_p} suffix, or in the stat.h5 file.  No mixed estimators will be dumped to the h5 file.

\item \textbf{Sampling}.  For pure estimators, one should check the traces of both pure and mixed estimates.  Ergodicity is a known problem in RMC.  Because we use the bounce algorithm, it is possible for the reptile to bounce back and forth without changing the electron coordinates of the central beads.  This might not easily show up with mixed estimators, since these are accumulated at constantly regrown ends, but pure estimates are accumulated on these central beads, and so can exhibit strong autocorrelations in pure estimate traces.

\item \textbf{Propagator}:  Our implementation of RMC uses Moroni's DMC link action (symmetrized), with Umrigar's scaled drift near nodes.  In this regard, the propagator is identical to the one QMCPACK uses in DMC.

\item \textbf{Sampling}:  We use Ceperley's bounce algorithm.  MaxAge is used in case the reptile gets stuck, at which point the code forces move acceptance, stops accumulating statistics, and requilibrates the reptile.  Very rarely will this be required.  For move proposals, we use particle-by-particle VMC a total of $N_e$ times to generate a new all-electron configuration, at which point the action is computed and the move is either accepted or rejected.
\end{itemize}


%% -*- coding:utf-8 -*-
\chapter{Natural transformation}

Natural transformation is the most important part of the category
theory. It provides a possibility to compare \mynameref{def:functor}s
via a standard tool.

\section{Definitions}

The natural transformation is not an easy concept compare other ones
and requires some additional preparations before we can give the
formal definition.

\begin{figure}
  \centering
  \begin{tikzpicture}[ele/.style={fill=black,circle,minimum
        width=.8pt,inner sep=1pt},every fit/.style={ellipse,draw,inner
        sep=-2pt}]

    % the texts

    \node at (0,3) {$C$};
    \node at (4,3) {$D$};

    \node[ele,label=above:$a$] (a) at (0,2) {};
    \node[ele,label=above:$a_F$] (af) at (4,2) {};
    \node[ele,label=below:$a_G$] (ag) at (4,0) {};

    \node[draw,fit= (a),minimum width=2cm, minimum
      height=3.5cm] {} ;
    \node[draw,fit= (af) (ag),minimum width=2cm, minimum
      height=3.5cm] {} ;

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$F$} (af);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$G$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[right]{$\alpha_a$} (ag);
  \end{tikzpicture}
  \caption{Natural transformation: object mapping}
  \label{fig:nt_objects_mapping}
\end{figure}

Consider 2 categories $\cat{C}, \cat{D}$ and 2
\mynameref{def:functor}s $F: \cat{C} \tof \cat{D}$ and $G:
\cat{C} \tof \cat{D}$. If we have an \mynameref{def:object} $a \in \catob{C}$ then
it will be translated by different functors into different objects of
category $\cat{D}$: $a_F = F(a), a_G = G(a) \in \catob{D}$ (see
\cref{fig:nt_objects_mapping}). There are 2 options possible
\begin{enumerate}
\item There is not  any \mynameref{def:morphism} that connects $a_F$
  and $a_G$.
\item $\exists \alpha_a \in \hom\left(a_F, a_G\right) \subset
  \cathom{D}$.
\end{enumerate}
We can of course to create an artificial morphism that connects the
objects but if we use \textit{natural} morphisms
\footnote{the word natural means that already existent morphisms from
  category $\cat{D}$ are used}
then we can get a
special characteristic of the considered functors and categories. For
instance if we have such morphisms then we can say that the
considered functors are related each other. Opposite example if there
are no such morphisms then the functors can be considered as unrelated
each other.
%% Another example if the
%% morphisms are \mynameref{def:isomorphism}s then the functors can be
%% considered as very close each other.

\begin{figure}
  \centering
  \begin{tikzpicture}[ele/.style={fill=black,circle,minimum
        width=.8pt,inner sep=1pt},every fit/.style={ellipse,draw,inner
        sep=-2pt}]

    % the texts

    \node at (0,3) {$C$};
    \node at (4,3) {$D$};

    \node[ele,label=above:$a$] (a) at (0,2) {};
    \node[ele,label=below:$b$] (b) at (0,0) {};
    \node[ele,label=above:$a_F$] (af) at (4,2) {};
    \node[ele,label=below:$a_G$] (ag) at (4,0) {};
    \node[ele,label=above:$b_F$] (bf) at (5.5,2) {};
    \node[ele,label=below:$b_G$] (bg) at (5.5,0) {};

    \node[draw,fit= (a) (b),minimum width=2cm, minimum
      height=3.5cm] {} ;
    \node[draw,fit= (af) (ag) (bf) (bg),minimum width=3cm, minimum
      height=4cm] {} ;

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[left]{$f$} (b);

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[below]{$f_F$} (bf);

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (ag) to
    node[above]{$f_G$} (bg);

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$F$} (af);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (b) to
    [out=45,in=135,looseness=1] node[above]{$F$} (bf);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$G$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (b) to
    [out=-45,in=-135,looseness=1] node[above]{$G$} (bg);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[left]{$\alpha_a$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (bf) to
    node[right]{$\alpha_b$} (bg);
  \end{tikzpicture}
  \caption{Natural transformation: morphisms mapping}
  \label{fig:nt_morphisms_mapping}
\end{figure}

The functor is not just the object mapping but also the morphisms
mapping. If we have 2 objects $a$ and $b$ in the category $\cat{C}$
then we potentially can have a morphism $f \in \hom_{\cat{C}}(a, b)$. In this
case the morphism is mapped by the functors $F$ and $G$ into 2
morphisms $f_f$ and $f_G$ in the category $\cat{D}$.
As result we have 4 morphisms: $\alpha_a, \alpha_b, f_F, f_G \in
\cathom{D}$. It is natural to impose additional conditions on the
morphisms especially that they form a
\mynameref{def:commutative_diagram} (see \cref{fig:nt_def}):
\[
f_f \circ \alpha_b = \alpha_a \circ f_G.
\]

\begin{definition}[Natural transformation]
\label{def:nt}

\begin{figure}
  \centering
  \begin{tikzpicture}[ele/.style={fill=black,circle,minimum
        width=.8pt,inner sep=1pt},every fit/.style={ellipse,draw,inner
        sep=-2pt}]

    % the texts
    \node[ele,label=above:$a_F$] (af) at (0,2) {};
    \node[ele,label=below:$a_G$] (ag) at (0,0) {};
    \node[ele,label=above:$b_F$] (bf) at (1.5,2) {};
    \node[ele,label=below:$b_G$] (bg) at (1.5,0) {};

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[below]{$f_F$} (bf);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (ag) to
    node[above]{$f_G$} (bg);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[left]{$\alpha_a$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (bf) to
    node[right]{$\alpha_b$} (bg);
  \end{tikzpicture}
  \caption{Natural transformation: commutative diagram}
  \label{fig:nt_def}
\end{figure}

Let $F$ and $G$ are 2 \mynameref{def:functor}s from category $\cat{C}$
to the category $\cat{D}$. The \textit{natural transformation} is a
set of \mynameref{def:morphism}s $\alpha \subset \cathom{D}$ which
satisfy the following conditions:
\begin{itemize}
\item For every \mynameref{def:object} $a \in \catob{C}$ $\exists
\alpha_a \in \hom\left(a_F, a_G\right)$
\footnote{
$a_F = F(a), a_G = G(a)$
}
- \mynameref{def:morphism}
in category $\cat{D}$. The morphism $\alpha_a$ is called the component of
the natural transformation.
\item For every morphism $f \in \cathom{C}$ that connects 2 objects
  $a$ and $b$, i.e. $f \in \hom_{\cat{C}}(a,b)$ the corresponding components of
  the natural transformation $\alpha_a, \alpha_b \in \alpha$ should
  satisfy the following conditions
  \begin{equation}
    f_G \circ \alpha_a = \alpha_b \circ f_F,
    \label{eq:nt_definition}
  \end{equation}
  where $f_F = F(f), f_G = G(f)$.
  In other words the morphisms form a
  \mynameref{def:commutative_diagram} shown on the \cref{fig:nt_def}.
\end{itemize}

We use the following notation (arrow with a dot) for the natural transformation between
functors $F$ and $G$: $\alpha: F \tont G$.
\end{definition}

\section{Operations with natural transformations}

\begin{example}[\textbf{Fun} category]
\label{ex:fun_category}
\index{Object!\textbf{Fun} example}
\index{Morphism!\textbf{Fun} example}
\index{Category!\textbf{Fun} example}

The functors can be considered as objects in a special category
\textbf{Fun}. The morphisms in the category are \mynameref{def:nt}s.

To define a category we need to define composition operation that
satisfied \mynameref{axm:composition}, identity
morphism and verify \mynameref{axm:associativity}.

\begin{figure}
  \centering
  \begin{tikzpicture}[ele/.style={fill=black,circle,minimum
        width=.8pt,inner sep=1pt},every fit/.style={ellipse,draw,inner
        sep=-2pt}]

    % the texts

    \node at (0,3) {$C$};
    \node at (4,5) {$D$};

    \node[ele,label=above:$a$] (a) at (0,2) {};
    \node[ele,label=above:$a_F$] (af) at (4,4) {};
    \node[ele,label=right:$a_G$] (ag) at (4,2) {};
    \node[ele,label=below:$a_H$] (ah) at (4,0) {};

    \node[draw,fit= (a),minimum width=2cm, minimum
      height=3.5cm] {} ;
    \node[draw,fit= (af) (ag) (ah),minimum width=5cm, minimum
      height=5cm] {} ;

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$F$} (af);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$G$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$H$} (ah);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[right]{$\alpha_a$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (ag) to
    node[right]{$\beta_a$} (ah);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
     [out=-45,in=45,looseness=1] node[right]{$\beta_a \circ \alpha_a$} (ah);
  \end{tikzpicture}
  \caption{Natural transformation vertical composition: object mapping}
  \label{fig:nt_objects_mapping_composition}
\end{figure}

For the composition consider 2 \mynameref{def:nt}s $\alpha, \beta$ and
consider how they act on an object $a \in \catob{C}$ (see
\cref{fig:nt_objects_mapping_composition}). We always can construct
the composition $\beta_a \circ \alpha_a$ i.e. we can define the
composition of natural transformations $\alpha, \beta$ as
\(
\beta \circ \alpha = \left\{
\beta_a \circ \alpha_a | a \in \catob{C}
\right\}
\).

\begin{figure}
  \centering
  \begin{tikzpicture}[ele/.style={fill=black,circle,minimum
        width=.8pt,inner sep=1pt},every fit/.style={ellipse,draw,inner
        sep=-2pt}]

    % the texts

    \node[ele,label=above:$a_F$] (af) at (0,4) {};
    \node[ele,label=left:$a_G$] (ag) at (0,2) {};
    \node[ele,label=below:$a_H$] (ah) at (0,0) {};
    \node[ele,label=above:$b_F$] (bf) at (3,4) {};
    \node[ele,label=right:$b_G$] (bg) at (3,2) {};
    \node[ele,label=below:$b_H$] (bh) at (3,0) {};

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[above]{$f_F$} (bf);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (ag) to
    node[above]{$f_G$} (bg);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (ah) to
    node[above]{$f_H$} (bh);

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[right]{$\alpha_a$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (ag) to
    node[right]{$\beta_a$} (ah);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
     [out=-135,in=135,looseness=1] node[left]{$\beta_a \circ
       \alpha_a$} (ah);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (bf) to
    node[right]{$\alpha_b$} (bg);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (bg) to
    node[right]{$\beta_b$} (bh);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (bf) to
     [out=-45,in=45,looseness=1] node[right]{$\beta_b \circ \alpha_b$}
     (bh);
  \end{tikzpicture}
  \caption{Natural transformation vertical composition: morphism mapping -
    commutative diagram}
  \label{fig:nt_morphism_mapping_composition}
\end{figure}

The natural transformation is not just object mapping but also
morphism mapping. We will require that all morphisms shown on \cref{fig:nt_morphism_mapping_composition} commute. The composition
defined in such way is called
\mynameref{def:vertical_composition}.

The functor category between categories $\cat{C}$ and $\cat{D}$ is
denoted as $[\cat{C}, \cat{D}]$.

\end{example}

\begin{definition}[Vertical composition]
\label{def:vertical_composition}
\index{Natural transformation!Vertical composition}
Let $F,G,H$ are functors between categories $\cat{C}$ and $\cat{D}$.
Also we have $\alpha : F \tont G, \beta: G \tont
H$ - natural transformations. We can compose the $\alpha$ and $\beta$
as follows
\[
\alpha \circ \beta: F \tont H.
\]
This composition
is called \textit{vertical composition}.
\end{definition}

\begin{definition}[Horizontal composition]
\label{def:horizontal_composition}
\index{Natural transformation!Horizontal composition}
If we have 2 pairs of functors. The first one $F,G: \cat{C} \to
\cat{D}$ and another one $J,K: \cat{D} \tof \cat{E}$. We also have a
natural transformation between each pair: $\alpha : F \tont
G$ for the first one and $\beta : J \tont
K$ for the second one. We can create a new transformation
\[
\alpha \star \beta: F \circ J \tont G \circ K
\]
that is called \textit{horizontal composition}. Note that we use a
special symbol $\star$ for the composition.
\end{definition}

\begin{remark}[Bifunctor in category of functors]
 \label{rem:bifunctor_fun_cat}
If we have the same pair of functors as in
\cref{def:horizontal_composition} then we can consider the functors as
objects of 3 categories: $\cat{\mathcal{A}} = \left[\cat{C},
  \cat{D}\right], \cat{\mathcal{B}} = \left[\cat{D},
  \cat{E}\right]$ and $\cat{\mathcal{C}} = \left[\cat{C},
  \cat{E}\right]$

  Next we want to construct a \mynameref{def:bifunctor}
  $\otimes: \cat{\mathcal{A}} \times \cat{\mathcal{B}} \tof \cat{\mathcal{C}}$
  where for each pair of objects $F \in \catob{\mathcal{A}}, J \in
  \catob{\mathcal{B}}$ we got another object from $\cat{\mathcal{C}}$.
  The used operation is an ordinary functor's composition.
  I.e.
  \[
  \otimes: F \times G \to F \circ G \in \catob{\mathcal{C}}.
  \]

  The bifunctor is not just a map for objects. There is also a map
  between morphisms. Thus if we have 2 \mynameref{def:morphism}s:
  $\alpha : F \to G$ and $\beta : J \to K$ then we can construct the
  following mapping
  \[
  \otimes: \alpha \times \beta \to \alpha \star \beta \in \cathom{\mathcal{C}}.
  \]

  As result we have the introduced mapping $\otimes$ as a bifunctor.
\end{remark}

\begin{definition}[Left whiskering]
\label{def:lw}
If we have 3 categories $\cat{B}, \cat{C}, \cat{D}$,
\mynameref{def:functor}s $F,G: \cat{C} \tof \cat{D}$, $H: \cat{B} \to
\cat{C}$ and \mynameref{def:nt}
$\alpha: F \tont G$ then we can construct a new natural
transformations:
\[
\alpha H : F \circ H \tont G \circ H
\]
that is called \textit{left whiskering} of functor and natural
transformation \cite{nlab:whiskering}.
\end{definition}

\begin{definition}[Right whiskering]
\label{def:rw}
If we have 3 categories $\cat{C}, \cat{D}, \cat{E}$,
\mynameref{def:functor}s $F,G: \cat{C} \tof \cat{D}$, $H: \cat{D} \to
\cat{E}$ and \mynameref{def:nt}
$\alpha: F \tont G$ then we can construct a new natural
transformations:
\[
H \alpha : H \circ F \tont H \circ G
\]
that is called \textit{right whiskering} of functor and natural
transformation \cite{nlab:whiskering}.
\end{definition}

\begin{definition}[Identity natural transformation]
\label{def:idnt}
If $F: \cat{C} \tof \cat{D}$ is a \mynameref{def:functor} then we can
define \textit{identity natural transformation}
$\idnt{F}$ that maps any \mynameref{def:object}
$a \in \catob{C}$ into \mynameref{def:id} $\idm{F(a)} \in \cathom{D}$.
\end{definition}

\begin{remark}[Whiskering]
\label{rem:whiskering}
With \mynameref{def:idnt} we can redefine \mynameref{def:lw} and
\mynameref{def:rw} via \mynameref{def:horizontal_composition} as follows.

For left whiskering:
\begin{equation}
\label{eq:lw}
\alpha H = \alpha \star \idnt{H}
\end{equation}

For right whiskering:
\begin{equation}
\label{eq:rw}
H \alpha = \idnt{H} \star \alpha
\end{equation}
\end{remark}

\section{Polymorphism and natural transformation}

Polymorphism plays a certain role in programming languages. Category
theory provides several facts about polymorphic functions which are
very important.

\begin{definition}[Parametrically polymorphic function]
\index{Parametric polymorphism}
\label{def:pp_function}
Polymorphism is parametric if all function instances behave uniformly
i.e. have the same realization. The functions which satisfy the
parametric polymorphism requirements are parametrically polymorphic.
\end{definition}

\begin{definition}[Ad-hoc polymorphism]
\label{def:ad_hoc_polymorphism}
Polymorphism is parametric if the function instances can behave
differently dependently on the type they are being instantiated with.
\end{definition}

\begin{theorem}[Reynolds]
\label{thm:reynolds}
\mynameref{def:pp_function}s are \mynameref{def:nt}s
\begin{proof}
TBD
\end{proof}
\end{theorem}

\subsection{\textbf{Hask} category}

In Haskell most of functions are \mynameref{def:pp_function}s
\footnote{really in the run-time the functions are not
  \mynameref{def:pp_function}s}.

\begin{example}[Parametrically polymorphic function][\textbf{Hask}]
\label{ex:nt_hask}
Consider the following function
\begin{minted}{haskell}
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:xs) = Just x
\end{minted}
The function is parametricaly polymorphic and by
\mynameref{thm:reynolds} is \mynameref{def:nt} (see \cref{fig:nt_pp_hask}).

\begin{figure}
  \centering
  \begin{tikzpicture}[ele/.style={fill=black,circle,minimum
        width=.8pt,inner sep=1pt},every fit/.style={ellipse,draw,inner
        sep=-2pt}]

    % the texts

    \node[ele,label=above:$a$] (a) at (0,2) {};
    \node[ele,label=below:$b$] (b) at (0,0) {};
    \node[ele,label=above:$\mbox{[a]}$] (af) at (5,2) {};
    \node[ele,label=below:$\mbox{Maybe a}$] (ag) at (5,0) {};
    \node[ele,label=above:$\mbox{[b]}$] (bf) at (7.5,2) {};
    \node[ele,label=below:$\mbox{Maybe b}$] (bg) at (7.5,0) {};

    \node[draw,fit= (a) (b),minimum width=2cm, minimum
      height=3.5cm] {} ;
    \node[draw,fit= (af) (ag) (bf) (bg),minimum width=6.5cm, minimum
      height=5.5cm] {} ;

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[left]{$f$} (b);

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[below]{$\mbox{fmap}_{[]}$} (bf);

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (ag) to
    node[above]{$\mbox{fmap}_{Maybe}$} (bg);

    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$$} (af);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (b) to
    [out=45,in=135,looseness=1] node[above]{$$} (bf);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (a) to
    node[above]{$$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (b) to
    [out=-45,in=-135,looseness=1] node[above]{$$} (bg);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (af) to
    node[left]{$\mbox{safeHead}_a$} (ag);
    \draw[->,thick,shorten <=2pt,shorten >=2pt] (bf) to
    node[right]{$\mbox{safeHead}_b$} (bg);
  \end{tikzpicture}
  \caption{Haskell parametric polymorphism as a natural transformation}
  \label{fig:nt_pp_hask}
\end{figure}

Therefore from the definition of the natural transformation
\eqref{eq:nt_definition} we have
\mintinline{haskell}{fmap f . safeHead = safeHead . fmap f}. I.e. it
does not matter if we initially apply \mintinline{haskell}{fmap f} and
then \mintinline{haskell}{safeHead} to the result or initially
\mintinline{haskell}{safeHead} and then \mintinline{haskell}{fmap f}.

The statement can be verified directly. For empty list we have
\begin{minted}{haskell}
fmap f . safeHead []
-- equivalent to
fmap f Nothing
-- equivalent to
Nothing
\end{minted}
from other side
\begin{minted}{haskell}
safeHead . fmap f []
-- equivalent to
safeHead []
-- equivalent to
Nothing
\end{minted}

For a non empty list we have
\begin{minted}{haskell}
fmap f . safeHead (x:xs)
-- equivalent to
fmap f (Just x)
-- equivalent to
Just (f x)
\end{minted}
from other side
\begin{minted}{haskell}
safeHead . fmap f (x:xs)
-- equivalent to
safeHead (f x: fmap f xs )
-- equivalent to
Just ( f x )
\end{minted}

Using the fact that \mintinline{haskell}{fmap f} is an expensive
operation if it is applied to the list we can conclude that the second
approach is more productive. Such transformation allows compiler to
optimize the code.
\footnote{It is not directly applied to Haskell because it has lazy
  evaluation that can perform optimization before that one}
\end{example}