\SetPicSubDir{ch-Exp}

\chapter{Experimenting with Other Random Models}
\label{ch:exp}
\vspace{2em}

A method similar to the 3-phase method in DHAM has been adopted and used to show existential/constructive results in some other models of random digraphs. Now that we are familiar with the DHAM algorithms, we shall attempt to inpnut graphs from some of these models, and see how DHAM performs on them. We shall try to look for patterns in terms of accuracy, runtime, or number of attempts in the following models.

\section{$k$-in, $k$-out Graphs}
\subsection{Graph Generation}
The way $D_{k-in, k-out}$ is defined, it is pretty straightforward to generate instances of this graph. At every vertex $u\in V_n$, we simply have to generate 2 lists of $k$ vertices each (as in-neighbours and out-neighbours), sampling uniformly at random from the set of all vertices. Now we add an edge from $u$ to each out-neighbour and an edge from each in-neighbour to $u$.
\subsection{Observations}
Cooper and Frieze \cite{cooper:kinout} have shown that $D_{2-in, 2-out}$ is Hamiltonian with High Probability, using a 3-phase analysis.

\begin{description}
\item[Phase 1] Show that $D_{2-in, 2-out}$ contains a permutation digraph, $\Pi$ of size at most $2\log n$.
\item[Phase 2] Increase the minimum cycle length in $\Pi$ to $n_0 = \Big\lceil \frac{1000n}{\log n} \Big\rceil$.
\item[Phase 3] Convert the Phase 2 permutation digraph to a Hamilton Cycle.
\end{description}
It is interesting to note that the proof follows a very similar outline to the one for Random Digraphs $D_{n, m}$, showing the existence of a Hamiltonian Cycle but, a similar bound on the runtime has not been obtained. It is still not known if there is a polynomial time algorithm to find the same.

\begin{figure}[ht]

\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth, height=7cm]{pic/ch-Exp/kin_time.png}
\caption{Runtime plot of $D_{k-in, k-out}$}
\label{fig:kin:time}
\end{subfigure}
\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth, height=7cm]{pic/ch-Exp/kin_accr.png}
\caption{Probability of finding a Hamilton cycle in $D_{k-in, k-out}$}
\label{fig:kin:accr}
\end{subfigure}

\caption{DHAM on $D_{k-in, k-out}$}
\label{fig:kin:plots}
\end{figure}

We try to test if DHAM might be successful in finding this Hamiltonian cycle in polynomial time.
From \autoref{fig:kin:time} we can see that (to the extend of n that is feasible for testing)
that runtime grows more or less the same as on $D_{n, m}$. This is suggestive of the fact that it might be possible to give a polynomial bound the runtime of 3-phase method on this class of graphs.

We also see some spikes in the runtime and also a lower probability of finding the Hamiltonian cycle in \autoref{fig:kin:accr} for $D_{2-in, 2-out}$, even though we know that this graph is Hamiltonian with high probability. This phenomenon is observed again in the next model we take a look at and seems to suggest that the algorithm does not run as well on sparse graphs.

\section{$k$-regular Graphs}
\subsection{Graph Generation}
To generate a $k$-regular digraph, we need to make sure that the in-degree and the out-degree of each vertex are k. But simply choosing $2k$ neighbours independently like for $D_{k-in, k-out}$ does not work, since we cannot guarantee that exactly $k$ other vertices will also be in-neighbours.

Instead, we notice that in a permutation digraph, each vertex has exactly $1$ in/out neighbour. We use this fact and take the union of k random permutation digraphs (which have no mutual overlap) to obtain a $k$-regular digraph.
\subsection{Observations}
Theoretically, it has been shown that $D_{n, r}$ is Hamiltonian with high probability for $r \ge 3$ \cite{cooper:kreg}. The proof for this is again based on a 3-phase method and is very similar to that for $D_{k-in, k-out}$, since large $k$-regular graphs look very similar to $D_{k-in, k-out}$ graphs. Hence it is not very surprising that their runtime plots look similar. The runtime very closely follows the same $n^{1.5}$ curve that $D_{n, m}$ had, suggesting that it might be possible to give a polynomial bound for DHAM on this class of graphs too.

Once again we notice the spikes in runtime and the lower probabilities of success for $k = 2, 3$ in \autoref{fig:kreg:accr}, reiterating the idea that DHAM performs poorly on sparse graphs. We can trace this bad performance to the first phase of the algorithm, where we construct a subgraph of average degree 10. The bipartite matching that follows depends on the degree of vertices in this subgraph, and a lower degree limits the success probability of the matching, and hence bottle-necking DHAM.

\begin{figure}[ht]

\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth, height=7cm]{pic/ch-Exp/kreg_time.png}
\caption{Runtime plot of $D_{n, r}$}
\label{fig:kreg:time}
\end{subfigure}
\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth, height=7cm]{pic/ch-Exp/kreg_accr.png}
\caption{Probability of finding a Hamilton cycle in $D_{n, r}$}
\label{fig:kreg:accr}
\end{subfigure}

\caption{DHAM on $D_{n, r}$}
\label{fig:kreg:plots}
\end{figure}
\subsection{Closer look at sparse graphs}
Since we notice the DHAM performs poorly on sparse graphs, but still works just fine at value below the mentioned degree $10$, in the original paper, we take a closer look to see above what value of $r$, does DHAM find a cycle in $D_{n, r}$, with high probability and low number of attempts.

\begin{figure}[ht]

\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth, height=7cm]{pic/ch-Exp/sprc_accr.png}
\caption{Probability of Finding a cycle in sparse $D_{n, r}$}
\label{fig:kreg:spaccr}
\end{subfigure}
\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth, height=7cm]{pic/ch-Exp/sprc_atmp.png}
\caption{Average no. of attempts to find the cycle}
\label{fig:kreg:spatmp}
\end{subfigure}

\caption{$D_{n, r}$ with low values of $r$}
\label{fig:kreg:sparse}
\end{figure}

From \autoref{fig:kreg:sparse} we see that for $r \ge 6$, the probability of finding a cycle is almost at 1, and the number of attempts also stabilises around 5.

\section{Random Tournaments}
\subsection{Graph Generation}
We can generate every possible pair of vertices, using a nested loop, and assign a direction to every edge uniformly at random to obtain the desired tournament.
\subsection{Observations}
Random Tournaments have been shown to have $\delta = min(\delta^+, \delta^-)$ edge disjoint Hamiltonian cycles\cite{kuhn:tourna}. Though the proof does not rely on the 3-phase method, DHAM using that method, still does find cycles in such graphs (\autoref{fig:tourna:time}), with high probability (probability 1 in our tests).

Tournaments grow in size as a function of $n^2$, limiting the range of $n$ feasible for testing. From the range of sizes that we tested on it is not possible to comment on the runtime on these graphs (since the implementation overhead might be affecting the runtime more than the algorithm itself). But we do notice that every graph generated returned a valid Hamiltonian cycle, which seems to suggest that the probability of success of the 3-phase method is also very high on random tournaments.
Also, since tournaments are dense graphs, we do not run into the bottlenecks that we observed in the last 2 models.

\begin{figure}[ht]

\centering
\includegraphics[width=0.9\linewidth,height=7cm]{pic/ch-Exp/tourna_time.png}
\caption{Runtime plot of Tournaments}
\label{fig:tourna:time}

\end{figure}

\section{Random $n$-lifts of complete digraph $K_h$}
\subsection{Graph Generation}
We first create the complete digraph, $K_h$ on $h$ vertices. Now, we start constructing a new digraph $D$, with $h \times n$ vertices, with the range of vertices $[i \times n, i \times (n+1) - 1]$ corresponding to each vertex $i\in V(K_h)$.

Now, for each edge $(u, v) \in E(K_h)$, we construct arrays $U$ \& $V$, of the vertices corresponding to $u, v \in V(K_h)$. After shuffling the arrays, we obtain a random matching as $\forall i<n, (U[i], V[i])$, which is now added to the graph $D$, to obtain the required $n$-lift of $K_h$.
\subsection{Observations}
This is another class of graphs that proved to be Hamiltonian \cite{frieze:lift} (for sufficiently large values of $h$) by using the 3-phase method, with appropriate modifications.
\begin{description}
\item[Phase 1] Show that with high probability the lift $D$ contains a directed permutation digraph, $\Pi$ of size at most $2\ln n$.
\item[Phase 2] Increase the minimum cycle length in $\Pi$ to $n_0 = \Big\lceil \frac{100nh^3}{\ln n} \Big\rceil$.
\item[Phase 3] Convert the Phase 2 permutation digraph to a Hamilton Cycle.
\end{description}

We make some interesting observations here.
The first is that for $k=8$ we see that all the generated graphs are Hamiltonian, which could be considered a more precise lower bound for $h$ than the \textit{sufficiently large h} . But more importantly, none of the n-lifts of $K_3$ are Hamiltonian. Frieze in his survey\cite{frieze:2019survey}, has posed the problem to show that n-lifts of $K_3$ are Hamiltonian. What we observe with DHAM, is that the probability of lifts of $K_3$ being Hamiltonian is zero. Though this particular algorithm failing, need not imply that n-lifts of $K_3$ are not Hamiltonian (indeed it could be because of the phenomenon of DHAM doing poorly on sparse graphs, with us also observing the runtime spikes, and low probability at $k=4$), it is an interesting observation nevertheless and worth taking a deeper look into.

\begin{figure}[ht]

\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth,height=7cm]{pic/ch-Exp/nlift_time.png}
\caption{Runtime plot of n-lifts}
\label{fig:nlift:time}
\end{subfigure}
\begin{subfigure}{\textwidth}
\centering
\includegraphics[width=0.9\linewidth, height=7cm]{pic/ch-Exp/nlift_accr.png}
\caption{Probability of finding a Hamilton cycle in lifts of $K_h$}
\label{fig:lift:accr}
\end{subfigure}

\caption{DHAM on n-lifts}
\label{fig:other:plots}
\end{figure}


\subsection{Three-dimensional RTE solver \index{MYSTIC} (mystic)}
\label{sec:mystic}

The Monte Carlo method is the most straightforward way to calculate
(polarized) radiative transfer. In forward tracing mode
individual photons are traced on their random paths through the atmosphere.
Starting from top of the atmosphere (for solar radiation), or being thermally
emitted by the atmosphere or surface, the photons are followed until they
hit the surface or leave again at top of the atmosphere (TOA). For
solar radiation, the start position is either a random location in the
TOA plane, with the direction determined by the solar zenith and
azimuth. Originally, the ``Monte Carlo for the physically correct tracing of
photons in cloudy atmospheres'' MYSTIC \citep{mayer2009} has been developed as
a forward tracing method for the calculation of irradiances and radiances in
\ifthreedmystic{3D} plane-parallel atmospheres. Later the model has been extended to fully
spherical geometry and a backward tracing mode \citep{emde2007}. The backward
photon tracing option speeds up the calculation of radiances and allows very
fast calculations in the thermal spectral range.

\ifthreedmystic{MYSTIC handles three-dimensional water and ice clouds in a
one-dimensional background  atmosphere of molecular scatterers and
absorbers and aerosol particles.  MYSTIC also allows topography as well as
inhomogeneous surface albedo and BRDF to be considered.}

MYSTIC is now a full vector code: It can handle polarization and
polarization-dependent scattering by randomly oriented particles,
i.e. clouds droplets and particles, aerosol particles, and molecules
\citep{emde2010}. To keep the computational time reasonable for
accurate calculations of e.g. polarized radiances in cloudy
atmospheres several ``tricks'' are required to speed up the
calculations. The first is the so called ``local estimate method''
\citep{marshak2005}. Using this method a photon contributes to the
final result of the calculation each time it is scattered. However, in
the presence of particles with strong forward scattering in the
simulated scene, such as clouds and large aerosols, the local estimate
method will produce so-called ``spikes'', these are rare photons whose
very large contribution to the result leads to slow convergence. The spike
problem can be resolved by using the ``Variance Reduction Optimal
Options Method'' \citep[VROOM,][]{buras2011a}, a collection of several
variance reduction methods which change the photon paths such that the
spikes disappear, but without altering the result (i.e.~the variance
reduction is ``unbiased'').

A detailed introduction to the Monte Carlo technique and in particular
to MYSTIC is given in \citet{mayer2009}. For specific questions
concerning the Monte Carlo technique the reader is referred to the literature
\citep{marchuk1980,collins1972,marshak2005,cahalan2005}.

MYSTIC is switched on by the option \code{rte\_solver mystic}. If no
other options are specified MYSTIC computes unpolarized quantities for
a \ifthreedmystic{3D} plane-parallel
atmosphere\ifthreedmystic{~(domain is divided into block-shaped
boxes)}. If \codeidx{mc\_polarisation} is specified, polarized
quantities are computed. The option \codeidx{mc\_spherical 1D} enables
calculations in a 1D spherical model atmosphere. All MYSTIC-specific
options start with \code{mc\_} and
are described in detail in section~\ref{sec:uvspec_options}.

\ifthreedmystic{
MYSTIC may be provided with various 2D and 3D input files, in addition
to the standard 1D input files of {\sl uvspec}. The input files may
include the following data:
\begin{itemize}
\item 3D water clouds
\item 3D ice clouds
\item 2D surface albedo
\item 2D elevation
\item 2D BRDF
%\item Lasers and detectors for lidar
\end{itemize}

If none of these are specified, MYSTIC does basically a 1D calculation
and should compare well with other solvers, in particular \code{disort2}.

MYSTIC operates in a user-defined model-domain. Since periodic boundary
conditions are applied, the user has to make sure that the quantity to be
calculated is not affected by the boundaries. For maximum flexibility,
the different grids (sample, cloud, elevation, albedo or BRDF) are
completely independent. The only constraint is that the domain size
is equal for all grids used. E.g., clouds may be defined in 5x5x2~km$^3$
cubes while the surface albedo is defined on a 1x1~km$^2$ grid,
the elevation on a 0.1x0.2~km$^2$ grid, and the output might
be sampled on a 3x4~km$^2$ grid. The only restrictions are
the available memory, the processor speed, and the requirements on
the precision of the result (see section~\ref{sec:mc_memory}).

The sampling information for MYSTIC is defined in the input file (e.g.
with \codeidx{mc\_sample\_grid}, \codeidx{zout}, \codeidx{umu}, ...).
After initialization MYSTIC reports how it interpreted the input parameters
which gives the user a chance to see if it really does what it is
supposed to be doing.

\subsubsection{Coordinates}
Mystic in cartesian mode uses an ENU coordinate system to define the atmospheric state:
\begin{itemize}
    \item{\emph{x}: east}
    \item{\emph{y}: north}
    \item{\emph{z}: up}
\end{itemize}

\begin{figure}[h!]
\centering
\tdplotsetmaincoords{70}{20}
\begin{tikzpicture}[scale=5,tdplot_main_coords]

    \coordinate (O) at (0,0,0);
    \coordinate (Ex) at (1,0,0);
    \coordinate (Ey) at (0,1,0);
    \coordinate (Ez) at (0,0,1);

    \draw[thick, ->] (-0.2,0,0) -- (Ex) node[anchor=west]{$x~\textrm{(east)}$};
    \draw[thick, ->] (0,-0.2,0) -- (Ey) node[anchor=west]{$y~\textrm{(north)}$};
    \draw[thick, ->] (0,0,0) -- (Ez) node[anchor=south]{$z~\textrm{(up)}$};

    \tdplotsetcoord{P}{1}{45.57}{60};
    \draw[thick, ->, color=red] (O) -- (P) node[anchor=south west]{sensor};
    \draw[dashed, color=red] (O) -- (Pxy);
    \draw[dashed, color=red] (P) -- (Pxy) node[midway,anchor=west]{$\textrm{umu} = 0.7$};

    \tdplotdrawarc[color=red]{(O)}{0.3}{90}{60}{xshift=0.3cm,anchor=north west}{$\textrm{phi} = 30\degree$};
\end{tikzpicture}
\caption{Sensor coordinate specification (\codeidx{umu} and \codeidx{phi}). The red arrow is pointing into the sensor, thus a sensor with positive umu values is looking downwards.}
\label{fig_sensor_coordinates}
\end{figure}
Generally, the sensor orientation is specified using the \codeidx{umu} and \codeidx{phi} input options as shown in figure~\ref{fig_sensor_coordinates}.
The location of the sensor is given in the same $x$, $y$, $z$ coordinate system by use of the option \codeidx{mc\_sensorposition}.
The position of the sun is specified either using \codeidx{latitude}, \codeidx{lognitude} and \codeidx{time} or using \codeidx{sza} and \codeidx{phi0}.
In the latter case, the angles are (maybe depending on the mindset of the reader), defined slightly different as shown in figure~\ref{fig_sun_coordinates}.

\begin{figure}[h!]
\centering
\tdplotsetmaincoords{70}{20}
\begin{tikzpicture}[scale=5,tdplot_main_coords]

    \coordinate (O) at (0,0,0);
    \coordinate (Ex) at (1,0,0);
    \coordinate (Ey) at (0,1,0);
    \coordinate (Ez) at (0,0,1);

    \draw[thick, ->] (-0.2,0,0) -- (Ex) node[anchor=west]{$x~\textrm{(east)}$};
    \draw[thick, ->] (0,-0.2,0) -- (Ey) node[anchor=west]{$y~\textrm{(north)}$};
    \draw[thick, ->] (0,0,0) -- (Ez) node[anchor=south]{$z~\textrm{(up)}$};

    \tdplotsetcoord{P}{1}{30}{210};
    \draw[thick, ->, color=orange] (O) -- (P) node[anchor=south east]{sun};
    \draw[dashed, color=orange] (O) -- (Pxy);
    \draw[dashed, color=orange] (P) -- (Pxy);

	\tdplotsetthetaplanecoords{210};
    \tdplotdrawarc[tdplot_rotated_coords, color=orange]{(O)}{0.5}{0}{30}{xshift=0.7cm,anchor=west}{$\textrm{sza} = 30\degree$}

    \tdplotdrawarc[color=orange]{(O)}{0.15}{270}{210}{yshift=-0.2cm,anchor=north}{$\textrm{phi0} = 60\degree$};
\end{tikzpicture}
\caption{Sun coordinate specification (sza and phi0). The orange arrow is pointing into the sun.}
\label{fig_sun_coordinates}
\end{figure}

\begin{figure}[h!]
\centering
\tdplotsetmaincoords{70}{20}
\pgfmathsetmacro{\thetavec}{20}
\pgfmathsetmacro{\phivec}{320}
\begin{tikzpicture}[scale=5,tdplot_main_coords]

    \coordinate (O) at (0,0,0);
    \coordinate (Ex) at (1,0,0);
    \coordinate (Ey) at (0,1,0);
    \coordinate (Ez) at (0,0,1);

    \draw[thick, ->] (-0.2,0,0) -- (Ex) node[anchor=west]{$x~\textrm{(east)}$};
    \draw[thick, ->] (0,-0.7,0) -- (Ey) node[anchor=west]{$y~\textrm{(north)}$};
    \draw[thick, ->] (0,0,-0.7) node[anchor=north]{nadir} -- (Ez) node[anchor=south]{$z~\textrm{(up, zenith)}$};

    \tdplotsetcoord{P1}{0.6}{60}{160}
    \tdplotsetcoord{P2}{0.6}{60}{100}
    \tdplotsetcoord{P3}{0.6}{100}{100}
    \tdplotsetcoord{P4}{0.6}{100}{160}
    \tdplotsetcoord{P3a}{0.6}{90}{100}
    \tdplotsetcoord{P3b}{0.7}{90}{100}

	\draw[dashed,color=orange] (O) -- (P1) node[anchor=east]{$(0,N_y-1)$};
	\draw[dashed,color=orange] (O) -- (P2) node[xshift=0.5cm,anchor=west]{$(N_x-1,N_y-1)$};
	\draw[dashed,color=orange] (O) -- (P3) node[xshift=0.5cm,anchor=west]{$(N_x-1,0)$};
	\draw[dashed,color=orange] (O) -- (P4) node[xshift=-1.2cm,anchor=north east]{$(0,0)$};
	\draw[dashed,color=black] (P3a) -- (P3b);

    \tdplotdrawarc[color=black,dotted]{(0,0,0)}{0.6}{160}{-90}{}{}
    \tdplotdrawarc[color=orange]{(P1z)}{0.519}{100}{160}{}{}
    \tdplotdrawarc[dashed,color=blue]{(P1z)}{0.519}{95}{100}{}{}
    \tdplotdrawarc[color=orange]{(P3z)}{0.59088}{100}{160}{}{}

    \tdplotdrawarc[color=black,dashed]{(0,0,0)}{0.6}{270}{160}{xshift=0.1cm,anchor=west}{$\phi_1 = 110\degree$}
    \tdplotdrawarc[color=black,dashed]{(0,0,0)}{0.7}{270}{100}{anchor=east}{$\phi_2 = 170\degree$}
    \tdplotsetthetaplanecoords{100}
    \tdplotdrawarc[tdplot_rotated_coords,color=orange]{(0,0,0)}{0.6}{60}{100}{}{}
    %\tdplotdrawarc[tdplot_rotated_coords,dotted,color=black]{(0,0,0)}{0.6}{0}{360}{}{}
    %\tdplotdrawarc[tdplot_rotated_coords,dashed,color=black]{(0,0,0)}{0.6}{100}{90}{}{}
    \tdplotsetthetaplanecoords{155}
    \tdplotdrawarc[tdplot_rotated_coords,dashed,color=blue]{(0,0,0)}{0.6}{100}{180}{anchor=east}{$\theta_1 = 80\degree$}
    \tdplotsetthetaplanecoords{95}
    \tdplotdrawarc[tdplot_rotated_coords,dashed,color=blue]{(0,0,0)}{0.6}{60}{180}{anchor=west}{$\theta_2 = 120\degree$}
    \tdplotsetthetaplanecoords{160}
    \tdplotdrawarc[tdplot_rotated_coords,color=orange]{(0,0,0)}{0.6}{60}{100}{}{}
    %\tdplotdrawarc[tdplot_rotated_coords,dotted,color=black]{(0,0,0)}{0.6}{0}{360}{}{}
    %\tdplotdrawarc[tdplot_rotated_coords,dashed,color=black]{(0,0,0)}{0.6}{80}{90}{}{}

\end{tikzpicture}
    \caption{Panorama coordinates for the option \codeidx{mc\_panorama\_alignment} \code{zenith} (default). The camera is located at the coordinate system origin. The image is recorded on a spherical shell inside the orange box, which is behind the origin. The boundaries of this box are given by the parameters $\phi_1$, $\phi_2$, $\theta_1$, $\theta_2$ to \codeidx{mc\_panorama\_view}. $\phi_1$ and $\phi_2$ are measured in the $x-y$-plane, beginning in the south. $\theta_1$ and $\theta_2$ measure the "latitude" where nadir is 0. The coordinates given in orange show the $(x, y)$ coordinates of the resulting image. The $(x, y)$ coordinates thus correspond to $(\theta, \phi)$ coordinates.}
\label{fig_panorama_coords_zenith}
\end{figure}

\begin{figure}[h!]
\centering
\tdplotsetmaincoords{70}{20}
\pgfmathsetmacro{\thetavec}{36.87}
\pgfmathsetmacro{\phivec}{-50}
\begin{tikzpicture}[scale=5,tdplot_main_coords]

    \coordinate (O) at (0,0,0);
    \coordinate (Ex) at (1,0,0);
    \coordinate (Ey) at (0,1,0);
    \coordinate (Ez) at (0,0,1);

    \draw[thick, ->] (-0.1,0,0) -- (Ex) node[anchor=west]{$x~\textrm{(east)}$};
    \draw[thick, ->] (0,-0.6,0) -- (Ey) node[anchor=west]{$y~\textrm{(north)}$};
    \draw[thick, ->] (0,0,0) -- (Ez) node[anchor=south]{$z~\textrm{(up)}$};

    \tdplotsetcoord{P}{0.6}{\thetavec}{\phivec}
    \tdplotsetcoord{Q}{0.6}{53.13}{130}
    \draw[dashed, color=blue] (P) -- (Pxy) node[near start,anchor=west]{$\textrm{umu} = -0.8$};
    \draw[dashed, color=blue] (O) -- (Pxy);
    \tdplotdrawarc[color=red]{(O)}{0.48}{270}{130}{xshift=0.3cm,anchor=south east}{$\textrm{phi} = 140\degree$};
    \draw[dashed, color=red] (Q) -- (Qxy);

    \tdplotsetrotatedcoords{\phivec}{\thetavec}{0}

    \draw[tdplot_rotated_coords, thick, ->, color=magenta] (0,-0.1,0) -- (0,0.6,0) node[anchor=south east]{$x'$};
    \draw[tdplot_rotated_coords, thick, ->, color=red] (0.4,0,0) -- (-0.6,0,0) node[anchor=north west]{$y'$};
    \draw[tdplot_rotated_coords, thick, -, color=red] (0.6,0,0) -- (0.53,0,0);
    \draw[tdplot_rotated_coords, thick, ->, color=blue] (0,0,-0.6) -- (0,0,0.6) node[anchor=south east]{$z'$};

    \tdplotdrawarc[tdplot_rotated_coords,color=black,dotted]{(0,0,0)}{0.6}{0}{345}{}{};
    \tdplotdrawarc[tdplot_rotated_coords,color=black,dashed]{(0,0,0)}{0.6}{0}{-15}{anchor=north west}{$\phi_1=15\degree$};
    \tdplotdrawarc[tdplot_rotated_coords,color=black,dashed]{(0,0,0)}{0.8}{0}{-45}{anchor=north west}{$\phi_2=45\degree$};

    \tdplotdrawarc[tdplot_rotated_coords,color=orange]{(0,0,0.1042)}{0.59088}{-15}{-45}{}{}
    \tdplotdrawarc[tdplot_rotated_coords,color=orange]{(0,0,-0.1042)}{0.59088}{-15}{-45}{}{}

    \tdplotsetrotatedthetaplanecoords{0}
    \tdplotdrawarc[tdplot_rotated_coords,color=black,dotted]{(0,0,0)}{0.6}{0}{360}{}{}
    \tdplotsetrotatedthetaplanecoords{-15} %note that this changes the rotated frame already
    \tdplotdrawarc[tdplot_rotated_coords,color=orange]{(0,0,0)}{0.6}{80}{100}{}{}
    \tdplotdrawarc[tdplot_rotated_coords,dashed,color=blue]{(0,0,0)}{0.6}{180}{100}{yshift=1cm,anchor=west}{$\theta_1=80\degree$}
    \tdplotsetrotatedthetaplanecoords{-30}
    \tdplotdrawarc[tdplot_rotated_coords,color=orange]{(0,0,0)}{0.6}{80}{100}{}{}
    \tdplotsetrotatedthetaplanecoords{-5}
    \tdplotdrawarc[tdplot_rotated_coords,dashed,color=blue]{(0,0,0)}{0.6}{180}{80}{yshift=0.5cm,anchor=east}{$\theta_2=100\degree$}

\end{tikzpicture}
    \caption{Panorama corrdinates for \codeidx{mc\_panorama\_alignment} \code{mu}. In \emph{mu} aligned mode, the panorama is taken as in \emph{zenith}-mode, however the whole coordinate system is rotated using the parameters \codeidx{umu} and \codeidx{phi} yielding the new coordinates $x'$, $y'$, $z'$. If $\textrm{umu} = -1$ and $\textrm{phi} = 180\degree$, the coordinates are exactly the same as in \emph{zenith} mode. Be aware that if \codeidx{umu} is $1$ or $-1$, the value of \codeidx{phi} is not accepted and the system behaves as if $\textrm{phi} = 180\degree$. In this case, the equivalent rotation can be achieved by $\phi_1$ and $\phi_2$.}
\label{fig_panorama_coords_mu}
\end{figure}

If panoramic images are calculated, the sensor specification is extended by a definition for the field of view of the camera an the option \codeidx{mc\_panorama\_view}.
The behavior of this specification can be changed by the \codeidx{mc\_panorama\_alignment}.
In the default mode (\codeidx{mc\_panorama\_alignment} \code{zenith}), \code{umu} and \code{phi} are ineffective.
The view specificatiion behaves as described in figure~\ref{fig_panorama_coords_zenith}.
If \codeidx{mc\_panorama\_alignment} \code{mu} is activated, the user can basically rotate the camera.
The angles are defined as in figure~\ref{fig_panorama_coords_mu}.

\subsubsection{Three-dimensional clouds}

The options \codeidx{wc\_file 3D}
and \codeidx{ic\_file 3D} may be used to define 3D water and ice
cloud properties respectively. The model atmosphere may contain both 3D
(defined in a \code{wc\_file/ic\_file 3D}) and 1D clouds (defined in a
\code{wc\_file/ic\_file 1D}), but for obvious reasons not in the same layer. The format
of the files is explained in section~\ref{sec:uvspec_options}.

The conversion from microphysical to optical properties
is done identically for 1D and 3D clouds and is defined
by the options \codeidx{wc\_properties} and \codeidx{ic\_properties}. All
possible settings for \code{wc\_properties} and \code{ic\_properties}
have been implemented in MYSTIC (e.g., hu, mie, yang, HEY, baum ...).
Clouds can be defined eiter as ASCII or as netCDF files.

\paragraph{ASCII}
The following example shows the easiest possible 3D
cloud file which defines a checkerboard grid of clouds:
\begin{Verbatim}[fontsize=\footnotesize, frame=single, samepage=true]
  2 2 5 3
  1.0 1.0 0 1 2 3 4 5

  1 1 2 0.1 10
  2 2 2 0.1 10
\end{Verbatim}
For the layer between 1 and 2 km a 3D cloud is defined with liquid water
content 0.1 $g/m^3$ and effective radius 10 $\mu$m for horizontal
boxes (1,1) and (2,2). Boxes (1,2) and (2,1) are cloudless. The result are
cubic clouds with a volume of 1x1x1~km$^3$. The microphysical properties are
converted to optical properties according to \code{wc\_properties}.

\paragraph{netCDF}
If the provided cloud file is a netCDF instead of an ASCII file, this will be
detected automatically. The netCDF file must have the following structure:
\begin{Verbatim}[fontsize=\footnotesize, frame=single, samepage=true]
netcdf cloud {
dimensions:
	ny = 2 ;
	nx = 2 ;
	nz = 1 ;
	nz_lev = 2 ;
variables:
	double lwc(ny, nx, nz) ;
	double z(nz_lev) ;
	double reff(ny, nx, nz) ;

// global attributes:
	:cldproperties = 3 ;
	:dx = 1. ;
	:dy = 1. ;
}
\end{Verbatim}
The order of the dimensions is important, and the size of \code{nz\_lev} must be
exactly \code{nz + 1}. The \code{cldproperties} attribute is equal to the flag
in the ASCII format. The variable names change for different \code{cldproperties}
according to the following table:
\begin{itemize}
    \item{1: \quad \code{ext g1 ssa}}
    \item{2: \quad \code{ext reff}}
    \item{3: \quad \code{lwc reff}}
\end{itemize}

\subsubsection{Two-dimensional surface albedo}

A 2D surface albedo may be defined using the option
\codeidx{mc\_albedo\_file}. The format of the file is explained in
section~\ref{sec:uvspec_options}.

\subsubsection{Topography}

A 2D elevation may be defined using the option
\codeidx{mc\_elevation\_file}. The ASCII format is explained in
section~\ref{sec:uvspec_options}. For the netcdf format please refer
to \file{README.MC}.

Caution:
\begin{itemize}
\item To avoid confusion, do not specify an \code{altitude} different
  from 0 in the uvspec input file.
\item There may be problems if the 2D surface hits 0
  (more testing required). Use 0.001 as lowest altitude.
\item  The elevation file MUST BE PERIODIC
\end{itemize}

Between the grid points, the surface is interpolated
bilinearely:
\begin{equation}
  z(x,y) = a + bx + cy + dxy
\end{equation}
where $z$ is the altitude and the coefficients $a$, $b$, $c$, and $d$
are determined from
the altitudes specified at the four corners of each pixel.
Slant surfaces are treated as they should be; e.g., photons
may be reflected downward at snow-covered mountain sides.

\subsubsection{Bidirectional reflectance distribution function}
MYSTIC allows different homogenous or 2D-inhomogeneous BRDFs. The
implementation of the different BRDFs is rather heterogeneous,
as were the requirements when each of them was first implemented.
Please note that BRDFs currently do not work together with topography. The
very simple reason for that is in structured terrain reflection
polar angles larger than 90 degree are possible for which the
existing parameterizations do not provide data. The following
parameterizations are included:
\begin{itemize}
\item Water BRDF by \citet{cox54a,cox54b}; currently only homogeneous; switched
  on with \codeidx{brdf\_cam u10}, ... like in the 1D case
\item AMBRALS (Algorithm for Modeling[MODIS] Bidirectional Reflectance
  Anisotropies of the Land Surface; \citet{wanner97}), see also
  \url{http://i3rc.gsfc.nasa.gov/phase3/brasil/phase3_step1_brasil.htm}.
  AMBRALS is three-parameter BRDF fit for vegetated and non-vegetated surfaces.
  A \codeidx{mc\_ambrals\_file} may be specified which contains the
  3 parameters for each surface pixel. The format is like
  the format of 2D surface albedo file, except that each data line
  contains (iso, vol, geo) instead of only one albedo value.
  Obviously, wavelength-dependent AMBRALS BRDFs are not
  possible at present.
\item RPV \citep{rahman93a}, a three parameter
  fit for vegetated and non-vegetated surfaces. RPV is currently the
  most flexible surface description in MYSTIC as it is currently
  the only way to define a wavelength-dependent 2D BRDF.
  Two different ways exist to define an RPV BRDF:
  \begin{itemize}
  \item 1D, using the options \codeidx{brdf\_rpv k} ... like in the 1D case
  \item using \codeidx{mc\_rpv\_file} and \codeidx{mc\_rpv\_type}.
    The first is a RPV
    type for each surface pixel; type is simply a label like
    "Grass" or "1" or whatever. For each of these types,
    \code{mc\_rpv\_type} must have an entry which connects the type to
    a file which contains wavelength-dependent RPVs. Sounds
    complicated but is a very efficient way to define a
    wavelength-dependent 2D RPV. Label ``CaM'' is reserved for Cox and Munk
    and invokes the Cox and Munk ocean BRDF for the respective pixel. Thus
    it is possible to combine land and ocean BRDFs.
  \end{itemize}
\item For calculations including polarization the option
  \codeidx{bpdf\_tsang\_u10} is available which calculates polarized
  bidirectional reflection from water surfaces.
\end{itemize}
}

\subsubsection{MYSTIC output}

{\sl uvspec} will print its output (horizontally averaged
irradiance and actinic flux) usually to stdout. MYSTIC provides
several additional output
files. We have to distinguish two classes of output:
Monochromatic and spectral output where the latter can be recognized
by the extension ``.spc''. Monochromatic output files

\begin{itemize}
\item mc.flx - irradiance, actinic flux at levels
\item mc.rad - radiance
\item mc.abs - absorption/emission
\item mc.act - actinic flux, averaged over layers
\end{itemize}

are generated only for the case of a calculation where MYSTIC is called
only once. That is, a monochromatic calculation without subbands introduced
by \code{mol\_abs\_param}. They contain ``plain'' MYSTIC output, without
consideration of extraterrestrial irradiance, sun-earth-distance, spectral
integration, etc. As such they are mainly interesting for MYSTIC developers
or for users interested in artificial cases and photon statistics since
they are as close as possible to the photon statistics of MYSTIC: e.g.
the ``irradiance'' in these files is basically the number of photons arriving
at the detector divided by the number of photons traced. In addition to the
average, a standard deviation of the result can be calculated online which is
stored in ``.std''.

For most real-world applications the user will prefer the ``.spc'' files

\begin{itemize}
 \item mc.flx.spc - spectral irradiance, actinic flux at levels
 \item mc.rad.spc - spectral radiance at levels
 \item ...
\end{itemize}

In contrast to the monochromatic files which are transmittances (E/E0, L/E0,
...) the data in ".spc" is "fully calibrated" output, as for all other
solvers. "fully calibrated" means multiplied with the extraterrestrial
irradiance, corrected for the Sun-Earth distance, integrated/summed
over wavelength, etc. Please be aware that such a calculation might require
a lot of memory because output is stored as a function of x, y, z, and
wavelength (and possibly polarization, if you switched on \code{mc\_polarisation}).
E.g. a comparatively harmless "mol\_abs\_param kato2" calculation with an sample grid of 100x100 pixels
at 10 altitudes would imply about 100x100x10x148 = 14,800,000 (Nx$\cdot$Ny$\cdot$Nz$\cdot$Nlambda) grid points. Depending
on the output chosen (irradiance, radiance, ...) up to six floating
point numbers need to be stored which amounts to 360 MBytes. Depending
on the post-processing in {\sl uvspec}, this memory may actually be used
twice which then would be 720 MBytes.

\begin{description}
\item[mc.flx / mcNN.flx]
  The output file \code{mc.flx} contains the irradiance
  at the surface defined by elevation file. Note that
  this output is {\bf not} for $z=0$, but for the actual 2D surface:
  \begin{Verbatim}[fontsize=\footnotesize, frame=single, samepage=true]
    500  500 0 0.325889 0 0 0.441766 0
    500 1500 0 0.191699 0 0 0.267122 0
    500 2500 0 0.210872 0 0 0.420268 0
  \end{Verbatim}
  The columns are:
  \begin{enumerate}
  \item  x [m] (pixel center)
  \item  y [m] (pixel center)
  \item  direct transmittance
  \item  diffuse downward transmittance
  \item  diffuse upward transmittance
  \item  direct actinic flux transmittance
  \item  diffuse downward actinic flux transmittance
  \item  diffuse upward actinic flux transmittance
  \end{enumerate}
  The transmittance is defined as irradiance devided by the extraterrestrial irradiance.
  It is not corrected for Sun-Earth-Distance.

  Note that even for an empty atmosphere, the transmittance
  would not be 1 but cos(SZA), due to the slant incidence of the radiation.

  The output files \code{mcNN.flx} contain the irradiances
  at different model levels - one for each \code{zout}. \code{NN} is the
  number of the output level counted from the bottom (ATTENTION: Levels are
  counted from 0 here!). The file format is the same as in \code{mc.flx}.

  (If interested in surface quantities, please use the irradiance data at the
  surface from \code{mc.flx}, not from \code{mc00.flx}; the data from
  \code{mc00.flx} or whatever layer coincides with the
  surface may be wrong for technical reasons).

\item[mc.rad / mcNN.rad]
  The output file \code{mc.rad} contains the radiance
  at the surface defined by \code{elevation\_file}. Note that
  this output is {\bf not} for $z=0$, but for the actual 2D surface:
  \begin{Verbatim}[fontsize=\footnotesize, frame=single, samepage=true]
    500  500 45 270 0.0239094 0 0.0623305 0.063324
    500 1500 45 270 0.0239094 0 0.0602891 0.063156
  \end{Verbatim}
  The columns are:
  \begin{enumerate}
  \item  x [m] (pixel center)
  \item  y [m] (pixel center)
  \item  viewing zenith angle  [deg]
  \item  viewing azimuth angle [deg]
  \item  aperture solid angle [sterad]
  \item  direct  radiance component
  \item  diffuse radiance component
  \item "escape" radiance
  \end{enumerate}
  For almost all applications you may safely ignore the ``direct'' and
  ``diffuse'' radiance components and use only the escape radiance. If the
  latter is 0 then you probably forgot to switch on \code{mc\_escape}.
  The "escape" radiance is the radiance "measured" by an ideal
  instrument with 0$^\circ$ opening angle. It is only calculated
  when \codeidx{mc\_escape} is selected and it usually converges
  much faster than the "cone sampled" radiance in column 7.
  It is recommended to always use \code{mc\_escape} for radiance
  calculations. For the ``direct'' and ``diffuse'' radiance, photons
  falling into the aperture are counted. This might be an option for
  instruments with a very large aperture only because otherwise the result
  is noisy.

  The output files \code{mcNN.rad} contain the radiances
  at different model levels - one for each \code{zout}. \code{NN} is the
  number of the output level counted from the bottom (ATTENTION: Levels are
  counted from 0 here!). The file format is the same as in \code{mc.rad}.

  (If interested in surface quantities, please use the radiance data
  at the surface from \code{mc.rad}, not from \code{mc00.rad}; the data from
  \code{mc00.rad} or whatever layer coincides with the
  surface may be wrong for technical reasons).

\item[mcNN.abs]
  The file \code{mcNN.abs} includes the absorption per unit area in the given layer.
  NN is the number of the output layer on the atmospheric
  grid (counted from the bottom, starting from 1). This file is generated if \code{mc\_forward\_ouput absorption}
  or \code{mc\_forward\_output emission} is specified.

  The columns are:
  \begin{enumerate}
  \item  x [m] (pixel center)
  \item  y [m] (pixel center)
  \item  absorption/emission/heating rate (W/m$^2$)
  \end{enumerate}

  If multiplied by the extraterrestrial irradiance, the column
  absorption in W/m$^2$ is obtained. In a 1D atmosphere, with a solar source,
  absorption = e\_net(top) - e\_net(bottom) (this is not true for a thermal
  source because then emission needs to be considered; see below). If
  \code{mc\_forward\_output emission} is specified, the file contains the thermal emission of
  the layer per unit area, that is, the Planck function times the optical
  thickness of the layer times 4$\pi$ (angular integral of the Planck
  radiance). If \code{mc\_forward\_output heating} is specified, the heating rate per unit area is
  provided instead of absorption (in the same units as absorption).
  For a solar source, the heating rate is identical to the absorption.
  In the thermal, however, each emitted photon is counted as cooling
  and hence the heating rate may be negative. In a 1D atmosphere, with a
  solar or thermal source, absorption = e\_net(top) - e\_net(bottom).

  For computational efficiency reasons \code{mcNN.abs} is not provided on the
  sample grid but on the atmospheric grid. For the same reason, results are
  only calculated for 3D layers. In order to obtain 3D absorption for 1D
  cloudless layer, you need to specify an optically very thin 3D cloud, e.g.
  LWC/IWC = 10$^{-20}$ g/m$^3$ (yes, this is a dirty trick but a necessary one).

\item[mcNN.act]
  \code{mcNN.act} contains the 4$\pi$ actinic flux in the given layer,
  calculated from the absorbed energy (per unit area) divided by the
  absorption optical thickness of the layer. In contrast to the
  actinic flux in \code{mcNN.flx}, this is a layer quantity the
  accuracy of which is generally much better than the level quantities
  which are calculated from radiance / cos (theta). As for the absorption
  above, \code{mcNN.act} is not provided on the sample grid but on the
  atmospheric grid. NN is the number of the output layer (counted from the
  bottom, starting from 1). This file is generated if \codeidx{mc\_forward\_output actinic} is specified.

  The columns are:
  \begin{enumerate}
  \item  x [m]
  \item  y [m]
  \item  actinic flux (W/m$^2$)
  \end{enumerate}

\end{description}

The spectral files are as follows:
\begin{description}
 \item[mc.flx.spc]
   \ifthreedmystic{This is the most versatile and useful irradiance /
     actinic flux output of MYSTIC}:
  \begin{Verbatim}[fontsize=\footnotesize, frame=single, samepage=true]
  400.0 0 0 0 1.0e+00 0.0e+00 1.5067e-01 1.0e+00 0.0e+00 3.5044e-01
  401.0 0 0 0 1.0e+00 0.0e+00 1.5044e-01 1.0e+00 0.0e+00 3.5863e-01
  402.0 0 0 0 1.0e+00 0.0e+00 1.5022e-01 1.0e+00 0.0e+00 3.4755e-01
  \end{Verbatim}

  The columns are:
  \begin{enumerate}
  \item  wavelength [nm]
  \item  ix (0 ... Nx-1)
  \item  iy (0 ... Ny-1)
  \item  iz (0 ... Nz-1)
  \item  direct irradiance
  \item  diffuse downward irradiance
  \item  diffuse upward irradiance
  \item  direct actinic flux
  \item  diffuse downward actinic flux
  \item  diffuse upward actinic flux
  \end{enumerate}
  These numbers are created the same way as the standard {\sl uvspec} output. That
  is, they are multiplied with the extraterrestrial irradiance, corrected for
  Sun-Earth-distance, integrated over wavelength, converted to reflectivity or
  brightness temperature, etc.

 \item[mc.rad.spc]
   \ifthreedmystic{This is the most versatile and useful radiance output of
   MYSTIC}:
  \begin{Verbatim}[fontsize=\footnotesize, frame=single, samepage=true]
  400.0 0 0 0 0.0398276
  401.0 0 0 0 0.0396459
  402.0 0 0 0 0.0398005
  \end{Verbatim}

  The columns are:
  \begin{enumerate}
  \item  wavelength [nm]
  \item  ix (0 ... Nx-1)
  \item  iy (0 ... Ny-1)
  \item  iz (0 ... Nz-1)
  \item  radiance
  \end{enumerate}
  These numbers are created the same way as the standard {\sl uvspec}
  output. That is, they are multiplied with the extraterrestrial irradiance,
  corrected for Sun-Earth-distance, integrated over wavelength, converted to
  reflectivity or brightness temperature, etc.

  If the {\bf polarized} mystic is used (\code{mc\_polarisation}) then the four
  components of the Stokes vector (I,Q,U,V) are output for each wavelength and
  grid point, in four separate lines.

\ifthreedmystic{
 \item[mc.abs.spc]
  \code{mc.abs.spc} contains the absorption per unit area for all layers. This
  file is generated if \code{mc\_forward\_output absorption} or \code{mc\_forward\_output emission} is specified.

  The columns are:
  \begin{enumerate}
  \item  wavelength [nm]
  \item  ix (0 ... Nx-1)
  \item  iy (0 ... Ny-1)
  \item  iz (0 ... Nz-1)
  \item  absorption/emission/heating rate
  \end{enumerate}

  These numbers are created the same way as the standard {\sl uvspec} output. That
  is, they are multiplied with the extraterrestrial irradiance, corrected for
  Sun-Earth-distance, integrated over wavelength, converted to reflectivity or
  brightness temperature, etc.  The unit is determined by an extra option to
  \code{mc\_forward\_output absorption} or \code{mc\_forward\_output emission}.

  For computational efficiency reasons \code{mc.abs.spc} is not provided on the
  sample grid but on the atmospheric grid. For the same reason, results are
  only calculated for 3D layers. In order to obtain 3D absorption for 1D
  cloudless layer, you need to specify an optically very thin 3D cloud, e.g.
  LWC/IWC = 10$^{-20}$ g/m$^3$ (yes, this is a dirty trick but a necessary one).

 \item[mc.act.spc]
  \code{mcNN.act} contains the 4$\pi$ actinic flux in the given layer,
  calculated from the absorbed energy (per unit area) divided by the
  absorption optical thickness of the layer. In contrast to the
  actinic flux in \code{mc.act.flx}, this is a layer quantity the
  accuracy of which is generally much better than the level quantities
  which are calculated from radiance / cos (theta). As for the absorption
  above, \code{mcNN.act} is not provided on the sample grid but on the
  atmospheric grid. NN is the number of the output layer (counted from the
  bottom, starting from 1). This file is generated if \codeidx{mc\_forward\_output actinic} is specified.

  The columns are:
  \begin{enumerate}
  \item  wavelength [nm]
  \item  ix (0 ... Nx-1)
  \item  iy (0 ... Ny-1)
  \item  iz (0 ... Nz-1)
  \item  actinic flux
  \end{enumerate}
}
\end{description}

\ifthreedmystic{
\subsubsection{Memory requirements and computational speed}
\label{sec:mc_memory}

\begin{enumerate}
\item  3D clouds are defined on a 3D grid and the amount of
  memory required by MYSTIC is usually determined by
  the 3D cloud grid. Several variables need to be stored
  for each grid cell, including the optical properties of
  the cell, the grid cell absorption, etc. Umpteen (20-100)
  bytes are typically required for each grid cell.
  Computational time is to a large degree determined by
  the total optical thickness of the cloud because higher
  extinction means more scattering events and a longer
  photon path. To a lesser degree, the computational time
  is influenced by the number of cells but this may become
  important if the radiance is calculated using
  local estimates.

\item 2D albedo requires some memory but usually less than
  clouds because it is defined on a 2D grid compared to the
  3D cloud grid. Only one double (8 bytes on a 32 bit machine)
  is stored per pixel. A high resolution has no influence
  on computational time.

\item 2D elevation requires somewhat more memory than a 2D albedo
  because 5 doubles are stored per pixel. Higher resolution
  will lead to higher computational times.

\item The sample grid by itself has only little influence on
  computational time because for a given number of photons,
  the computational time does not depend on the number of
  grid cells. The precision of the result, however depends
  strongly on the number of grid cells Nx $\cdot$ Ny, as it
  decreases with sqrt(Nx$\cdot$Ny). The number of altitude
  levels has only little influence on the computational
  time but of course a large influence on the memory
  requirements. The calculation of radiances has a large
  impact on computational time if local estimates are used.
  % CE: In current version it is only possible to compute 1 direction at a time
  %In the worst case, the computational time may
  %scale directly with the number of directions for which the
  %radiance is to be calculated.
\end{enumerate}
}


\section{System Flow}
\label{sec:system-flow}

The system flow can be specified by session types, as in the following
sections.

\subsection{Session Types}
\label{sec:session-types}

\subsubsection{Welcome}
\label{sec:welcome}

\begin{align}
  Welcome &= \&
                \begin{cases}
                  \boption{register}{Register}\\
                  \boption{login}{Login}\\
                  \boption{contact}{Contact}\\
                  \boption{translate}{Translate}
                \end{cases}
\end{align}
%

\subsubsection{Registration}
\label{sec:registration}

\begin{align}
  Register &= \&
                 \begin{cases}
                   \boption{input}{ConfirmR}
                 \end{cases}
\end{align}
%
\begin{align}
  ConfirmR &= +
             \begin{cases}
               \boption{ok}{SaveR}\\
               \boption{cancel}{Welcome}
             \end{cases}
\end{align}
%
\begin{align}
  SaveR &= \&
              \begin{cases}
                \boption{save}{Welcome}
              \end{cases}
\end{align}
%

\subsubsection{Login}
\label{sec:login}

\begin{align}
  Login &= \&
              \begin{cases}
                \boption{input}{ConfirmL}
              \end{cases}
\end{align}
%
\begin{align}
  ConfirmL &= +
             \begin{cases}
               \boption{ok}{Home}\\
               \boption{cancel}{Welcome}
             \end{cases}
\end{align}
%

\subsubsection{Services Access}
\label{sec:services-access}

\begin{align}
  Home &= +
         \begin{cases}
           \boption{user}{UserHome}\\
           \boption{org}{OrgHome}
         \end{cases}
\end{align}
%
\begin{align}
  UserHome &= \&
                 \begin{cases}
                   \boption{event}{EventManager}\\
                   \boption{account}{AccountManager}\\
                   \boption{timeline}{Timeline}\\
                   \boption{yellowPages}{YellowPages}
                 \end{cases}
\end{align}
%
\begin{align}
  OrgHome &= \&
                \begin{cases}
                  \boption{service}{ServiceManager}\\
                  \boption{account}{AccountManager}\\
                  \boption{timeline}{Timeline}\\
                  \boption{yellowPages}{YellowPages}
                \end{cases}
\end{align}
%

\subsubsection{Impressum}
\label{sec:impressum}

\begin{align}
  Contact &= \&
                \begin{cases}
                  \boption{read}{Contact}\\
                  \boption{welcome}{Welcome}
                \end{cases}
\end{align}

\subsection{Navigation}
\label{sec:navigation}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "main"
%%% End:


%% Last update: Oct. 21, 2020
\newcommand{\ignore}[1]{}

%\subsubsection{\stid{3.07} Factorization Based Sparse Solvers and Preconditioners for Exascale} \label{subsubsect:strumpack}
\subsubsection{\stid{3.07} STRUMPACK-SuperLU} \label{subsubsect:strumpack}

\paragraph{Overview}
% \textit{Provide an overview of your project.  You might find that the introductory text from your Fall 2017 Project Summary \url{https://confluence.exascaleproject.org/display/1ST/Fall+2017+ECP+ST+Project+Summaries} useful as a starting draft.}
This project will deliver factorization-based sparse solvers
encompassing the two widely used algorithm variants: supernodal
(SuperLU: \url{https://portal.nersc.gov/project/sparse/superlu})
and multifrontal (STRUMPACK: \url{http://portal.nersc.gov/project/sparse/strumpacK}).
STRUMPACK is
further enhanced with scalable preconditioning using
hierarchical and data-sparse matrix algebra. Both libraries are purely algebraic,
applicable to many application domains. We will address
several Exascale challenges, with the following
focus areas:
(1) Develop novel approximation algorithms that have lower
arithmetic and communication complexity with respect to the size of the
input matrix;
(2) Develop new parallelization strategies that reduce
inter-process communication and expose task parallelism and vectorization
for irregular computations involving sparse data structures to better
use on-node resources;
(3) Integrate our software into higher-level
algebraic solvers such as hypre, PETSc, Trilinos, and collaborate with
ECP teams for application-specific and hardware-specific tuning
of the parameters space to achieve optimal efficiency.

Our solver technology is essential for ECP, because many
% DOE simulation and data analysis
codes expected to run on Exascale machines need
solutions of sparse algebraic systems, and many high-fidelity simulations
involve large-scale multiphysics and multiscale modeling problems that
generate highly ill-conditioned and indefinite algebraic equations,
for which pure iterative methods
% such as Krylov and multigrid, albeit readily parallelizable on large machines,
cannot converge to the solution.
The factorization-based algorithms being developed herein
represent an important class of methods that are indispensable building
blocks for solving those numerically challenging problems. Our software
can often be used as a reliable standalone solver, or as a preconditioner
for Krylov methods, or as a coarse grid solver in multigrid
methods. %, just to name a few.

\vspace{-10pt}
\paragraph{Key Challenges}
%\textit{Describe what is hard to do, why it is challenging.}
At Exascale we need to address several major challenges:
decreasing amount of memory per core, increasing impact of communication
cost and load imbalance, and increasing architectural heterogeneity.
Our new design of algorithms and codes must focus on
reducing communication and synchronization and task scheduling
instead of floating point operation throughput. In sparse factorization
methods, we expect new bottlenecks in parts of the code
that previously received little attention. For example, the preprocessing
step involves numerical pivoting for selecting stable pivots and
symbolic factorization, which do not yet parallelize well on manycore
architectures with fine-grained parallelism.
At Exascale, direct solvers are more likely to
be used in a preconditioning strategy, for example, in block Jacobi
preconditioning, in domain decomposition methods or as coarse-grid
solvers in algebraic multigrid, which requires repeated triangular
solves. The challenge here is to mitigate the low arithmetic intensity
and high degree of data dependency.

Compared to iterative methods, the primary bottleneck of direct solvers
is the asymptotically higher growth in memory need and floating point
operations, especially for problems from three-dimensional geometry.
It is imperative to develop new factorization methods that require
much less memory and data movement.

\vspace{-10pt}
\paragraph{Solution Strategy}
%\textit{Describe your basic strategy for addressing the challenges.}
We will address these challenges in several thrust areas.
The new techniques will be implemented in the two software packages SuperLU
and STRUMPACK. The former is a widely used sparse direct solver based on
supernodal factorization and the latter is a newer direct
solver/preconditioner package based on multifrontal factorization
and hierarchical low-rank matrix structures.
% Parallel pre-pivoting for both packages.

The improvements for SuperLU will be mainly in two areas: (1) develop
the communication-avoiding 3D factorization and triangular solve
algorithms and codes that have provably lower communication complexity;
(2) develop a synchronization-avoiding triangular solve code to enable more
overlap of communications of different processes at different substitution steps;
(3) develop new multi-GPU codes for both symbolic preprocessing step and
numerical factorization and solve steps.

In addition to exploiting structural sparsity as SuperLU does, STRUMPACK
also exploits data sparseness in the dense blocks of sparse factors using
low-rank representations, which leads to linear scaling $O(n)$ or $O(n \log n)$
memory and arithmetic complexity for PDEs with smooth kernels.
The developments for STRUMPACK will focus on several areas:
\ignore{ %% old
(1) develop robust stopping criteria --- both absolute and relative --- for
    adaptive (incremental) randomized sampling schemes to reveal numerical
    ranks in the low-rank compression routine. The goal is to use
    enough samples for stability, but not too many for efficiency;
(2) add OpenMP support for both HSS compression and ULV factorization routines,
    especially use OpenMP task construct to support irregular parallelism;
(3) reduce MPI communication in all stages of the code, including HSS
    construction, ULV factorization and triangular solve;
(4) in addition to HSS, develop codes to support other simpler low-rank
    formats, such as HOLDR and BLR. The HSS format has asymptotically
    lower complexity than HOLDR and BLR, but has a larger prefactor constant.
    We expect HSS to be more useful for large-scale problems while HOLDR
    and BLR are more useful for mid-range problems;
(5) work with ECP application teams to examine their specific problem
    characteristics and develop the best clustering/ordering methods to
    reveal low-rank structures.
}

(1) development of an advanced preconditioner based on approximate
multifrontal LU factorization, combining small dense fronts, medium
sized Block Low-Rank (BLR) fronts (reducing the complexity pre-factor)
and large fronts compressed using the Hierarchically Off-Diagonal
Butterfly (HODBF) representation (leading to nearly linear scaling for
large high-frequency problems); (2) port the BLR algorithms --
including several variants like left and right-looking, low-rank
update and accumulate -- to GPUs (targeting CUDA, HIP/ROCm and
SYCL/DPC++), and include in the preconditioner;
%targeting Perlmutter, Frontier and Aurora.  (3) reduce
%MPI communication
(3) develop sparse direct solvers (preconditioners) that are fully
resident on the GPU, including reordering and symbolic analysis.
%. (4)
%work with ECP application teams to examine their specific problem
%characteristics

\vspace{-10pt}
\paragraph{Recent Progress}
%\textit{Describe what you have done recently.  It would be good to have some kind of figure or diagram in this section.}
\ignore{ %%%% replace the following by the new activities
In the past six months, we added more support for GPUs and
improved on-node threading performance.  To this end, we participated
in the 3.5-day ECP OpenMP Hackathon at NERSC in August 2019,
working closely with the HPCToolkit and SOLLVE teams,
as well as the OpenMP/vectorization experts from Intel.
Using HPCToolkit revealed several performance bottlenecks.  We rewrote
the code to remove a few inefficiencies, and identified solution strategies
for the other bottlenecks.

We also worked with two ECP applications: MFEM electromagnetic diffusion
problems governed by high frequency indefinite Maxwell equations
(CEED Co-Design Center) and ExaSGD Miniapp2 -- sparse ACOPF matrices:
\url{https://github.com/LLNL/hiop/tree/sandbox/matrices/data/acopf_matrices}
}  %%%% ignored

We mainly focus on the multi-GPU developments. For SuperLU, the new developments are
on triangular solve with one-sided communication using Nvidia's NVSHMEM and AMD's
ROCSHMEM (in design stage).
%All the experiments are performed on Summit.
% The main algorithmic challenges we have to overcome are: parallel tasks are of non-uniform size,
% load imbalance, and memory and communication bound operations.
% For STRUMPACK we improved the GPU off-loading code. We ported the
% preconditioner based on block low-rank compression to distributed
% memory systems. We developed an interface from Trilinos to STRUMPACK.
For STRUMPACK we further improved performance of the sparse direct
solver on GPUs, by reducing memory allocations. We reduced the peak
memory usage of the BLR enabled preconditioner, allowing to solve much
larger problems.
We also worked with the ECP application ExaSGD team, applying our sparse solvers to
the linear systems coming from AC optimal power flow problems. The linear systems
arising from the Interior Point optimization loops are highly ill-conditioned,
and zero-pivots are encountered during numerical factorization.
We improved both STRUMPACK and SuperLU to deal with the situation and allow the factorization
to succeed and recover the solution accuracy by iterative refinement.

The other algorithmic changes and the results are detailed below.

\vspace{-5pt}
\paragraph\
\underline{STRUMPACK}  % {\bf (Pieter -- update the following)}
\begin{itemize}
\item We improved the block low-rank preconditioner to drastically
  reduce the peak memory usage. This is achieved by building the BLR
  representation one single column at a time. This has allowed us to
  solve numerically challenging 3D problems up to $350^3$, using
  double precision complex arithmetic, on 64 nodes of Cori.
\item We implemented different BLR variants, including left-looking
  (reducing communication), and low-rank update and accumulate
  operations (reducing algorithm complexity).
\item In addition to NVIDIA and AMD GPU support~\cite{ghyselsSTRUMPACKGPU}, STRUMPACK now has
  experimental support for Intel GPUs through SYCL/DPC++ and the oneAPI
  standard's variable sized batched BLAS and LAPACK routines.
\end{itemize}
\vspace{-.13in}
\begin{figure}[htb]
  \centering
  \includegraphics[scale=0.7]{projects/2.3.3-MathLibs/2.3.3.07-STRUMPACK-SuperLU/P3_V100.pdf}
  \vspace{-.13in}
  \caption{STRUMPACK numerical factorization performance on Summit.}
  \label{fig:strumpack-parmetis-scaling}
\end{figure}

\underline{SuperLU}
\begin{itemize}
\item For the multi-GPU sparse triangular solve (SpTRSV), we leverage the advantage of
  GPU-initiated data transfers of NVSHMEM.
  %  We create a novel producer-consumer paradigm to manage the computation
  % and communication in SpTRSV and implement it using two CUDA streams.
  The new  multi-GPU SpTRSV implementation using two CUDA streams
  achieves a $3.7\times$ speedup when using twelve GPUs (two nodes of the Summit
  supercomputer at ORNL) relative to our implementation on a single GPU, and
  up to $6.1\times$ compared to NVIDIA's cuSOLVER (cuSPARSE csrsv2) over the range of
  one to eighteen GPUs~\cite{Sptrsv-nvshmem}.
%\item Implemented the single precision LU factorization with double precision iterative refinement.
% Initial tests show up to 50-60\% speedup on 1 node Summit using 6 CPU cores and 6 GPUs.
%  The speedup mainly comes from reduced data transfer / communication.
\item In the new v7.0.0 release of SuperLU\_DIST, we released the 3D factorization algorithm,
  where MPI ranks are arranged as 3D process grid: Px X Py X Pz.  Pz direction is used
  internally for storing sub-parts of Schur-complement updates. The input \{A, B\} matrices and
  output X matrix need to reside on Px X Py. We implemented a new interface that enables
  redistribution of the users matrices between all MPI ranks and the layer Px X Py.
  The interface is flexible, allows uneven block partition of the user input, and allows separate
  calls to factorization and triangular solves.
\end{itemize}

\ignore{
\vspace{-.13in}
\begin{figure}[htb]
%\begin{minipage}[t]{0.48\columnwidth}
%% \centering
%% \includegraphics[scale=0.7]{projects/2.3.3-MathLibs/2.3.3.07-STRUMPACK-SuperLU/strumpack-Summit.pdf}
%% \caption{STRUMPACK factorization on Summit GPU.}
%% \label{fig:strumpack-parmetis-scaling}
%% \end{minipage}
%% \hfill
%% \begin{minipage}[t]{0.48\columnwidth}
%  \centering
% The following are for an earlier versions of CAR
%\includegraphics[scale=0.8]{projects/2.3.3-MathLibs/2.3.3.07-STRUMPACK-SuperLU/superlu-solve-Summit.pdf}
%\caption{SuperLU solve on Summit GPU.}
%\includegraphics[scale=0.2]{projects/2.3.3-MathLibs/2.3.3.07-STRUMPACK-SuperLU/speedup_SOA.jpg}
% \caption{SuperLU symbolic factorization: GPU speedup over CPU, 13 matrices}
%  on Summit GPU nodes; 13 matrices}
%% \end{minipage}
\end{figure}
} %%%% ignored

%%--------------------------------------

\vspace{-.135in}
\paragraph{Next Steps} Our future efforts will focus on the following areas:
%\textit{Describe what you are working on next.}
%\begin{itemize}
%\item
%%  {\bf (Pieter updates)}
 For STRUMPACK, we will work to improve the performance of the block
 low-rank preconditioner on multi-GPU systems.
% \item
 For SuperLU, we will develop a new GPU-friendly meta-data structure for the sparse U matrix,
 replacing the skyline data structure. That trades increased memory usage for
 parallelism-friendly memory access, and is will particularly helpful to improve
 U-solve performance on GPU.
% \item
 Furthermore, we will apply the GPTune autotuner developed from xSDK4ECP project to conduct comprehensive
 tuning in the parameter space for both STRUMPACK and SuperLU, for the ECP applications and
 on the pre-exascale machines.
% \end{itemize}

%-----------
\ignore{  %%%% from last period ....
\begin{itemize}
\item For STRUMPACK, we will improve the performance of the HSS solve
      routine, add OpenMP and reduce communication. We will implement
      the HOLDR low-rank format.
\item For both STRUMPACK and SuperLU, we will build detailed performance
      models and performance specific code optimizations for the ECP
      applications that use our solvers.
\end{itemize}
} %%%%------ ignored from last period ....

%----------- Oct. 2021, remove FFTX
\ignore{
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% FFTX sub-project %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{\stid{3.07} Sub-project: FFTX} \label{subsubsect:fftx}
\noindent

\paragraph{Overview}

The use of Fast Fourier Transforms (FFTs) span a broad range of DOE science applications, including ones represented in the Exascale applications space.
In the FFTX project (\url{https://github.com/spiralgen/fftx}),
we are developing a new package for supporting FFT applications on exascale architectures. Our approach is based on the following ideas: a C++ high-level API that can express a more complete set of use cases as a composition of operators including FFTs, but also computation of and multiplication by a symbol, and padded inputs / pruned outputs; a toolchain based on the SPIRAL toolset, an open-source toolchain for FFT developed at CMU, that enables the
specialization of the FFT calculation and its surrounding use case calculations (scaling, data layout transformation, marshalling/unmarshalling for communication), using code generation, symbolic analysis, automatic performance tuning, and applications-specific code generation; and a workflow that automates the code generation and integration into the applications software. We are using specific ECP applications and target ECP exascale platforms to provide a focus for this work.

\paragraph{Key Challenges}
There are several challenges to the FFT-based simulations on exascale systems.
\begin{trivlist}
\item
(1) Performance engineering on accelerator-based systems. The traditional approach to FFT calculations is to provide library functions for computing FFTs, with user code to calculate the remaining parts of the algorithm. Such an approach can lead to less than the theoretically maximum performance, specifically due to the larger amounts of data motion due to the coarse data granularity of the library interface. This can be addressed to some extent using a finer-grained interface, but only incompletely, and with code that complicated and difficult to maintain.
\item
(2) Performance portability. High performance is difficult to obtain on a single accelerator-based platform, and the low-level code required to obtain high performance as described in (1) is likely to change as one moves onto different hardware and programming systems.

\item
(3)
The need for an open-source ecosystem. One of the major successes of the FFTW software is that it was open source, and available as a starting point for any FFT-based application. However, FFTW has not been supported since the mid-2000's, and is not being ported to GPUs. In the absence of a new open-source FFT code base, ECP will be entirely dependent on what is provided by the vendors, which is a significant risk to the overall success of the ECP applications that depend on FFTs.
\end{trivlist}

\paragraph{Solution Strategies}
Our approach is based on SPIRAL, an open-source framework for expressing the family of algorithms that includes FFT applications in a high-level notation that can be parsed and represented as nontrivial decompositions of low-level algorithmic fragments (analogous to FFTW codelets). This decomposition can then be transformed into low-level code to be called by the application. The decomposition and code generation is done in a platform-specific fashion for optimal performance, and multiple variants can be generated for the purpose of autotuning.
FFTX is building out from SPIRAL in the following ways.
First, we are developing a C++ API that expresses high-level components of FFT-based algorithms in a mathematically concise fashion. Executing C++ programs written in terms of this interface generates a SPIRAL symbolic representation of these algorithms, which is then transformed by SPIRAL into optimized low-level code. The class of algorithms expressible in the FFTX API (and in the SPIRAL symbolic representation) includes many of the ECP algorithms, such as convolutions of various types, and plane-wave calculations for density functional theory calculations. Second, we are developing novel algorithmic analysis and code generation techniques specific to the requirements of exascale systems, in particular to reduce data footprint and data movement in ways that are impractical, if not impossible, for a human programmer to do. Finally, we are developing an automated workflow for managing the process that goes from an FFTX specification to code generation to compiling and linking to a user's application.

This approach addresses the challenges given above. The ``whole-algorithm'' approach to expressing and generating optimized code for FFT-based algorithms enables optimizations that are not feasible in the classical library approach; for example, fine-grained interleaving of sub-steps in a multidimensional FFT and parts of the symbol calculation in a convolution, or eliminating unused calculations for padded inputs or pruned outputs. The high-level specification of the algorithms through the FFTX API does not change when moving between platforms, this providing performance portability from the application developer's standpoint. Also, other parts of the toolchain are reused across platforms, such as the higher-level stages of the SPIRAL representation. Finally, the entire SPIRAL and FFTX software stack is open source. SPIRAL is publicly available, as will be various FFTX capabilities as they are completed.

\paragraph{Recent Progress}

We have a complete end-to-end FFTX implementation of the PSATD algorithm for solving Maxwell's equations on CPUs, a key component of the ECP WarpX application. This includes: a FFTX API representation of the PSATD algorithm; SPIRAL code generation of c code; and linking to a version of the WarpX ECP application that uses PSATD, including coupling of FFTX and AMReX data representations. We have performed side-by-side comparisons of the results obtained by the standard FFTW-based WarpX implementation, and that obtained from FFTX, and they agree to within roundoff error.
We have also developed strategies for obtaining high-performance on multi-gpu and multi-node subsets of summit.

\paragraph{Next Steps} Our future efforts will focus on the following areas:
\begin{itemize}
\item Deliver high performance on Summit for ECP AD use cases, including plane-wave, PSATD, and periodic convolutions, both on single-GPU and multi-GPU configurations.
\item Code generation for Tulip / Frontier platform, based on the HIP programming tools.
\item Complete release version, documentation for release.
\end{itemize}
} %%%% removed


\documentclass[jou]{apa6}

\usepackage[american]{babel}

\usepackage{csquotes}
\usepackage[style=apa,sortcites=true,sorting=nyt,backend=biber]{biblatex}
\DeclareLanguageMapping{american}{american-apa}
\addbibresource{bibliography.bib}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Discrete Structures
%% The start of RBS stuff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Working internal and external links in PDF
\usepackage{hyperref}
% Extra math symbols in LaTeX
\usepackage{amsmath}
\usepackage{gensymb}
\usepackage{amssymb}
% Enumerations with (a), (b), etc.
\usepackage{enumerate}

\let\OLDitemize\itemize
\renewcommand\itemize{\OLDitemize\addtolength{\itemsep}{-6pt}}

\usepackage{etoolbox}
\makeatletter
\preto{\@verbatim}{\topsep=3pt \partopsep=3pt }
\makeatother

% These sizes redefine APA for A4 paper size
\oddsidemargin 0.0in
\evensidemargin 0.0in
\textwidth 6.27in
\headheight 1.0in
\topmargin -24pt
\headheight 12pt
\headsep 12pt
\textheight 9.19in

\usepackage{xcolor}

\title{Sample Quiz 3}
\author{Discrete Structures, Fall 2020}
\affiliation{RBS}

\leftheader{Discrete Sample Quiz 3}

\abstract{%
}

%\keywords{}

\begin{document}

\twocolumn

\section{Worksheet 3: First Order Logic}

\vspace{6pt}
{\bf Question 1.} {\em Definition.} A Boolean formula is a
{\em Conjunctive Normal Form (CNF)},
if it is a conjunction of one or more clauses,
where a clause is a disjunction of literals. Each literal
is either a variable ($u,v,\ldots$) or its negation ($\neg u, \neg v, \ldots$).

Find the CNF computing the following truth table for Boolean
expression $E(a,b,c)$:\\
\begin{tabular}{ c | c | c | c }
$a$ & $b$ & $c$ & $E(a,b,c)$  \\ \hline
{\tt T} & {\tt T} & {\tt T} & {\tt T} \\ \hline
{\tt T} & {\tt T} & {\tt F} & {\tt F} \\ \hline
{\tt T} & {\tt F} & {\tt T} & {\tt F} \\ \hline
{\tt T} & {\tt F} & {\tt F} & {\tt F} \\ \hline
{\tt F} & {\tt T} & {\tt T} & {\tt T} \\ \hline
{\tt F} & {\tt T} & {\tt F} & {\tt F} \\ \hline
{\tt F} & {\tt F} & {\tt T} & {\tt F} \\ \hline
{\tt F} & {\tt F} & {\tt F} & {\tt T} \\ \hline
\end{tabular}

\vspace{6pt}
{\bf Question 2.} The following CNF is given:
$$E = (a \vee \neg c) \wedge (b \vee \neg b).$$
Find $2$ Boolean expressions equivalent to $E$:\\[3pt]
{\bf (A)} $a \rightarrow \neg b$,\\[3pt]
{\bf (B)} $a \rightarrow c$,\\[3pt]
{\bf (C)} $\neg c \rightarrow \neg a$,\\[3pt]
{\bf (D)} $(a \wedge c) \rightarrow b$,\\[3pt]
{\bf (E)} $c \rightarrow a$,\\[3pt]
{\bf (F)} $a \rightarrow (c \rightarrow b)$,\\[3pt]
{\bf (G)} $\neg a \rightarrow \neg c$.

\vspace{6pt}
{\bf Question 3.} We have six statements about Python programs $p \in \mathcal{P}$
that convert inputs $i \in \mathbb{Z}^{+}$ into results $r \in \mathbb{Z}^{+}$.
A Python program may either loop indefinitely or halt (i.e.\ it eventually stops).

\begin{enumerate}
\item Some programs return the correct result for all possible inputs and
they never loop indefinitely.
\item For any program one can find another program such that it returns
the same result for the same inputs as the first one (or loops indefinitely,
{\color{red} \bf iff} the first program does the same).
\item There is a program that only loops indefinitely for at most finitely many inputs (or maybe none at all),
but for all other inputs it produces the correct result.
\item There is at least one Python program that always halts, and for sufficiently large inputs it produces
the correct result, but it may err for some small-size inputs.
\item For a program to produce a correct result for some input $i$ it is strictly necessary to halt.\\
\item A Python program always produces exactly one result for the given input provided that it halts.
\end{enumerate}

We use these $3$ predicates:\\
$A(p_1,i_2,r_3)$ is true iff
Python program $p_1 \in \mathcal{P}$ receives input $i_2 \in \mathbb{Z}^{+}$ and outputs
result $r_3 \in \mathbb{Z}^{+}$.\\
$H(p_1,i_2)$ is true iff program $p_1 \in \mathcal{P}$ receives input $i_2$ and halts (i.e.\ does not
loop indefinitely).\\
$C(i_1,r_2)$ is true iff for input $i_1$ the correct result is $r_2$.

{\em Note.} Write your answer as a comma-separated list: For example,
{\tt F,E,D,C,B,A} tells that the 1st statement is {\bf (F)}, the 2nd one
is {\bf (E)}, $\ldots$, the last one is {\bf (A)}.

\begin{enumerate}[(A)]
\item ${\displaystyle \forall p \in \mathcal{P}\; \forall i \in \mathbb{Z}^+\; \forall r \in \mathbb{Z}^+,}$\\
${\displaystyle \left( A(p,i,r) \wedge C(i,r) \,\rightarrow\, H(p,i) \right) }$.
\item ${\displaystyle \forall p_1 \in \mathcal{P}\; \exists p_2 \in \mathcal{P}\;
\forall i \in \mathbb{Z}^{+}\; \textcolor{red}{\forall r \in \mathbb{Z}^{+},}}$\\
${\displaystyle \left( (\neg H(p_1,i) \wedge \neg H(p_2,i)) \vee
(A(p_1,i,r) \leftrightarrow A(p_2,i,r)) \right)}$
\item ${\displaystyle \exists p \in \mathcal{P}\; \exists N \in \mathbb{Z}^{+}\;
\forall i \in \mathbb{Z}^{+}\; \textcolor{red}{\exists r \in \mathbb{Z}^{+}},}$\\
${\displaystyle \left( ( i \leq N \wedge \neg H(p,i) ) \vee (A(p,i,r) \wedge C(i,r)) \right)}$.
\item ${\displaystyle \forall p \in \mathcal{P}\; \forall i \in \mathbb{Z}^{+}\; \forall r_1 \in \mathbb{Z}^{+}\;
\forall r_2 \in \mathbb{Z}^{+},}$\\
${\displaystyle \left( H(p,i) \wedge A(p,i,r_1) \wedge  A(p,i,r_2) \,\rightarrow\, r_1 = r_2 \right)}$.
\item ${\displaystyle \exists p \in \mathcal{P}\; \exists N \in \mathbb{Z}^{+}\; \forall i \in \mathbb{Z}^{+}\;
\textcolor{red}{\forall r \in \mathbb{Z}^{+}},}$\\
${\displaystyle \left( H(p,i) \,\wedge\, ( A(p,i,r) \wedge (i > N) \,\rightarrow\, C(i,r) ) \right)}$.
\item ${\displaystyle \exists p \in \mathcal{P}\; \forall i \in \mathbb{Z}^{+}\; \forall r \in \mathbb{Z}^{+},}$\\
${\displaystyle \left( H(p,i) \,\wedge\, (A(p,i,r) \rightarrow C(i,r) \right)}$.
\end{enumerate}

\vspace{10pt}
{\bf Question 4.} There is a set of $4$ students $S = \{ s_1, s_2, s_3, s_4 \}$ and
a set of $2$ chairs $C = \{ c_1, c_2 \}$.
Find, how many such functions $f\,:\,S \rightarrow C$ exist,
how many of them are injective, surjective and bijective.\\
{\em Note.} Your answer should be a comma-separated list of
4 numbers (and 3 commas): {\tt total,injective,surjective,bijective}.

\vspace{10pt}
{\bf Question 5.}
There is a predicate $S(x, y, z)$ defined for triplets
of positive integers,
$S: \mathbb{Z}^{+} \times \mathbb{Z}^{+} \times \mathbb{Z}^{+} \rightarrow \{ \mathtt{T}, \mathtt{F} \}$.
$S(x,y,z)$ is true iff $x \cdot y = z$.\\
Express these statements about positive integers
using only $S(x,y,z)$, Boolean operations and quantifiers.\\
{\em Note.} Please use only the predicate $S(\ldots)$ in your answers,
avoid any other predicates or relations (such as equality, divisibility, etc.).

\begin{enumerate}[(A)]
\item $x/y = z$,
\item $x = 1$,
\item $x = y$,
\item $x$ is divisible by $y$ (i.e. $y \,\mid\, x$).
\item $x$ has odd number of positive divisors.
\item $x$ is not a prime.
\item $x$ is a prime.
\end{enumerate}

\subsection{Answers}

\vspace{6pt}
{\bf Question 1.} Answer:
\begin{align}
 & \textcolor{red}{(\neg a \vee \neg b \vee c)} \wedge
\textcolor{blue}{(\neg a \vee b \vee \neg c)} \wedge
\textcolor{blue}{(\neg a \vee b \vee c)} \;\wedge \nonumber \\
\wedge\; & \textcolor{red}{(a \vee \neg b \vee c)} \wedge
(a \vee b \vee \neg c) \nonumber
\end{align}
Every value {\tt F} in the truth table produces one
clause in this expression. For example $E(\mathtt{T},\mathtt{T},\mathtt{F}) = \mathtt{F}$
is addressed by a disjunction $(\neg a \vee \neg b \vee c)$.

If we combine red and blue clauses, we can rewrite this into a more compact expression,
which is also CNF. Note, that this is not the only way to rewrite:
$$\textcolor{red}{(\neg b \vee c)} \wedge
\textcolor{blue}{(\neg a \vee b)} \wedge
(a \vee b \vee \neg c).$$

\vspace{6pt}
{\bf Question 2.} Answer: {\bf (E)}, {\bf (G)}.\\
$(a \vee \neg c) \wedge (b \vee \neg b) = (a \vee \neg c) \wedge \mathtt{T} = (a \vee \neg c)$.
This is same as $c \rightarrow a$ or the contrapositive variant of the same implication:
$\neg a \rightarrow \neg c$.

\vspace{6pt}
{\bf Question 3.} Answer:\\
\begin{tabular}{|c|c|c|c|c|c|} \hline
1 & 2 & 3 & 4 & 5 & 6 \\ \hline
{\bf (F)} & {\bf (B)} & {\bf (C)} & {\bf (E)} & {\bf (A)} & {\bf (D)} \\ \hline
\end{tabular}

\vspace{3pt}
In {\bf (B)} we should write: the second program loops indefinitely {\bf iff}
the first program does so. If we write {\bf if} instead, it
would mean only one-way conditional, which does not mean
equivalence between the programs $p_1$ and $p_2$, but something more complicated.

In {\bf (B)} you could write $(H(p_1,i) \leftrightarrow H(p_2,i))$
instead of $(\neg H(p_1,i) \wedge \neg H(p_2,i))$ or
even omit any reference to $H(\ldots)$ predicates.
The notation $(H(p_1,i) \leftrightarrow H(p_2,i))$ stresses the fact that $p_1$ and $p_2$ behave in the same way.
But in fact the equivalence $(A(p_1,i,r) \leftrightarrow A(p_2,i,r))$ implicitly
states the fact that $p_1$ and $p_2$ are defined on the same inputs.

Please note that {\bf (B)} should {\bf NOT} have quantifier
 $\textcolor{red}{\exists r \in \mathbb{Z}^{+}}$
(instead of  $\textcolor{red}{\forall r \in \mathbb{Z}^{+}}$), because we need
equivalence for all positive integers $r$. If we only care about the
actual result of $p$ on input $i$, then it is possible to ``cheat'' the logic formula:
pick result $r$ which is impossible for both $p_1$ and $p_2$; then $A(p_1,i,r)$
and $A(p_2,i,r)$ would both be false (and thus equivalent).

In {\bf (C)} one cannot replace $\textcolor{red}{\exists r \in \mathbb{Z}^{+}}$
with $\textcolor{red}{\forall r \in \mathbb{Z}^{+}}$ (as in an earlier draft of this test),
because it does not make sense to ask that a program $p$ on input $i$ produces
{\bf each} positive integer result; and all results turn out to be correct.
(Such a formula may have some useful meaning if predicates $A,H,C$ have different
interpretations, but for Python programs this is technically correct, but
has an absurd meaning: that a given program produces any result whatsoever.)

In {\bf (E)} it is absolutely necessary to write a quantifier
$\textcolor{red}{\forall r \in \mathbb{Z}^{+}}$, because
leaving $r$ as a free variable (without a quantifier) would
mean that the Python program always produces the same result
(the value of $r$). It is not

\vspace{6pt}
{\bf Question 4.} Answer: {\tt 16,0,14,0}\\
Please note that there can be no injections (and therefore also bijections):
students will always collide \textendash{} run to the same chair,
since there are fewer chairs than students.

The total number of functions is $2^4 = 16$. Each student
can choose between $2$ chairs, so it is $2 \times 2 \times 2 \times 2 = 16$.
Moreover, there are only $2$ ``constant'' functions (where all four
students go to $c_1$ or to $c_2$). They are not surjective, because
some chairs stay unoccupied in this case.
All the other $16 - 2 = 14$ functions from $S$ (4 elements) to $C$ (2 elements)
are surjections.

\vspace{6pt}
{\bf Question 5.} Here we write all $7$ statements with predicate $S(x,y,z)$ and quantifiers.

\begin{enumerate}[(A)]
\item $S(z,y,x)$ (or, equivalently, $S(y,z,x)$).
\item $\exists y \in \mathbb{Z}^{+},\; S(x,y,y)$.\\
Use the property: $x = 1$ can multiply with an $y$, and does not increase/decrease. \\
You could also write simply $S(x,x,x)$. Indeed, $x$ is the only
positive integer such that $x \cdot x = x$. (Allowing $x = 0$ would
spoil this, because $0^2 = 0$.)
\item $\exists z \in \mathbb{Z}^{+},\; S(x,z,y) \wedge S(z,z,z)$.\\
So, $x = y$ iff there is a $z = 1$ such that $x \cdot z = y$.
\item $\exists d \in \mathbb{Z}^{+},\; S(y,d,x)$.
\item $\exists y \in \mathbb{Z}^{+},\; S(y,y,x)$.\\
This means that $y^2 = x$ for some $y$;
hence $x$ is a full square and should have odd number of divisors.
\item $\exists y \in \mathbb{Z}^{+}\;\exists z \in \mathbb{Z}^{+},\;(S(y,z,x) \wedge \neg S(y,y,y) \wedge \neg S(z,z,z))$.\\
This means that a non-prime $x$ can be expressed as a product of two positive integers $y,z$,
where neither of them is $1$.)
\item $\forall y \in \mathbb{Z}^{+}\;\forall z \in \mathbb{Z}^{+},\;(\neg S(y,z,x) \vee S(y,y,y) \vee S(z,z,z))$.\\
We apply negation to the previous quantifier formula; all $\exists$ quantifiers turn into $\forall$;
formulas are changed according to De Morgan's laws.
\end{enumerate}

\end{document}


\chapter{\wannier\ as a library}\label{ch:wann-lib}

This is a description of the interface between any external program
and the wannier code. There are two subroutines: \verb#wannier_setup#
and \verb#wannier_run#. Calling \verb#wannier_setup# will return
information required to construct the $M_{mn}^{(\mathbf{k,b})}$
overlaps (Ref.~\cite{marzari-prb97}, Eq.~(25)) and
$A_{mn}^{(\mathbf{k})}=\left\langle
  \psi_{m\mathbf{k}}|g_{n}\right\rangle$ projections
(Ref.~\cite{marzari-prb97}, Eq.~(62); Ref.~\cite{souza-prb01},
Eq.~(22)). Once the overlaps and projection have been computed,
calling \verb#wannier_run# activates the minimisation and plotting
routines in \wannier.

%\section{Dependencies}
%\begin{itemize}
%\item Parameters
%\item IO
%\item Kmesh
%\item Overlap
%\item Wannierise
%\end{itemize}

\section{Subroutines}

\subsection{{\tt wannier\_setup}}

{\noindent \bf \verb#wannier_setup(seed_name,mp_grid,num_kpts,real_lattice,recip_lattice,#\\
\verb#              kpt_latt,num_bands_tot,num_atoms,atom_symbols,atoms_cart,#\\
\verb#              gamma_only,spinors,nntot,nnlist,nncell,num_bands,num_wann,proj_site,#\\
\verb#              proj_l,proj_m,proj_radial,proj_z,proj_x,proj_zona,#\\
\verb#              exclude_bands,proj_s,proj_s_qaxis)#}

\begin{itemize}
\item \verb#character(len=*), intent(in) :: seed_name#\\ The seedname
  of the current calculation.
\item \verb#integer, dimension(3), intent(in) :: mp_grid#\\ The
  dimensions of the {Monkhorst-Pack} k-point grid.
\item \verb#integer, intent(in) :: num_kpts#\\ The number of k-points on
  the {Monkhorst-Pack} grid.
\item \verb#real(kind=dp), dimension(3,3), intent(in) :: real_lattice#\\
  The lattice vectors in Cartesian co-ordinates in units of Angstrom.
\item \verb#real(kind=dp), dimension(3,3), intent(in) :: recip_lattice#\\
  The reciprocal lattice vectors in Cartesian co-ordinates in units of reciprocal Angstrom.
\item
  \verb#real(kind=dp), dimension(3,num_kpts), intent(in) :: kpt_latt#\\
  The positions of the k-points in fractional co-ordinates
  relative to the reciprocal lattice vectors.
\item \verb#integer, intent(in) :: num_bands_tot#\\ The total number of bands in the
first-principles calculation (note: including semi-core states).
\item \verb#integer, intent(in) :: num_atoms#\\ The total number of atoms
  in the system.
\item \verb#character(len=20), dimension(num_atoms),#
      \verb# intent(in) :: atom_symbols#\\ The elemental symbols of
      the atoms.
\item \verb#real(kind=dp), dimension(3,num_atoms),#
      \verb#intent(in) :: atoms_cart#\\ The positions of the atoms in
      Cartesian co-ordinates in Angstrom.
\item \verb#logical, intent(in) :: gamma_only#\\ Set to \texttt{.true.} if the
  underlying electronic structure calculation has been performed with
  only $\Gamma$-point sampling and, hence, if the Bloch eigenstates
  that are used to construct $A_{mn}^{(\mathbf{k})}$ and
  $M_{mn}^{\mathbf{(k,b)}}$ are real.
\item \verb#logical, intent(in) :: spinors#\\ Set to \texttt{.true.} if
  underlying electronic structure calculation has been performed with
  spinor wavefunctions.
\item \verb#integer, intent(out) :: nntot#\\ The
  total number of nearest neighbours for each k-point.
\item \verb#integer, dimension(num_kpts,num_nnmax),#
      \verb# intent(out) :: nnlist#\\
      The list of nearest neighbours for each k-point.
\item \verb#integer,dimension(3,num_kpts,num_nnmax),#
      \verb# intent(out) :: nncell#\\
      The vector, in fractional reciprocal lattice co-ordinates, that
      brings the \verb#nn#$^{\mathrm{th}}$ nearest neighbour of
      k-point \verb#nkp# to its periodic image that
      is needed for computing the overlap
      $M_{mn}^{(\mathbf{k,b})}$.
\item \verb#integer, intent(out) :: num_bands#\\ The number of bands in the
first-principles calculation used to form the overlap matricies (note: excluding eg. semi-core states).
\item \verb#integer, intent(out) :: num_wann#\\ The number of MLWF
  to be extracted.
\item  \verb#real(kind=dp), dimension(3,num_bands_tot), intent(out) :: proj_site# \\
Projection function centre
in crystallographic co-ordinates relative to the direct lattice
vectors.
\item \verb#integer, dimension(num_bands_tot), intent(out) :: proj_l#\\
 $l$  specifies the angular part $\Theta_{lm_{\mathrm{r}}}(\theta,\varphi)$ of the
projection function  (see Tables~\ref{tab:angular}, \ref{tab:hybrids}
and \ref{tab:radial}).
\item \verb#integer, dimension(num_bands_tot), intent(out) :: proj_m#\\
 $m_\mathrm{r}$ specifies the angular part $\Theta_{lm_{\mathrm{r}}}(\theta,\varphi)$, of the
projection function
 (see Tables~\ref{tab:angular}, \ref{tab:hybrids}
and \ref{tab:radial}).
\item \verb#integer, dimension(num_bands_tot), intent(out) :: proj_radial#\\
$\mathrm{r}$ specifies the radial part $R_{\mathrm{r}}(r)$ of the
projection function
(see Tables~\ref{tab:angular}, \ref{tab:hybrids}
and \ref{tab:radial}).
\item  \verb#real(kind=dp), dimension(3,num_bands_tot), intent(out) :: proj_z#\\
Defines the axis from which the polar angle
$\theta$ in spherical polar coordinates is measured. Default is
\verb#0.0 0.0 1.0#.
\item  \verb#real(kind=dp), dimension(3,num_bands_tot), intent(out) :: proj_x#\\
Must be orthogonal to
\verb#z-axis#; default is \verb#1.0 0.0 0.0# or a vector
perpendicular to \verb#proj_z# if \verb#proj_z# is given; defines the
axis from with the azimuthal angle $\varphi$ in spherical polar
coordinates is measured.
\item \verb#real(kind=dp), dimension(num_bands_tot), intent(out) :: proj_zona#\\
The value of $\frac{Z}{a}$ associated
with the radial part of the atomic orbital. Units are in reciprocal
Angstrom.
\item \verb#integer, dimension(num_bands_tot), intent(out) :: exclude_bands#\\
      Kpoints independant list of bands to exclude from the
      calculation of the MLWF (e.g., semi-core states).
\item \verb#integer, dimension(num_bands_tot), optional,intent(out) :: proj_s#\\
'1' or '-1' to denote projection onto up or down spin states
\item  \verb#real(kind=dp), dimension(3,num_bands_tot), intent(out) :: proj_s_qaxisx#\\
Defines the spin quantisation axis in Cartesian coordinates.

\end{itemize}

Conditions:
\begin{itemize}
\cond $\verb#num_kpts# = \verb#mp_grid(1)# \times \verb#mp_grid(2)#
\times \verb#mp_grid(3)#$.
\cond $\verb#num_nnmax# = 12$
\end{itemize}

This subroutine returns the information required to determine the
required overlap elements $M_{mn}^{(\mathbf{k,b})}$ and
projections $A_{mn}^{(\mathbf{k})}$,
i.e., \verb#M_matrix# and \verb#A_matrix#, described in
Section~\ref{wannier_run}.

For the avoidance of doubt, \verb#real_lattice(1,2)# is the
$y-$component of the first lattice vector $\mathbf{A}_{1}$, etc.

The list of nearest neighbours of a particular k-point \verb#nkp# is
given by \verb#nnlist(nkp,1:nntot)#.

Additionally, the parameter \verb#shell_list#
may be specified in the \wannier\ input file.

\subsection{{\tt wannier\_run}} \label{wannier_run}

{\noindent \bf \verb#wannier_run(seed_name,mp_grid,num_kpts,real_lattice,recip_lattice,#\\
\verb#            kpt_latt,num_bands,num_wann,nntot,num_atoms,atom_symbols,#\\
\verb#            atoms_cart,gamma_only,M_matrix_orig,A_matrix,eigenvalues,#\\
\verb#            U_matrix,U_matrix_opt,lwindow,wann_centres,wann_spreads,#\\
\verb#            spread#)}

\begin{itemize}
\item \verb#character(len=*), intent(in) :: seed_name#\\ The seedname
  of the current calculation.
\item \verb#integer, dimension(3), intent(in) :: mp_grid#\\ The
  dimensions of the {Monkhorst-Pack} k-point grid.
\item \verb#integer, intent(in) :: num_kpts#\\ The number of k-points on
  the {Monkhorst-Pack} grid.
\item \verb#real(kind=dp), dimension(3,3),#
      \verb# intent(in) :: real_lattice#\\ The lattice vectors in
      Cartesian co-ordinates in units of Angstrom.
\item \verb#real(kind=dp), dimension(3,3), intent(in) :: recip_lattice#\\
  The reciprical lattice vectors in Cartesian co-ordinates in units of inverse Angstrom.
\item \verb#real(kind=dp), dimension(3,num_kpts),#
      \verb# intent(in) :: kpt_latt#\\ The positions of the k-points in
      fractional co-ordinates relative to the reciprocal lattice
      vectors.
\item \verb#integer, intent(in) :: num_bands#\\ The total number of
      bands to be processed.
\item \verb#integer, intent(in) :: num_wann#\\ The number of MLWF to
  be extracted.
\item \verb#integer, intent(in) :: nntot#\\ The number of
  nearest neighbours for each k-point.
\item \verb#integer, intent(in) :: num_atoms#\\ The total number of atoms
  in the system.
\item \verb#character(len=20), dimension(num_atoms),#
      \verb# intent(in) :: atom_symbols#\\ The elemental symbols of
      the atoms.
\item \verb#real(kind=dp), dimension(3,num_atoms),#
      \verb#intent(in) :: atoms_cart#\\ The positions of the atoms in
      Cartesian co-ordinates in Angstrom.
\item \verb#logical, intent(in) :: gamma_only#\\ Set to \texttt{.true.} if the
  underlying electronic structure calculation has been performed with
  only $\Gamma$-point sampling and, hence, if the Bloch eigenstates
  that are used to construct $A_{mn}^{(\mathbf{k})}$ and
  $M_{mn}^{\mathbf{(k,b)}}$ are real.
\item \verb#complex(kind=dp),#
      \verb# dimension(num_bands,num_bands,nntot,num_kpts),#\\
      \verb#                  intent(in) :: M_matrix#\\
      The matrices of overlaps between neighbouring periodic parts of
      the Bloch eigenstates at each k-point, $M_{mn}^{(\mathbf{(k,b)})}$
      (Ref.~\cite{marzari-prb97}, Eq.~(25)).
\item \verb#complex(kind=dp), dimension(num_bands,num_wann,num_kpts),#\\
      \verb#                  intent(in) :: A_matrix# \\The matrices
      describing the projection of \verb#num_wann# trial orbitals on
      \verb#num_bands# Bloch states at each k-point,
      $A_{mn}^{(\mathbf{k})}$ (Ref.~\cite{marzari-prb97}, Eq.~(62);
      Ref.~\cite{souza-prb01}, Eq.~(22)).
\item \verb#real(kind=dp), dimension(num_bands,num_kpts),#
      \verb#intent(in) :: eigenvalues#\\ The
      eigenvalues $\varepsilon_{n\mathbf{k}}$ corresponding to the
      eigenstates, in eV.
\item \verb#complex(kind=dp), dimension(num_wann,num_wann,num_kpts),#\\
      \verb#                  intent(out) :: U_matrix#\\ The unitary
      matrices at each k-point (Ref.~\cite{marzari-prb97}, Eq.~(59))
\item \verb#complex(kind=dp), dimension(num_bands,num_wann,num_kpts),#\\
      \verb#               optional, intent(out) :: U_matrix_opt#\\ The
      unitary matrices that describe the optimal sub-space at each
      k-point (see Ref.~\cite{souza-prb01}, Section~{\sc IIIa}). The array is
      packed (see below)
\item \verb#logical, dimension(num_bands,num_kpts), optional, intent(out) :: lwindow#\\
       The element \verb#lwindow(nband,nkpt)# is {\tt .true.} if the band
{\tt nband} lies within the outer energy window at kpoint {\tt nkpt}.
\item \verb#real(kind=dp), dimension(3,num_wann), optional, intent(out) :: wann_centres#\\
      The centres of the MLWF in Cartesian co-ordinates in Angstrom.
\item \verb#real(kind=dp), dimension(num_wann), optional, intent(out) :: wann_spreads#\\
      The spread of each MLWF in \AA$^{2}$.
\item \verb#real(kind=dp), dimension(3), optional, intent(out) ::#
      \verb#spread#\\
      The values of $\Omega$, $\Omega_{\mathrm{I}}$ and
      $\tilde{\Omega}$ (Ref.~\cite{marzari-prb97}, Eq.~(13)).
\end{itemize}

Conditions:
\begin{itemize}
\cond $\verb#num_wann# \le \verb#num_bands#$
\cond $\verb#num_kpts# = \verb#mp_grid(1)# \times \verb#mp_grid(2)#
\times \verb#mp_grid(3)#$.
\end{itemize}

If $\verb#num_bands# = \verb#num_wann#$ then \verb#U_matrix_opt# is the identity matrix and
\verb#lwindow=.true.#

For the avoidance of doubt, \verb#real_lattice(1,2)# is the
$y-$component of the first lattice
vector $\mathbf{A}_{1}$, etc.

\begin{eqnarray*}
\verb#M_matrix(m,n,nn,nkp)# & = & \left\langle u_{m\mathbf{k}} |
u_{n\mathbf{k+b}}\right\rangle\\
\verb#A_matrix(m,n,nkp)# & = &
\left\langle \psi_{m\mathbf{k}}|g_{n}\right\rangle\\
\verb#eigenvalues(n,nkp)# &=& \varepsilon_{n\mathbf{k}}
\end{eqnarray*}
where
\begin{eqnarray*}
\mathbf{k} &=&\verb#kpt_latt(1:3,nkp)#\\
\mathbf{k+b}&=& \verb#kpt_latt(1:3,nnlist(nkp,nn))# +
\verb#nncell(1:3,nkp,nn)#
\end{eqnarray*}
and
$\left\{|g_{n}\rangle\right\}$ are a set of initial trial
orbitals. These are
typically atom or bond-centred Gaussians that are modulated by
appropriate spherical harmonics.

Additional parameters should be specified in the \wannier\ input
file.