\chapter{WordRatio View}\label{Appendix_WordRatioOld}
\begin{lstlisting}[
    label=lst:RenamingOldModelsSQL,
    language=SQL,
    caption=SQL script renaming the existing database structures,
    showspaces=false,
    numbers=left,
    numberstyle=\footnotesize,
    commentstyle=\color{gray},
    escapechar=|
 ]
 CREATE VIEW "WordRatio" AS
 SELECT "ArticleId", "Word", "Count", "Title", "FilePath",
       "TotalWords","Article"."PublisherName",
        round("Count"::numeric / "TotalWords"::numeric * 100::numeric, 2) AS "Percent"
 FROM "Article"
          JOIN "Term" ON "ArticleId" = "Article"."Id"
          JOIN "Publisher" ON "Article"."PublisherName"
              = "Publisher"."PublisherName"

 CREATE VIEW "WordRatio" AS
 SELECT "ArticleId", "Word", "Count", "Title", "FilePath",
       "TotalWords","Article"."PublisherName",
        round("Count"::numeric / "TotalWords"::numeric * 100::numeric, 2) AS "Percent"
 FROM "Article"
          JOIN "Term" ON "ArticleId" = "Article"."Id"
          JOIN "Publisher" ON "Article"."PublisherName"
              = "Publisher"."PublisherName"
\end{lstlisting}


\chapter{SELFE Model}
\label{chap:selfe}
\section{Introduction}
\section{SELFE suite of tools}
The \acrfull{selfe} \citep{Zhang08} is a cross-scale 3D shallow water open source hydrodynamic model jointly
developed by \acrfull{cmop} and \acrfull{vims}.

The main variables calculated by SELFE are the elevation of the free surface (stage),
three-dimensional velocity and concentrations of salinity,
temperature and other scalar concentrations (only salinity is considered in this calibration), as well as turbulent quantities. Extensions in the SELFE suite use the flow field to calculate particle trajectories, sediment transport and nutrient availability. The input required by SELFE includes the initial state of the system and boundary time series
 representing fluxes and water surfaces at all the open boundaries.

The underlying computational engine SELFE is a second-generation semi-implicit model sharing some of the
algorithmic background of the \cite{Casulli99} family of models, which also includes UnTRIM and SUNTANS that have been
used before with some success on the Bay. SELFE's predecessor, ELCIRC \citep{Zhang04}, was perhaps the first open source model of this class to receive wide distribution. SELFE was devised to improve the depiction of
bathymetry and salinity plume transport in realtime applications in the Columbia River region.
SELFE shares some code with ELCIRC, but its discretization and solution scheme includes some
innovations that make it more formally accurate. SELFE has also been parallelized and used by groups all over the world on a diverse
variety of high performance computers.

\begin{figure}
	\centering
		\includegraphics[scale=1.0]{image/depth_definition}
	\caption{Definition of bathymetric depth ($h$), elevation ($\eta$) and total depth ($H$) as used in SELFE.}
	\label{fig:depths}
\end{figure}

\section{Formulation}
\input{form_hydro.tex}
\input{form_transport.tex}
%\input{form_turbulence.tex}
\input{form_wvel.tex}

\section{Discretization and data centering}
SELFE uses a triangular unstructured mesh in the horizontal direction and a bathymetry-conforming
hybrid Z-S coordinate mesh \citep{Zhang08} in the vertical.

\subsection{Horizontal mesh}
The horizontal mesh is referred to as {\em unstructured} because the connectivity of the triangles
is general and unconstrained.
Unstructured grids incur some computational overhead because lists of neighbors must be tabulated as input and neighbors
are not adjacent to one another in memory on the computer. The benefit, though, is that it is
easy to represent complex shorelines with a fair amount of accuracy (see, for instance, Figure \ref{fig:hgrid}.

\begin{figure}
	\centering
		\includegraphics[width=\textwidth,clip,trim=3in 0in 2.5in 4.25in]{image/hgrid}
	\caption{Horizontal mesh near Franks Tract.}
	\label{fig:hgrid}
\end{figure}

\begin{figure}
	\centering
		\includegraphics[scale=1.0]{image/ortho}
	\caption{a. Orothogonal triangular mesh. b. Non-orthogonal mesh with some skew.}
	\label{fig:ortho}
\end{figure}

One distinguishing characteristic of the horizontal mesh used in SELFE compared to
semi-implicit models based on finite differences such as UnTRIM or SUNTANS is that the mesh is not
required to be {\em orthogonal} (Figure \ref{fig:ortho}. An orthogonal mesh is one where the edges of the mesh are
perpendicular to the line between the centers of the elements.
For a triangular mesh, the orthogonality requirement leads to triangles that are nearly equilateral,
a shape that enjoys some efficiency properties and nominally leads to higher accuracy even in SELFE. The
problem with orthogonal meshes is that they have traditionally
been expensive to generate, not only in terms of the dollar cost of the software involved
(now lessened by software produced by \cite{Holleman13}) but also
in terms of the tradeoffs they impose with other desirable properties such as conforming to the contours
at the foot of a slope at medium-low resolution.

\begin{figure}
	\centering
		\includegraphics[scale=0.5]{image/vgrid}
	\caption{a. The hybrid coordinate system used in SELFE. S-coordinates are used above the threshold depth $h_s$,
	         while z (stairstepping) coordinates are used below. b. Vertical transect of an SZ mesh.}
	\label{fig:vgrid}
\end{figure}

Generating a good unstructured grid for SELFE requires some guidelines, and we'll elaborate on this in Section (\ref{sec-delta-mesh}).

\subsection{Vertical mesh}
SELFE has a flexible meshing system in the vertical direction, allowing a hybrid
of Z layers below and S coordinates above as shown in Figure \ref{fig:vgrid}.
The Z mesh has levels that are horizontal and is fixed
at prescribed elevations, except for the partial level at the bed. This leads to
a stairstep representation of the boundary as shown. The S coordinates \citep{Song94} are
terrain following, with a constant number of levels between the bed (or uppermost z layer) and the free surface.
The S grid parametrization allows the user to concentrate greater or less
density in the lower or upper boundary layers.  \gls{cmop} did extensive side-by-side
testing of SELFE and ELCIRC, a Z-based model, and the terrain following mesh is one of the factors cited in the improved performance of SELFE.

As we shall describe in Section \ref{sec-delta-mesh}, we felt the Bay-Delta is generally shallow
enough to avoid the $Z$ layers entirely.
The original purpose of the SZ hybrid was to avoid some of the pitfalls associated with topography conforming
meshes particularly on steep bathymetry in deep water, particularly so-called {\em hydrostatic inconsistency} and
the associated issues of inaccuracy in pressure calculations \citep{Shchepetkin05,Haney91}. Subsequent work on several basins, including the Columbia River, indicate that except in particularly steep, deep applications the pressure errors are secondary compared to the benefits of a terrain conforming mesh.

Although we are confident the pure-S approach is the best option available to us between S, Z and SZ,
we have also begun testing a vanishing quasi-sigma vertical coordinate system similar to that described by
\cite{Dukhovskoy09} in which layers disappear gradually in shallower water. Our implementation includes an
enhancement to avoid the stairstepping noted by  \cite{Dukhovskoy09}. This gridding system preserves the advantages
of bathymetry conforming coordinates while reducing pressure errors,
preserving stratification and eliminating some practical issues associated with
over-resolution in shallow water. Such overcrowding of layers in shallow water almost always
occurs upstream if the deeper waters in the Bay are properly resolved).

Regardless of what vertical mesh option is chosen when running SELFE, the primary purpose of the mesh is to define the
locations of the prisms in vertical space, which in the case of S coordinates changes over time with the evolution of
the water surface. This calculation is made once per time step; once that transformation is complete, the
solver is based almost entirely on z coordinates.

\begin{figure}
	\centering
		\includegraphics[scale=1.0]{image/prism}
	\caption{Nomenclature associated with a prism. Note that the term {\em element} is used for
	the 2D horizontal component, and also for integrated quantities involving the entire water column.
	.}
	\label{fig:prism}
\end{figure}

\subsection{Variables and mesh centerings}
Fig \ref{fig:prism} illustrates the nomenclature associated with the staggering scheme and variable locations used in SELFE.
The surface elevation is defined at nodes, horizontal velocity at side (edges of an element) centers and whole levels (tops of prisms), tracers at prism centers (under upwind
or TVD transport schemes), and the vertical velocity at element centroids and whole levels. The staggering of variable enhances numerical stability \citep{Danilov13}. One difference to note between SELFE and other semi-implicit models
such as UnTRIM and SUNTANS is that SELFE calculates both components of velocity $(u,v)$ rather than a single
component normal to the edge. This is not relevant when calculating fluxes, but it avoids certain difficulties associated
with the Coriolis term.

\section{Simulation steps and options}
\subsection{Outline of solution}
Details of the solution steps for the hydrostatic algorithm are given in the SELFE paper \citep{Zhang08}.
Our goal here is only to sketch the algorithm, focusing attention on components that represent important
solver options.

The time advance from step $n$ to step $n+1$ includes the following steps:

\begin{description}
\item[Momentum advection] The advection of momentum is handled using the \gls{elm} method. In an ELM, changes in advection are evaluated along flow paths, which means that characteristic paths have to be {\em backtracked}.
\item[Evaluation of explicit terms] The momentum equation includes some terms that are implicit (the value
over the time step is estimated by a combination of the value at the old time $n$ and the new time $(n+1)$.
An example is friction.
Other terms, notably horizontal viscosity and Coriolis, are
evaluated explicitly using only the value at time $n$. This
step calculates the old time component of the implicit terms and
\item[Depth averaged mass and momentum] The depth-integrated mass and momentum equations are combined into
a single (2D) integral form and solved using the Finite Element Method. This step produces the new water surface
height $\eta^{(n+1)}$.
\item[Horizontal velocity] is calculated algebraic from the momentum equation and new water surface algebraically
\item[Vertical closure] Vertical velocities are inferred from the horizontal ones and mass conservation.
\item[Transport] Salt and temperature are advanced using the velocity field just calculated. These will be used
in the hydrodynamics for density evaluation in the next time step
\item[Turbulence] closure is updated for use in the next time step (on a lagged basis)
\end{description}

\subsection{ELM options}
In SELFE, the momentum advection is {\em always} treated with ELM. The transport equation can be solved using ELM as well, although this is rarely done due to mass conservation issues associated with ELM.

The ELM option treats the advection in an Eulerian-Lagrangian sense. For example, the total derivative of the velocity is approximated as:
\beq
  \frac{D u}{D t} \approx \frac{u^{n+1}-u^*}{\D t}
\eeq
where $u^n$ is the velocity at the new time step and $u^*$ is calculated
by following a fictitious flow particle, starting at a pre-given point $\bs{x}$, backward in time and space
(Figure \ref{fig:backtrack})
\begin{figure}
	\centering
		\includegraphics[scale=1.0]{image/backtrack}
	\caption{Backtracking of a fictitious particle is performed from the ending location at an edge center
	(arrow) to the source (dot).}
	\label{fig:backtrack}
\end{figure}

The particle trajectory is determined by the characteristic equation, which moves the ficticious particle at the
the local (interpolated) velocity from the last time step.
\beq
  \frac{D \bs{x}}{D t}=\bs{u} \label{char}
\eeq

Variants of the method depend on how velocities are interpolated for purposes of backtracking and how
quantities are interpolated at the foot of the characteristic path.

In SELFE, the integration of (\ref{char}) is done using either a simpler backward Euler
or 2nd-order Runge-Kutta scheme. To more closely follow the characteristic line,
the integration time step is sub-divided into smaller steps.  After the foot of the characteristic line is found from (\ref{char}), $u^*$ is then interpolated using a scheme that is independent of
the one used for backtracking. The order of interpolation function
used will determine if the ELM is diffusion (lower-order) or dispersion (higher-order) dominates the
error in the computation. In this project, the choice between lower-order interpolant was treated
as a calibration option.

\subsection{Barotropic vs Baroclinic}
It is common, when speaking of the shallow water equations, to decompose the motion into
the barotropic and baroclinic modes. The barotropic mode is the most fundamental motion,
and is associated with pressure gradients due to  variations in water surface height.
The baroclinic modes are induced by more complex vertical density structure
caused by salt (and temperature) differences.

In SELFE, the baroclinic and barotropic modes are toggled with a single parameter. They differ in that in Baroclinic mode, the contribution of temperature- and salinity-induced density differences is included in the momentum equations. In contrast, in Barotropic mode salt and temperature are (at most) considered passive tracers.
The turbulence closure is still calculated in 3D, but the suppression of turbulence due to stratification is not included.

One common usage pattern with SELFE is to use a sequence of barotropic-baroclinic model runs. The barotropic simulation is used in a preliminary simulation in order to calculate 3D boundary conditions (particulary the velocity) for the subsequent baroclinic analysis. Typically this is done with transport off or even, maximizing speed for the barotropic step and deliberately choosing diffusive model parameter combinations.

We believe the 3D mode can be used profitably for modeling the Delta alone with a boundary at Martinez,
particularly for studies that do not otherwise involve salt transport. The upstream part of the Delta is not stratified enough for baroclinicity to play an important role, and the cost savings of dropping salinity transport
is significant.

\subsection{Transport options}
There are three transport options available in SELFE:
\begin{enumerate}
\item \gls{elm}
\item First order upwind finite volume scheme
\item Higher accuracy \gls{tvd} finite volume scheme based on the scheme of \citet{Casulli05}
\end{enumerate}

We have already remarked that only the finite volume options are normally used. The first order and higher order TVD scheme can be hybridized on one mesh based on region or a depth-based switching criterion, and indeed the stringent \gls{cfl} time step restrictions of the TVD scheme more or less require this in shallow water. For this project, we used depth of 6m as the depth criterion and only used the TVD scheme below the confluence region.

\section{Wetting and drying}
 SELFE does not allow partial wetting and drying, and so the wetting and drying rule
is based on full elements or edges. An element is wet if all
its 3 nodes are wet (based on the total depths there and a threshold minimum
depth specified); otherwise it's dry. Based on this
information, a node is considered wet if and only if at least one of its surrounding
 elements is wet. Similarly, a side is 'wet'  if and only if at least
one of its adjacent elements is wet.

\subsection{Options}
There are two options for calculating wetting and drying at a new time step. The first consists of a simple sweep among all
nodes/sides/elements as described above. The second option is iterative starting from the shoreline position at the previous step.
The rule is applied at all shoreline nodes and adjacent elements and sides and the iteration is used to advance the shoreline from
one step to the next. At the end of iteration, a constant extrapolation scheme is used to 'project' the surface to the next
neighboring dry element. This option is designed for grids with adequate resolution so the inundation process can be tracked
accurately. For other grids, the first option should be used (as in the case of the current project).
\subsection{Implications for gridding}
\label{subsec-wet-dry-grid}
Because SELFE does not allow partial wetting and drying, the user must be careful not to grid the channel bottom too high such that
the entire channel is blocked from flow. In practice, it's best to at least use 2 nodes that are always wet in a channel, and use
extra nodes on either side to capture the wetting and drying process. However, if the other nodes are gridded too high, the side
elements may not be ever activated.

\input{structs.tex}

\section{Mass sources and sinks}
\label{sec-source}
Assuming that the extra momentum from the sources and sinks is negligible,
we accommodate sources through the by adding them to the continuity equation (\ref{cont1}):
\beq
  \eta_t+\nabla \cdot \int_{-h}^\eta \bs{u}  = \sum_m s_m(t)\hat{S}(\bs{x}-\bs{x}_m) \label{cont2}
\eeq
where $s_m$ is the discharge, and $\hat{S}$ is a Dirac delta function defined at a series of points $\bs{x}_m$ (in the model we
assume these are located at element centroids). Note that the transport equation (\ref{tr1}) already accounts for the sources and sinks in the term $\hat{Q}$.

\section{Model-specific sources of error/uncertainty}
  \subsection{Mass conservation}
    SELFE does not explicitly enforce volume conservation (through the continuity equation),
		due to the Galerkin \gls{fem} used in the solver. Mass
conservation for tracers is however enforced with the upwind/TVD schemes, as a consistent treatment is used for the 3D continuity
equation (\ref{3Dcon}) and the transport fluxes.
	\subsection{Vertical closure for flow over topography}
    This error is related to the volume conservation error shown above. The horizontal divergence drives the vertical velocity, which is calculated starting from the bottom b.c. and progressing upward. The mismatch between the calculated vertical
velocity at the surface and the b.c. there is the closure error. The error can be large when the bottom slope is large (e.g., Golden
Gate). Judicious gridding and choice of vertical grid can alleviate this error somewhat.

   Note that even if the volume is perfectly conserved, the vertical velocity may still become too large at the surface due to other
reasons as explained in Wolfram and Fringer (2013).
	\subsection{Shallow water and friction}
    The use of a large bottom friction in shallow areas in SELFE3D can lead to parasitic oscillations due to spurious wetting and
drying. This is particularly the case when the channel is narrow and under-resolved. In this case, the 3D model tends to generate
large vertical shear as the flow is being blocked. Note that SELFE2D does not have this issue as a 2D model cannot allow vertical
shear.
    Obviously this has implication for gridding. A simple work-around is to ramp the friction down in the shallow areas to alleviate
the shear. This approach has worked reasonably well for Bay-Delta domain.
	\subsection{Diffusion-dispersion characteristics}
  SELFE has a myriad of schemes inside. Some schemes are more diffusive than others. An example is the interpolation schemes used in
ELM. Another example is the scheme used to convert side-based velocity from node-based velocity. This can be done using a simple
weighted averaging scheme which is more diffusive, or using the linear conforming or non-conforming shape function inside each
surrounding element before averaging. The latter is more dispersive, and requires a 5-point Shapiro filter to filter out spurious
sub-grid modes.


\section{Abstracting over Sloman's space}

Sloman's space can be envisaged as a literal mathematical space, where every point describes a certain mind. We can see that there is no guarantee that a subspace of human minds and a subspace of artificial minds --- minds born from simple intelligent agents, for example --- will have anything in common mathematically. Certainly, one cannot assert that numerically identical minds exist in both subspaces, as two numerically identical minds would, by definition, occupy the same point in Sloman's space.\par

However, Sloman's space describes the fundamental properties of a mind; emergent phenomena\footnote{Emergent phenomena are generally complex phenomena where the same behaviour can arise from different initial conditions, or entirely different systems. They are often studied in sociotechnical systems research, which analyses systems of interrelated social and technical components working in synchrony.} are unsuitable as dimensions of the space, as they can be affected by many independent variables. Note also that these emergent phenomena can arise in the same way in different minds. Kripke was the first to discuss that a behavioural artifact with the same rigid designator can arise from different minds~\citep{kripke1972naming} --- a simple corollary being that behaviour cannot distinguish different minds, as their properties can converge on the same behaviour.\par

\subsection{Anthropomorphic Algorithms for Specifying Behaviour}

According to Castelfranchi \& Falcone~\citep{CastelfranchiSocialApproach}, trust arises from an assessment of the capability and will of a trusted agent to achieve goals of the trustee. Luhmann, a sociologist, asserts that trust is a form of social risk aversion~\citep{luhmann2000familiarity}, while Deutsch, a psychologist, indicates that trust incorporates utility as well as risk in different ways, expressed as confidence, gambling, masochism and other behavioural tendencies~\citep{deutsch1962cooperation}. Some sociotechnical work attempts to bridge the divide between the sociological and psychological approaches through algorithmic formalism~\citep{Marsh1994FormalisingConcept}.\par

Trust is a well-studied topic with a range of literature to be drawn from. More importantly to the argument at hand, it is an emergent phenomena which manifests in different ways and is born from no clear underlying properties of a mind. However, formalisms of trust --- and how trusting agents behave --- can be found in Castelfranchi and Falcone's work, as well as Marsh's, and plenty of others. One can assert that these formalisms describe an aspect of behaviour in humans (with the exception of some types of minds such as human sociopaths, whose behaviour one might expect to be abnormal). Many formalisms listed are an algorithmic formalisms, meaning that they can be implemented so as to direct the behaviour of an intelligent agent in a more anthropomorphic way. They are therefore the canonical example of the anthropomorphic algorithm, and happen to be the most extensively studied.\par

A given anthropomorphic algorithm wouldn't apply to simply any type of mind: caveats such as sociopaths are to be expected, and so a domain --- a subspace of Sloman's space --- is suitable as a way to limit the scope of the formalism. Trust formalisms could then be seen as algorithms (or ordinary mathematical functions) over a subspace of minds which describe behaviour. However, from existing anthropomorphic algorithms such as trust, we can see that this domain hints toward making Sloman's space more useful philosophically: the domain of a trust formalism such as Marsh's is to apply to not only neuronormative humans, but intelligent agents, also.\par

The mind of an intelligent agent and a human may be markedly different, but they can give rise to the same emergent phenomena. Importantly, the formalisms might manifest in numerically non-identical ways: the way an intelligent agent computes trust is rather different to how the human brain does, even under the same formalism, due to differences in hardware and in implementation detail. However, they conform to the same description of the phenomenon they exhibit --- the formalism --- and should behave in the same way as a result. One might say that the minds trust in \emph{qualitatively identical} ways, because they follow a numerically identical formalism, with differences arising in implementation of the overarching theory.\par

Using anthropomorphic algorithms, then, the philosopher can assert behavioural identity between different types of minds. This abstraction over Sloman's space means that the space's indeterminate structure no longer prevents asserting these identities, precisely because the space --- regardless of structure --- allows for the definition of the domains of formalisms which describe an agent's behaviour.\par

\subsection{Compatibility with Theories of Mind}
To a degree, this thesis depends on non-reductive physicalism: for a behaviour to apply to a domain of minds, there has to be nothing non-physical that affects that behaviour, as this would imply a behaviour cannot be shared by humans and computers. However, that the thesis is compatible with non-reductive physicalism means that it can co-exist with existing literature on theory of mind, and that the theories of mind it relies on are at least partially defined already.\par

Non-reductive physicalism works well as a foundation for the notion that non-biological systems --- such as computers --- might also have minds. For that reason, that fact that the application of anthropomorphic algorithms for behaviour specification works well with non-reductive physicalism helps to present a more whole notion of how a behaviour might arise from a computational system.\par


\par
\section{Driver programs for the {\tt Drand} object}
\label{section:Drand:drivers}
\par
This section contains brief descriptions of the driver programs.
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
testDrand msglvl msgFile distribution param1 param2 seed1 seed2 n
\end{verbatim}
This driver program test the {\tt Drand} random number generator.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
The {\tt distribution} parameter specifies the mode of the object.
If {\tt 1}, the distribution is uniform.
If {\tt 2}, the distribution is normal.
\item
When {\tt distribution = 1}, {\tt param1} is the lower bound for
the interval.
When {\tt distribution = 2}, {\tt param1} is the mean for the
normal distribution.
\item
When {\tt distribution = 1}, {\tt param2} is the upper bound for
the interval.
When {\tt distribution = 2}, {\tt param2} is the variance for the
normal distribution.
\item
{\tt seed1} is the first random number seed.
\item
{\tt seed2} is the second random number seed.
\item
{\tt n} is the length of the vector of random numbers to be
generated.
\end{itemize}
%-----------------------------------------------------------------------
\end{enumerate}


\chapter{Input Parameters}
\label{ch:input}

\newcommand{\param}[5]{{\setlength{\parindent}{0cm} {\ttfamily \bfseries \hypertarget{#1}{#1}}\\{\it Type}: #2\\{\it Default}: #3\\{\it When it matters}: #4\\{\it Meaning}: #5}}
\newcommand{\myhrule}{{\setlength{\parindent}{0cm} \hrulefill }}

\newcommand{\true}{{\ttfamily .true.}}
\newcommand{\false}{{\ttfamily .false.}}

In this section we describe all the parameters which can be included in the input namelist.

\section{General parameters}

\param{general\_option}
{integer}
{1}
{Always}
{Determines the overall flow of program execution.\\

{\ttfamily general\_option} = 1: Compute the current potential for a range of $\lambda$.\\

{\ttfamily general\_option} = 2: Do not compute the current potential, but rather load the current potential computed
by \nescoil~in the file \parlink{nescout\_filename}, compute the $\chi^2_B$ and $\chi^2_K$ for it,
and save results. For this setting, \parlink{Nlambda} will be over-written with the number of
current potential solutions found in the nescout file.\\

{\ttfamily general\_option} = 3: Emulate \nescoil's truncated singular value decomposition (TSVD) solver.
The least-squares problem solved will be minimization of only $\chi^2_B$ (i.e. $\lambda=0$.)
Output quantities will be saved in the same arrays as if $\lambda$ were scanned.
For this setting, \parlink{Nlambda} will be over-written with the number of
singular values.\\

{\ttfamily general\_option} = 4: Search for a value of the regularization weight such that
a certain target is met. The target is chosen using \parlink{target\_option}.
Use this value of {\ttfamily general\_option} for running \regcoil~inside
a fixed-boundary plasma shape optimization, in which case {\ttfamily chi2\_B\_target}
is the objective function you should minimize in the optimization.\\

{\ttfamily general\_option} = 5: Same as 4, except that before the $\lambda$ search is carried out,
the system is solved
for $\lambda=0$ and $\lambda=\infty$ to check whether the current density target is attainable.
Thus, this option takes a little more time than {\ttfamily general\_option}=4 but is more robust.
}

\myhrule

\param{regularization\_term\_option}
{string}
{{\ttfamily "chi2\_K"}}
{Always}
{Determines which term is used for regularization.\\

{\ttfamily regularization\_term\_option = "chi2\_K"}: Use $\chi^2_K$ as the regularization term, as described in the Nuclear Fusion paper.\\

{\ttfamily regularization\_term\_option = "Laplace-Beltrami"}: Use $\int d^2a (\nabla^2 \Phi)^2$ as the regularization term, where the integral is
performed over the coil surface, and $\nabla^2$ is the Laplace-Beltrami operator.

}

\myhrule

\param{nescout\_filename}
{string}
{{\ttfamily ""}}
{Only when \parlink{general\_option}=2.}
{Name of a \nescoil~output file which can be read in for processing.
}

\myhrule

\param{symmetry\_option}
{integer}
{1}
{Always}
{Determines whether stellarator symmetry is imposed.\\

{\ttfamily symmetry\_option} = 1: Force the single-valued part of the current potential
to be odd in $\theta$ and $\zeta$. This option corresponds to stellarator symmetry.\\

{\ttfamily symmetry\_option} = 2: Force the single-valued part of the current potential
to be even in $\theta$ and $\zeta$. I'm not sure why you would ever use this option,
but it is available for completeness.\\

{\ttfamily symmetry\_option} = 3: No symmetry in the current potential is imposed.
}

\myhrule

\param{save\_level}
{integer}
{3}
{Always}
{Option related determining how many variables are saved in the \netCDF~output file.  The larger the value, the smaller the output file.\\

{\ttfamily save\_level} = 0: Save everything.\\

{\ttfamily save\_level} = 1: Do not save the inductance matrix.\\

{\ttfamily save\_level} = 2: Also do not save the matrix $g$.\\

{\ttfamily save\_level} = 3: Also do not save the normal vector or derivatives of the position vector.
}

\myhrule

\param{load\_bnorm}
{logical}
{\false}
{When \parlink{general\_option}=1 or 3.}
{Whether or not an output file from the \bnorm~code is to be loaded.
Set this option to \true~if there is significant current in the plasma,
meaning the coils will need to cancel the associated magnetic field component normal
to the target plasma surface.
}

\myhrule

\param{bnorm\_filename}
{string}
{{\ttfamily ""}}
{When \parlink{general\_option}=1 or 3 and \parlink{load\_bnorm}=\true.}
{Output file from the \bnorm~code which contains the magnetic field normal to the target
plasma surface associated with current inside the plasma.}

\myhrule

\param{net\_poloidal\_current\_Amperes}
{real}
{1.0}
{If \parlink{geometry\_option\_plasma}=0,1, 5 or 7, i.e. if the plasma surface is not a vmec equilibrium.}
{The number of Amperes of current the links the coil winding surface poloidally,
denoted $G$ in \cite{regcoilPaper}. If the plasma surface is obtained from a vmec equilibrium,
then {\ttfamily net\_poloidal\_current\_Amperes} will be determined instead
from the {\ttfamily bvco} value in the vmec wout file.
}

\myhrule

\param{net\_toroidal\_current\_Amperes}
{real}
{0.0}
{Always}
{The number of Amperes of current the links the coil winding surface toroidally,
denoted $I$ in \cite{regcoilPaper}. Unlike the net poloidal current, this number
is never read from a wout file.
}

\section{Resolution parameters}

For any new set of surface geometries you consider, you should vary the resolution parameters in this section to make sure
they are large enough.  These parameters should be large enough that the code results you care about are unchanged under further
resolution increases.

\myhrule

\param{ntheta\_plasma}
{integer}
{64}
{Always}
{Number of grid points in poloidal angle used to evaluate surface integrals on the plasma surface.
Often 64 or 128 is a good value.
It is resonable and common but not mandatory to use the same value for {\ttfamily ntheta\_plasma} and \parlink{ntheta\_coil}.}

\myhrule

\param{ntheta\_coil}
{integer}
{64}
{Always}
{Number of grid points in poloidal angle used to evaluate surface integrals on the coil winding surface.
Often 64 or 128 is a good value.
It is resonable and common but not mandatory to use the same value for \parlink{ntheta\_plasma} and {\ttfamily ntheta\_coil}.}

\myhrule

\param{nzeta\_plasma}
{integer}
{64}
{Always}
{Number of grid points in toroidal angle used to evaluate surface integrals on the plasma surface.
Often 64 or 128 is a good value.
It is resonable and common but not mandatory to use the same value for {\ttfamily nzeta\_plasma} and \parlink{nzeta\_coil}.}

\myhrule

\param{nzeta\_coil}
{integer}
{64}
{Always}
{Number of grid points in toroidal angle used to evaluate surface integrals on the coil winding surface.
Often 64 or 128 is a good value.
It is resonable and common but not mandatory to use the same value for \parlink{nzeta\_plasma} and {\ttfamily nzeta\_coil}.}

\myhrule

\param{mpol\_potential}
{integer}
{12}
{Always}
{Maximum poloidal mode number to include for the single-valued part of the current potential on the coil winding surface.
}

\myhrule

\param{ntor\_potential}
{integer}
{12}
{Always}
{
Maximum toroidal mode number to include for the single-valued part of the current potential on the coil winding surface.
}

\myhrule

\param{mpol\_transform\_refinement}
{real}
{5.0}
{Only when \parlink{geometry\_option\_plasma} is 4.}
{The number of poloidal mode numbers in the \vmec~file will be multiplied by this value
when transforming from the original poloidal angle to the straight-field-line angle.
Since the original \vmec~angle is chosen to minimize the number of Fourier modes required,
more modes are required in any other coordinate.
This parameter affects the time required to compute constant-offset surfaces,
but does not affect the time for other calculations.
}

\myhrule

\param{ntor\_transform\_refinement}
{real}
{1.0}
{Only when \parlink{geometry\_option\_plasma} is 4.}
{The number of toroidal mode numbers in the \vmec~file will be multiplied by this value
when transforming from the original poloidal angle to the straight-field-line angle.
Since the original \vmec~angle is chosen to minimize the number of Fourier modes required,
more modes are required in any other coordinate.
This parameter affects the time required to compute constant-offset surfaces,
but does not affect the time for other calculations.
}

\section{Geometry parameters for the plasma surface}

\param{geometry\_option\_plasma}
{integer}
{0}
{Always}
{This option controls how you specify the shape of the target plasma surface.\\

{\ttfamily geometry\_option\_plasma} = 0: The plasma surface will be a plain circular torus. The major radius will be \parlink{R0\_plasma}.
     The minor radius will be \parlink{a\_plasma}. This option exists just for testing purposes.\\

{\ttfamily geometry\_option\_plasma} = 1: Identical to option 0.\\

{\ttfamily geometry\_option\_plasma} = 2: The plasma surface will be the last surface in the full radial grid of the \vmec~file specified by \parlink{wout\_ilename}.
The poloidal angle used will be the normal \vmec~angle which is not a straight-field-line coordinate.
This is typically the best option to use for working with \vmec~equilibria.\\

{\ttfamily geometry\_option\_plasma} = 3: The plasma surface will be the last surface in the half radial grid of the \vmec~file specified by \parlink{wout\_filename}.
The poloidal angle used will be the normal \vmec~angle which is not a straight-field-line coordinate.
This option exists so that the same flux surface can be used when comparing with {\ttfamily geometry\_option\_plasma} = 4.\\

{\ttfamily geometry\_option\_plasma} = 4: The plasma surface will be the last surface in the half radial grid of the \vmec~file specified by \parlink{wout\_filename}.
The poloidal angle used will be the straight-field-line coordinate, obtained by shifting the normal \vmec~poloidal angle by \vmec's $\lambda$ quantity.
This option exists in order to examine changes when using a different poloidal coordinate compared to {\ttfamily geometry\_option\_plasma} = 3.\\

{\ttfamily geometry\_option\_plasma} = 5: The plasma surface will be the flux surface with normalized poloidal flux
\parlink{efit\_psiN} taken from the {\ttfamily efit} file specified by \parlink{efit\_filename}. \\

{\ttfamily geometry\_option\_plasma} = 6: The plasma surface will be loaded from an ASCII file, specified by \parlink{shape\_filename\_plasma}. The first line of this file is ignored. The second line is an integer giving the number of Fourier modes
to read. The remaining lines contain $m$, $n$, $rmnc$, $zmns$, $rmns$, $zmnc$. \\

{\ttfamily geometry\_option\_plasma} = 7: The plasma surface and Bnorm information will be loaded from an ASCII file in FOCUS format, specified by \parlink{shape\_filename\_plasma}. For more information, please look here \url{https://princetonuniversity.github.io/FOCUS/rdsurf.pdf}.

}

\myhrule

\param{shape\_filename\_plasma}
{string}
{{\ttfamily ""}}
{Only when \parlink{geometry\_option\_plasma} is 6 or 7.}
{ASCII file from which to read in the plasma shape.}

\myhrule

\param{R0\_plasma}
{real}
{10.0}
{Only when \parlink{geometry\_option\_plasma} is 0 or 1.}
{Major radius of the plasma surface, when this surface is a plain circular torus.}

\myhrule

\param{a\_plasma}
{real}
{0.5}
{Only when \parlink{geometry\_option\_plasma} is 0 or 1.}
{Minor radius of the plasma surface, when this surface is a plain circular torus.}

\myhrule

\param{nfp\_imposed}
{integer}
{1}
{Only when \parlink{geometry\_option\_plasma} is 0 or 1.}
{When the plasma surface is a plain circular torus, only toroidal mode numbers that are a multiple of this parameter will be considered.
This parameter thus plays a role like \vmec's {\ttfamily nfp} (number of field periods),
and is used when {\ttfamily nfp} is not already loaded from a \vmec~file.}

\myhrule

\param{wout\_filename}
{string}
{{\ttfamily ""}}
{Only when \parlink{geometry\_option\_plasma} is 2, 3, or 4.}
{Name of the \vmec~{\ttfamily wout} output file which will be used for the plasma surface.
You can use either a \netCDF~or {\ttfamily ASCII} format file.}

\myhrule

\param{efit\_filename}
{string}
{{\ttfamily ""}}
{Only when \parlink{geometry\_option\_plasma} is 5.}
{Name of the {\ttfamily efit} output file which will be used for the plasma surface.}

\myhrule

\param{efit\_psiN}
{real}
{0.98}
{Only when \parlink{geometry\_option\_plasma} is 5.}
{Value of normalized poloidal flux at which to select a flux surface from the {\ttfamily efit} input file.
A value of 1 corresponds to the last closed flux surface, and 0 corresponds to the magnetic axis.}

\myhrule

\param{efit\_num\_modes}
{integer}
{10}
{Only when \parlink{geometry\_option\_plasma} is 5.}
{Controls the number of Fourier modes used to represent $R(\theta)$ and $Z(\theta)$ for the shape of
the plasma surface. Each of these functions will be expanded in a sum of functions $\sin(m\theta)$ and $\cos(m\theta)$,
where $m$ ranges from 0 to {\ttfamily efit\_num\_modes}$-1$.}

\section{Geometry parameters for the coil winding surface}

\param{geometry\_option\_coil}
{integer}
{0}
{Always}
{This option controls which type of geometry is used for the coil surface.\\

{\ttfamily geometry\_option\_coil} = 0: The coil surface will be a plain circular torus. The major radius will be the
same as the plasma surface: either \parlink{R0\_plasma} if \parlink{geometry\_option\_plasma} is 0 or 1, or {\ttfamily Rmajor\_p} from the \vmec~{\ttfamily wout} file
if  \parlink{geometry\_option\_plasma} is 2.
     The minor radius will be \parlink{a\_coil}.\\

{\ttfamily geometry\_option\_coil} = 1: Identical to option 0, except the major radius of the coil surface will be set by \parlink{R0\_coil}.\\

{\ttfamily geometry\_option\_coil} = 2: The coil surface will computing by expanding the plasma surface uniformly by a distance \parlink{separation}. The expanded surface will be saved to a local file specified by \parlink{nescin\_filename}. \\

{\ttfamily geometry\_option\_coil} = 3: The coil surface will be the `coil' surface in the \nescoil~`nescin' input file specified by \parlink{nescin\_filename}. \\

{\ttfamily geometry\_option\_coil} = 4: Similar to option 2, except that the poloidal angle will be changed such that the arclength (with respect to $\theta)$ is independent of $\theta$ at each $\zeta$. The coil surface will computing by expanding the plasma surface uniformly by a distance \parlink{separation}. The expanded surface will be saved to a local file specified by \parlink{nescin\_filename}. \\
}

\myhrule

\param{R0\_coil}
{real}
{10.0}
{Only when \parlink{geometry\_option\_coil} is 1.}
{Major radius of the coil surface, when this surface is a plain circular torus.}

\myhrule

\param{a\_coil}
{real}
{1.0}
{Only when \parlink{geometry\_option\_coil} is 0 or 1.}
{Minor radius of the coil surface, when this surface is a plain circular torus.}

\myhrule

\param{separation}
{real}
{0.2}
{Only when \parlink{geometry\_option\_coil} is 2.}
{Amount by which the coil surface is offset from the plasma surface.}

\myhrule

\param{nescin\_filename}
{string}
{{\ttfamily "nescin.out"}}
{Only when \parlink{geometry\_option\_coil} is 2 (write to) or 3 (read from).}
{Name of a {\ttfamily nescin} file, of the sort used with the \nescoil~code.
If \parlink{geometry\_option\_coil}=3, the coil surface from
this file will be used as the coil surface for \regcoil.
If \parlink{geometry\_option\_coil}=2, \regcoil~will save the uniform-offset surface it computes
into a file with this name.}

\myhrule

\param{mpol\_coil\_filter}
{integer}
{24}
{Only when \parlink{geometry\_option\_coil} is 2, 3, or 4.}
{Terms in the Fourier series for $R(\theta,\zeta)$ and $Z(\theta,\zeta)$ describing the coil winding surface will be dropped if the poloidal mode number is larger than {\ttfamily mpol\_coil\_filter}.}

\myhrule

\param{ntor\_coil\_filter}
{integer}
{24}
{Only when \parlink{geometry\_option\_coil} is 2, 3, or 4.}
{Terms in the Fourier series for $R(\theta,\zeta)$ and $Z(\theta,\zeta)$ describing the coil winding surface will be dropped if the toroidal mode number is larger than {\ttfamily ntor\_coil\_filter}. Specify 1, 2, 3, $\ldots$ rather than {\ttfamily nfp}, 2$\times${\ttfamily nfp}, 3$\times${\ttfamily nfp}, etc.}

\section{Parameters related to the regularization weight}

\param{Nlambda}
{integer}
{4}
{Only when \parlink{general\_option} = 1, 4, or 5.}
{When \parlink{general\_option}=1, {\ttfamily Nlambda} is the number of values of $\lambda$ for which the problem is solved.
When \parlink{general\_option}=4 or 5, {\ttfamily Nlambda} is the upper limit on the number of values of $\lambda$ for which the problem is solved.}

\myhrule

\param{lambda\_max}
{real}
{1.0e-13}
{Only when \parlink{general\_option} = 1.}
{Maximum value of $\lambda$ for which the problem is solved.}

\myhrule

\param{lambda\_min}
{real}
{1.0e-19}
{Only when \parlink{general\_option} = 1.}
{Minimum nonzero value of $\lambda$ for which the problem is solved.
Note that the problem is always solved for $\lambda=0$ in addition to
the nonzero values.}

\myhrule

\param{target\_option}
{string}
{{\ttfamily "max\_K"}}
{Only when \parlink{general\_option} = 4 or 5.}
{Controls which quantity is targeted to determine $\lambda$:\\

{\ttfamily target\_option = "max\_K"}: Search for the $\lambda$ value such that the maximum
current density over the winding surface equals \parlink{target\_value}.\\

{\ttfamily target\_option = "chi2\_K"}: Search for the $\lambda$ value such that $\chi^2_K$ equals \parlink{target\_value}.\\

{\ttfamily target\_option = "rms\_K"}: Search for the $\lambda$ value such that the root-mean-square current density
$\left( \int d^2a\; K^2 \right)^{1/2}$ (where the integral is over the current winding surface) equals \parlink{target\_value}.\\

{\ttfamily target\_option = "max\_Bnormal"}: Search for the $\lambda$ value such that the maximum
$\vect{B}\cdot\vect{n}$ over the plasma surface equals \parlink{target\_value}.\\

{\ttfamily target\_option = "chi2\_B"}: Search for the $\lambda$ value such that $\chi^2_B$ equals \parlink{target\_value}.\\

{\ttfamily target\_option = "rms\_Bnormal"}: Search for the $\lambda$ value such that the root-mean-square value of $\vect{B}\cdot\vect{n}$, i.e.
$\left( \int d^2a\; B_n^2 \right)^{1/2}$ (where the integral is over the plasma surface) equals \parlink{target\_value}.

{\ttfamily target\_option = "max\_K\_lse"}: Search for the $\lambda$ value such that $K_{\max,\text{lse}}$ (the maximum approximated using the log-sum-exponent norm) equals \parlink{target\_value}.
\begin{gather}
K_{\max,\text{lse}} = \frac{1}{\texttt{target\_option\_p}} \log \left( \frac{\int_{\text{coil}} d^2 A \exp \left( \texttt{target\_option\_p}K \right)}{A_{\text{coil}}} \right)
\end{gather}
See \parlink{target\_option\_p}.

{\ttfamily target\_option = "lp\_norm\_K"}: Search for the $\lambda$ value such that $|| \bm{K} ||_p$ ( the $L^p$ norm of $K$) equals \parlink{target\_value}.
\begin{gather}
|| {\bm{K}} ||_p = \left( \frac{\int_{\text{coil}} d^2 A \, K^{\texttt{target\_option\_p}} }{A_{\text{coil}}} \right)^{1/p}
\end{gather}
See \parlink{target\_option\_p}.

}

\myhrule

\param{target\_option\_p}
{real}
{4.0}
{Only when \parlink{target\_option} = {\ttfamily "lp\_norm\_K"} or {\ttfamily "max\_K\_lse"}.}
{The value of $p$ used for the $L^p$ norm or log-sum-exponent norm of $K$.}

\myhrule

\param{target\_value}
{real}
{8.0e6}
{Only when \parlink{general\_option} = 4 or 5.}
{The value of the quantity specified by \parlink{target\_option} that the code will attempt to match
by varying $\lambda$.
}

\myhrule

\param{lambda\_search\_tolerance}
{real}
{1.0e-5}
{Only when \parlink{general\_option} = 4 or 5.}
{Relative tolerance for the lambda root-finding.}

\myhrule

\section{Parameters related to adjoint solve}

\param{sensitivity\_option}
{integer}
{1}
{Only when one wishes to compute derivatives of output quantities with respect to the coil winding surface parameters. Note that {\ttfamily sensitivity\_option > 1} must be used with \parlink{general\_option} = 1, 4, or 5. {\ttfamily sensitivity\_option = 3, 4, 5} should give the same results, although 4 or 5 tend to be more efficient. }
{\\
{\ttfamily sensitivity\_option = 1}: Derivatives are not computed. \\
{\ttfamily sensitivity\_option = 2}: Derivative of $\chi^2$ is computed. \\
{\ttfamily sensitivity\_option = 3}: Derivatives of $\chi^2_K$, $\chi^2_B$, and $\chi^2$ are computed. This requires two adjoint solves. \\
{\ttfamily sensitivity\_option = 4}: Derivatives of $\chi^2_K$, $\chi^2_B$, and $\chi^2$ are computed. An adjoint solve is used to compute the derivative of $\chi^2_K$ and the derivative of $\chi^2_B$ is computed from it. This requires one adjoint solve. \\
{\ttfamily sensitivity\_option = 5}: Derivatives of $\chi^2_K$, $\chi^2_B$, and $\chi^2$ are computed. An adjoint solve is used to compute the derivative of $\chi^2_B$ and the derivative of $\chi^2_K$ is computed from it. This requires one adjoint solve.
}

\myhrule

\param{fixed\_norm\_sensitivity\_option}
{logical}
{false}
{When \parlink{sensitivity\_option} $> 1$.}
{If true, derivatives of $\chi^2$, $\chi^2_B$, and $\chi^2_K$ are computed at fixed target (indicated by \parlink{target\_option}) rather than at fixed $\lambda$. This option must be used with \parlink{general\_option} $> 3$ and \parlink{target\_option} = \texttt{"chi2\_B"}, \texttt{"lp\_norm\_K"} or \texttt{"max\_K\_lse"}.}

\myhrule

\param{sensitivity\_symmetry\_option}
{integer}
{1}
{Symmetry assumed when computing derivative with respect to coil geometry parameters. This does not need to be the same as \parlink{symmetry\_option}.}
{\\
{\ttfamily sensitivity\_symmetry\_option = 1}: Only compute derivatives with respect to $r_{mn}^c$ and $z_{mn}^s$ of the winding surface using the \texttt{NESCIN} convention. This option corresponds to stellarator symmetry. \\
{\ttfamily sensitivity\_symmetry\_option = 2}: Only compute derivatives with respect to $r_{mn}^s$ and $z_{mn}^c$ of the winding surface using the \texttt{NESCIN} convention. \\
{\ttfamily sensitivity\_symmetry\_option = 3}: No symmetry in the winding surface is imposed.}

\myhrule

\param{nmax\_sensitivity}
{integer}
{1}
{When \parlink{sensitivity\_option} $> 1$.}
{Derivatives of $\chi^2$, $\chi^2_B$, and $\chi^2_K$ are computed with respect to winding surface Fourier modes with $\abs{n} \leq$ \texttt{nmax\_sensitivity}.}

\myhrule

\param{mmax\_sensitivity}
{integer}
{1}
{When \parlink{sensitivity\_option} $> 1$.}
{Derivatives of $\chi^2$, $\chi^2_B$, and $\chi^2_K$ are computed with respect to winding surface Fourier modes with $\abs{m} \leq$ \texttt{mmax\_sensitivity}.}

\myhrule

\param{coil\_plasma\_dist\_lse\_p}
{real}
{1.0d4}
{When \parlink{sensitivity\_option}$> 1$.}
{If \parlink{sensitivity\_option} $> 1$, the derivative of the log-sum-exponent approximation to the coil-plasma distance will be computed. The value of \texttt{coil\_plasma\_dist\_lse\_p} determines the scaling, $p$, in the exponent for this form of the distance approximation.
\begin{gather}
d_{\min,\text{lse}} = - \frac{1}{p} \log \left( \frac{ \int_{\text{coil}} d^2 A \int_{\text{plasma}} d^2 A \, \exp \left( - p \sqrt{ (\bm{r}_{\text{coil}}- \bm{r}_{\text{plasma}})^2} \right)}{A_{\text{coil}} A_{\text{plasma}}} \right)
\end{gather}
 }

\myhrule


\section{Type inference}
\label{appendix:infer}

\begin{figure*}[tbp]
  \centering
  \input{infer/kinds}
  \caption{Kind inference rules -- $\inferK{(C,\unif)}{{\inP\E}}{{\inP\tau}}{k}$}
  \label{rules:kinding}
\end{figure*}

\begin{figure*}[!tbp]
  \input{infer/typing}
  \caption{Type inference rules --
    $\inferW{\Sigma}{(C,\psi)}{{\inP\E}}{{\inP e}}{\tau}$ }
  \label{rules:typing:full}
\end{figure*}

In this appendix, we provide the complete type inference rules
and show that our type inference algorithm is sound and complete.
The constraints rules are already shown in \cref{inference}.
Kind inference is presented in \cref{rules:kinding:full}
and the detailed treatment of let-bindings in
\cref{infer:let}.
The type inference rules are shown in \cref{rules:typing:full}.
The various theorems and their proofs are direct adaptations
of the equivalent statements for \hmx \citep{sulzmann1997proofs}.

\subsection{Kind inference}
\label{rules:kinding:full}

We write $\inferK{(C,\unif)}{{\inP\E}}{{\inP\tau}}{k}$ when type $\tau$ has kind $k$
in environment $\E$ under constraints $C$ and unifier $\unif$.
$\inP\E$ and $\inP\tau$ are the input parameters of
our inference procedure.
We present the kind inference algorithm as a set of rules in
\cref{rules:kinding}.
Higher-kinds are not generally supported
and can only appear by looking-up the kind scheme of a type constructor,
for use in the type application rule {\sc KApp}.
Type variables must be of a simple kind in rule {\sc KVar}.
Kind schemes are instantiated in the {\sc KVar} rules by creating
fresh kind variables and the associated substitution.
{\sc KArr} and {\sc KBorrow} simply returns the kind of the primitive
arrow and borrow types.
The $\operatorname{normalize}$ function is used every time several constraints
must be composed in order to simplify the constraint and return a most general
unifier.

\subsection{Generalization and constraints}
\label{infer:let}

% So far, constraints have only been composed of a list of kind inequalities.
% The internal language of constraints used for inference is in fact
% richer.
% To illustrate this, we show the inference rule for let-bindings
% in \cref{rule:infer:let}.
The {\sc Let} rule combines several ingredients previously seen:
since let expressions are binders, we use $\Weaken$ on the bound
identifier $x$. Since let-expressions contain
two subexpressions, we use the environment splitting relation,
$\bsplit{C_s}{\Sv}{\Sv_1}{(\Sv_2 \Sdel{x})}$. We remove the $x$ from
the right environment, since it is not available outside of the expression
$e_2$, and should not be part of the returned usage environment.

As per tradition in ML languages, generalization is performed
on let-bindings.
Following \hmx, we write $(C_\schm, \schm) = \generalize{C}{\E}{\tau}$
for the pair of a constraint and a scheme resulting from
generalization. The definition is provided in \cref{rule:infer:let}.
The type scheme $\schm$ is created by quantifying over all the appropriate
free variables and the current constraints.
The generated constraint $C_\schm$ uses a new projection operator,
$\Cproj{x}{D}$ where $x$ can be either a type or a kind variable, which
allow the creation of local variables inside the constraints.
This allows us to encapsulate all the quantified variables in the global constraints.
It also reflects the fact that there
should exist at least one solution for $C$ for the scheme to be valid.
\citet{DBLP:journals/tapos/OderskySW99} give a detailed account
on the projection operators in HM inference.

% \begin{figure}[tp]
%   \centering
%   \begin{mathpar}

%     % \inferrule{
%     %   \inferK{C \Cand C_x} \E \tau {k'} \\
%     %   D = C \Cand C_x \Cand \Cleq{k'}k
%     % }{
%     %   \E \vdash \Cleq{\forall \kvar_i \forall (\tvar_j:k_j).\ \qual{C_x}{\tau}}{k} \Crewrite  D
%     % }
%   \end{mathpar}
%   \caption{Auxiliary rules for inference}
%   \label{op:usgmap}
% \end{figure}

\input{infer/metatheory}

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


%% !TEX root = manual.tex

\section{Fixed-Time Quanta Charts}

\label{sec:tutorials:ftq}

\begin{figure}[h!]
\centering
\includegraphics[width=0.6\textwidth]{figures/matplotlib/ftq/pic1024.png}
\caption{Application Activity (Fixed-Time Quanta; FTQ) histogram}
\label{fig:ftq}
\end{figure}

Another way of visualizing application activity is a fixed-time quanta (FTQ) chart.
While the call graph gives a very detailed profile of what critical code regions, they lack temporal information.
Figure \ref{fig:ftq} displays the proportion of time spent by ranks in MPI communication and computation in a PIC trace replay with respect to simulation time.
After running, two new files appear in the folder: \inlineshell{<fileroot>_app1.py} and \inlineshell{<fileroot>_app1.dat} that can use Python's matplotlib to generate plots.
Previously, plots were generated using Gnuplot, but this has been deprecated in favor of much more aesthetically pleasing maplotlib output.

\begin{ShellCmd}
your_project # python output_app1.py --help
usage: output_app1.py [-h] [--show] [--title TITLE] [--eps] [--pdf] [--png]
                      [--svg]

optional arguments:
  -h, --help     show this help message and exit
  --show         display the plot on screen
  --title TITLE  set the title
  --eps          output .eps file
  --pdf          output .pdf file
  --png          output .png file
  --svg          output .svg file
\end{ShellCmd}

Generating the histogram requires matplotlib, and visualizing the histogram interactively with \inlineshell{--show} requires a screen or X11 forwarding.
FTQ aggregates tags into tunable time "epochs".
An epoch states the ratio of each tag represented at a point in time.
Larger epochs will smooth the graph and decrease the quantity of data required to render a plot; while a smaller epoc will add more detail, at the risk of making the plot excessively volatile.

SST/macro activates FTQ for a given application as:

\begin{ViFile}
node {
 app1 {
  name = sstmac_mpi_testall
  launch_cmd = aprun -n 8 -N 2
  ftq {
   type = ftq_calendar
   epoch_length = 1ms
   output = ftq
   group = app1
  }
  print_times = false
  message_size = 400B
 }
}
\end{ViFile}
where the \inlinefile{fileroot} a path and a file name prefix.


\input{../header_class}

%---------- start document ---------- %
 \section{poly.multiutil -- utilities for multivariate polynomials}\linkedzero{poly.multiutil}
 \begin{itemize}
   \item {\bf Classes}
     \begin{itemize}
     \item \linkingone{poly.multiutil}{RingPolynomial}
     \item \linkingone{poly.multiutil}{DomainPolynomial}
     \item \linkingone{poly.multiutil}{UniqueFactorizationDomainPolynomial}
     \item OrderProvider
     \item NestProvider
     \item PseudoDivisionProvider
     \item GcdProvider
     \item RingElementProvider
     \end{itemize}
   \item {\bf Functions}
     \begin{itemize}
     \item \linkingone{poly.multiutil}{polynomial}
     \end{itemize}
 \end{itemize}

\C

 \subsection{RingPolynomial}\linkedone{poly.multiutil}{RingPolynomial}
 General polynomial with commutative ring coefficients.

 \initialize
   \func{RingPolynomial}{%
    \hiki{coefficients}{terminit},\ %
    **\hiki{keywords}{dict}}{\out{RingPolynomial}}\\
  \spacing
  % document of basic document
  \quad The \param{keywords} must include:
  \begin{description}
  \item[coeffring] a commutative ring ({\it CommutativeRing})
  \item[number\_of\_variables] the number of variables({\it integer})
  \item[order] term order ({\it TermOrder})
  \end{description}
  \quad This class inherits \linkingone{poly.multivar}{BasicPolynomial},
  \linkingone{poly.multiutil}{OrderProvider},
  \linkingone{poly.multiutil}{NestProvider} and
  \linkingone{poly.multiutil}{RingElementProvider}.
%
  \begin{at}
    \item[order]\linkedtwo{poly.multiutil}{RingPolynomial}{order}:\\
      term order.
  \end{at}
%
  \method
  \subsubsection{getRing}\linkedtwo{poly.multiutil}{RingPolynomial}{getRing}
  \func{getRing}{\param{self}}{\out{Ring}}\\
  \spacing
  \quad Return an object of a subclass of {\tt Ring},
  to which the polynomial belongs.\\
  (This method overrides the definition in RingElementProvider)

  \subsubsection{getCoefficientRing}\linkedtwo{poly.multiutil}{RingPolynomial}{getCoefficientRing}
  \func{getCoefficientRing}{\param{self}}{\out{Ring}}\\
  \spacing
  \quad Return an object of a subclass of {\tt Ring},
  to which the all coefficients belong.\\
  (This method overrides the definition in RingElementProvider)

  \subsubsection{leading\_variable}\linkedtwo{poly.multiutil}{RingPolynomial}{leading\_variable}
  \func{leading\_variable}{\param{self}}{\out{integer}}\\
  \spacing
  \quad Return the position of the leading variable
  (the leading term among all total degree one terms).\\
  The leading term varies with term orders, so does the result. The
  term order can be specified via the attribute {\tt order}.\\
  (This method is inherited from NestProvider)

  \subsubsection{nest}\linkedtwo{poly.multiutil}{RingPolynomial}{nest}
  \func{nest}{\param{self},\ \hiki{outer}{integer},\ \hiki{coeffring}{CommutativeRing}}{\out{polynomial}}\\
  \spacing
  \quad Nest the polynomial by extracting \param{outer} variable
  at the given position.\\
  (This method is inherited from NestProvider)

  \subsubsection{unnest}\linkedtwo{poly.multiutil}{RingPolynomial}{unnest}
  \func{nest}{\param{self},\ \hiki{q}{polynomial},\ \hiki{outer}{integer},\ \hiki{coeffring}{CommutativeRing}}{\out{polynomial}}\\
  \spacing
  \quad Unnest the nested polynomial \param{q} by inserting \param{outer}
  variable at the given position.\\
  (This method is inherited from NestProvider)

 \subsection{DomainPolynomial}\linkedone{poly.multiutil}{DomainPolynomial}
 Polynomial with domain coefficients.
 \initialize
   \func{DomainPolynomial}{%
    \hiki{coefficients}{terminit},\ %
    **\hiki{keywords}{dict}}{\out{DomainPolynomial}}\\
  \spacing
  % document of basic document
  \quad The \param{keywords} must include:
  \begin{description}
  \item[coeffring] a commutative ring ({\it CommutativeRing})
  \item[number\_of\_variables] the number of variables({\it integer})
  \item[order] term order ({\it TermOrder})
  \end{description}
  \quad This class inherits \linkingone{poly.multiutil}{RingPolynomial} and
  \linkingone{poly.multiutil}{PseudoDivisionProvider}.
%
  \begin{op}
    \verb+f / g+ & division (result is a rational function)\\
  \end{op}
  \method

  \subsubsection{pseudo\_divmod}\linkedtwo{poly.multiutil}{DomainPolynomial}{pseudo\_divmod}
  \func{pseudo\_divmod}{\param{self},\ \hiki{other}{polynomial}}{\out{polynomial}}\\
  \spacing
  \quad Return \(Q\), \(R\) polynomials such that:
  \[d^{deg(self) - deg(other) + 1} self = other \times Q + R\]
  w.r.t. a fixed variable, where \(d\) is the leading coefficient of
  \param{other}.\\
  \quad The leading coefficient varies with term orders,
  so does the result. The term order can be specified via
  the attribute {\tt order}.\\
  (This method is inherited from PseudoDivisionProvider.)

  \subsubsection{pseudo\_floordiv}\linkedtwo{poly.multiutil}{DomainPolynomial}{pseudo\_floordiv}
  \func{pseudo\_floordiv}{\param{self},\ \hiki{other}{polynomial}}{\out{polynomial}}\\
  \spacing
  \quad Return a polynomial \(Q\) such that
  \[d^{deg(self) - deg(other) + 1} self = other \times Q + R\]
  w.r.t. a fixed variable, where \(d\) is the leading coefficient of
  \param{other} and \(R\) is a polynomial.\\

  The leading coefficient varies with term orders, so does the result.
  The term order can be specified via the attribute {\tt order}.\\
  (This method is inherited from PseudoDivisionProvider.)

  \subsubsection{pseudo\_mod}\linkedtwo{poly.multiutil}{DomainPolynomial}{pseudo\_mod}
  \func{pseudo\_mod}{\param{self},\ \hiki{other}{polynomial}}{\out{polynomial}}\\
  \quad Return a polynomial \(R\) such that
  \[ d^{deg(self) - deg(other) + 1} \times self = other \times Q + R\]
  where \(d\) is the leading coefficient of \param{other} and \(Q\)
  a polynomial.\\
  \quad The leading coefficient varies with term orders,
  so does the result. The term order can be specified via
  the attribute {\tt order}.\\
  (This method is inherited from PseudoDivisionProvider.)

  \subsubsection{exact\_division}\linkedtwo{poly.multiutil}{DomainPolynomial}{exact\_division}
  \func{exact\_division}{\param{self},\ \hiki{other}{polynomial}}{\out{polynomial}}\\
  \spacing
  \quad Return quotient of exact division.\\
  (This method is inherited from PseudoDivisionProvider.)

 \subsection{UniqueFactorizationDomainPolynomial}\linkedone{poly.multiutil}{UniqueFactorizationDomainPolynomial}
 Polynomial with unique factorization domain (UFD) coefficients.
 \initialize
   \func{UniqueFactorizationDomainPolynomial}{%
    \hiki{coefficients}{terminit},\ %
    **\hiki{keywords}{dict}}{\out{UniqueFactorizationDomainPolynomial}}\\
  \spacing
  % document of basic document
  \quad The \param{keywords} must include:
  \begin{description}
  \item[coeffring] a commutative ring ({\it CommutativeRing})
  \item[number\_of\_variables] the number of variables({\it integer})
  \item[order] term order ({\it TermOrder})
  \end{description}
  \quad This class inherits \linkingone{poly.multiutil}{DomainPolynomial} and
  \linkingone{poly.multiutil}{GcdProvider}.
  \method
  \subsubsection{gcd}\linkedtwo{poly.multiutil}{UniqueFactorizationDomainPolynomial}{gcd}
  \func{gcd}{\param{self},\ \hiki{other}{polynomial}}{\out{polynomial}}\\
  \quad Return gcd. The nested polynomials' gcd is used.\\
  (This method is inherited from GcdProvider.)

  \subsubsection{resultant}\linkedtwo{poly.multiutil}{UniqueFactorizationDomainPolynomial}{resultant}
  \func{resultant}{\param{self},\ \hiki{other}{polynomial},\ \hiki{var}{integer}}{\out{polynomial}}\\
  \quad Return resultant of two polynomials of the same ring,
  with respect to the variable specified by its position \param{var}.

% Functions
 \subsection{polynomial -- factory function for various polynomials}\linkedone{poly.multiutil}{polynomial}
  \func{polynomial}{\hiki{coefficients}{terminit},\ \hiki{coeffring}{CommutativeRing}, \hikiopt{number\_of\_variables}{integer}{None}}{\out{polynomial}}\\
   \spacing
   % document of basic document
   \quad Return a polynomial.\\
   \spacing
   \quad \negok One can override the way to choose a polynomial type
   from a coefficient ring, by setting:\\
   {\tt special\_ring\_table[coeffring\_type] = polynomial\_type}\\
   before the function call.

 \subsection{prepare\_indeterminates -- simultaneous declarations of indeterminates}\linkedone{poly.multiutil}{prepare\_indeterminates}
 \func{prepare\_indeterminates}{\hiki{names}{string},\ \hiki{ctx}{dict},\ %
   \hikiopt{coeffring}{CoefficientRing}{None}}{\out{None}}\\
 \spacing
 \quad From space separated \param{names} of indeterminates, prepare variables
 representing the indeterminates.  The result will be stored in \param{ctx}
 dictionary.\\
 \quad The variables should be prepared at once, otherwise wrong aliases of
 variables may confuse you in later calculation.\\
 \quad If an optional \param{coeffring} is not given, indeterminates will be
 initialized as integer coefficient polynomials.\\

\begin{ex}
>>> prepare_indeterminates("X Y Z", globals())
>>> Y
UniqueFactorizationDomainPolynomial({(0, 1, 0): 1})
\end{ex}
\C

%---------- end document ---------- %

\input{../footer}


\documentclass{article}
\usepackage{algpseudocode}
\usepackage{amsmath}
\usepackage{latexsym}
\usepackage[super]{nth}
\title{MeshAdapt}
\author{Dan Ibanez}
\date{Jun 16, 2015}
\begin{document}

\maketitle

\section{Coarsening}

Garimella outlines conditions for an
edge collapse to be valid, which have since then been refined
into the following four conditions:

\begin{enumerate}
\item If the vertices are classified on equal order model entities,
then both vertices and the edge must have the same classification.
\item If the vertices are classified on different orders, then
the vertex to be collapsed and the edge must be classified on
the higher-order entity.
\item If there exists a ring of three edges containing the
collapsing edge, there must exist a face bounded by this ring.
The non-collapsing edge adjacent to the collapsing vertex
must have the same classification as this face.
\item If there exist two edge-adjacent faces that connect
the vertices, those faces and the edge must bound a tet.
The face adjacent to the collapsing vertex must
have the same classification as this tet.
\end{enumerate}

The last two conditions can be checked by identifying the generalized
"ring" cases and using findUpward in the 2D case or a specialized
search on the adjacent regions of a face in the 3D case.

For condition 4, here referred to as the face ring condition,
it is useful to optimize the procedure since a naive implementation
compares adjacent faces of one vertex to another, performing $n^2$
comparisons where $n$ is the number of faces adjacent to a vertex.
$n$ is on average 30 and can be as high as 78 as measured in some tet
meshes, and this has been measured as the bottleneck in the current
coarsening procedure.

De Cougny outlines an algorithm for identifying the independent set
of vertices to not collapse in order to maintain a decent vertex
distribution:
\begin{algorithmic}
\For{$d \in [0..n_{sd}]$}
\For{$v \sqsubset G^d_j$}
\State $v \in S$
\For{$e \in v\{M^1\}$}
\If{$e \in E_{\text{collapse}}$}
\State $v_2 = (e\{M^0\})\setminus v$
\If{$v_2\in S$}
\If{$(v\sqsubset g)\land(v_2\sqsubset\bar{g})$}
\State $v\not\in S$
\EndIf
\EndIf
\EndIf
\EndFor
\EndFor
\EndFor
\end{algorithmic}
Basically, given a target vertex, if another vertex is adjacent via
a collapsing edge and the other vertex is classified on the closure
of the classification of the target, then the target is not placed
in the set.

Which is just another way of stating the definition of vertices to
collapse as defined by conditions 1 and 2
described by Garimella.

In fact, we can use those conditions to more efficiently compute the
set by avoiding the check $v_2\sqsubset\bar{g}$, which requires checking
for classification on the closure of a model entity $g$, which may be
expensive (model adjacency counts are not bounded in any way).

If we first reverse the problem and choose to only identify vertices
not in the independent set $v\in\bar{S}$ (i.e. vertices which we intend to collapse),
then the algorithm can proceed as follows:
\begin{enumerate}

\item All vertices are implicitly assumed to be in $S$, $\bar{S}$ is empty.

\item Identify candidate edges and vertices for collapsing based on the initial
criteria (a mesh size field) and Garimella's first 2 conditions.
If the edge satisfies condition 1, both vertices have equal classification and are on the closures
of one another's classifications, and both are placed in $\bar{S}$ tentatively.
If the edge satisfies condition 2, only the vertex with higher order classification
is a candidate and the non-candidate is clearly on the closure of the candidate.
The candidate is placed in $\bar{S}$.

\item Run the modified graph algorithm as follows:
\begin{algorithmic}
\For{$d \in [0..n_{sd}]$}
\For{$\{v|v\in\bar{S}, \sqsubset G^d_j\}$}
\State {remove $v$ from $\bar{S}$}
\For{$e \in v\{M^1\}$}
\If{$e \in E_{\text{collapse}}$}
\State $v_2 = (e\{M^0\})\setminus v$
\If{$v_2\not\in\bar{S}$}
\State {put $v$ back in $\bar{S}$}
\EndIf
\EndIf
\EndFor
\EndFor
\EndFor
\end{algorithmic}
\end{enumerate}

Note that the independent set algorithm can be most simply expressed as:
mark a vertex as illegal to collapse unless doing so would prevent a marked
edge from collapsing.
By the end of the procedure, every vertex which is legal to collapse is required
for some particular edge to collapse.

In order to prevent confusion about which edge collapse is associated with a vertex
to collapse, we coarsen one geometric dimension at a time, starting with model edges.
The topological, classification, and independent set routines operate only over
edges and vertices classified on model entities of dimension $d$, where $d$ increases from 1.

Garimella's conditions 3 and 4 must be checked right before executing the collapse,
since nearby edge collapses can affect the outcome of these topological checks.

Collapsing an edge involves two sets of elements: the set of elements to collapse
and the set of elements to keep.
The set of elements to collapse are those adjacent to the edge to collapse,
and the set of elements to keep are those adjacent to the vertex to collapse
but not to the edge to collapse.
To collapse an edge, the elements to keep are first reconstructed by with
the vertex to collapse replaced by the vertex to keep.
Care must be taken to exactly duplicate the geometric classification of
entities as they are reconstructed.
After that reconstruction, the elements to collapse are removed, taking
with them the edge and vertex to collapse.

Before an edge is collapsed, a final check is performed to ensure no invalid
elements will be created.
Since the mesh is straight-sided, the check temporarily moves the vertex to
collapse onto the vertex to keep and then checks the resulting volumes of the elements to keep.

All three steps of coarsening: initial checks, independent set finding, and collapsing
operate on a single geometric model dimension using the cavity operator
framework provided in APF.
For the initial checks, the cavity includes all elements adjacent to both
vertices of the edge.
For independent set, the cavity is the elements around a vertex.
Finally, an edge collapse requires all elements adjacent to the vertex to collapse.

\section{Refinement}

A single step of refinement is run as follows:
\begin{enumerate}
\item select edges to split
\item for each dimension, split entities of that dimension
by just creating new entities,
classifying those new entities the same as the parent being split
and performing solution transfer.
\item link the edge split vertices based on the remote
copies of their parent edges.
\item invoke the refinement templates on all mesh entities,
one dimension at a time from edges up to regions.
\item remove all old entities that have been split
\item link all other remote copies based on the remote copies
of vertices
\end{enumerate}

The majority of the complexity in refinement is the use of
whole-entity refinement templates as opposed to individual
edge splits.
Refinement is well-defined for simplex meshes, and
templates exist for triangular faces and tetrahedra.
In general, for a simplex, there is one template for
each rotationally unique combination of split/unsplit edges.
The total number of combinations is $2^e$ for a simplex
with $e$ edges.
The number of rotationally unique combinations is smaller:
3 for triangles and 12 for tetrahedra.

We first define lookup tables from the full set of combinations
into the rotationally unique ones.
To form a lookup table, we encode a combination as an integer
in $[0..2^e-1]$ using binary numbers where each bit represents
the state of one edge.
These are called edge codes.
A set of codes representing the rotationally unique combinations
is chosen as the set of canonical edge codes.
The lookup table maps all edge codes to a rotation and a
canonical edge code.

Rotation itself is a key tool for implementing refinement templates,
and rotation functions and their properties are at the heart of
the system.

Also at the center of the code's simplicity is the representation
of all domains as a set of vertices, and manipulating only
vertex sets.
This is supported by a set of entity creation functions that
accept vertex sets and recursively construct the closure
of the entity, using existing entities if possible.

Given that all domains are represented by a set of vertices,
we need to know the geometry of each domain and provide
rotation functions for the geometries of interest.

The usefulness of all this becomes apparent when templates
are decomposed into sub-problems, where a sub-problem may
involve tetrahedronizing a subspace of the parent tetrahedron
that is shaped like a pyramid or a prism or an octahedron
whose bounding vertices are known.
This delegation to sub-problems shortens the code, which
greatly improves maintainability and reduces the probability
of programming errors.

It also allows more advanced decisions, such as choosing
the shortest edge when triangulating a quad or an octahedron,
to be represented by one function for all cases.

\section{Size Field}

The size field is a \nth{2}-order tensor field over the mesh.
It is meant to indicate the anisotropic desired fineness or
coarseness of discretization along a particular direction
at any point in space.

One way to interpret the size field is as a generalization of the dot product.
Where a vector $v$ at a particular point $p$ in space would have
been measured as $v\cdot v$ (not dependent on $p$), it is now
measured using the metric tensor $T(p)$ at $p$: $vT(p)v^T$.

Another interpretation is to decompose the metric tensor into
the product of a transformation matrix times itself: $T=QQ^T$.
One can then see that the metric measures a transformed vector
$v'=vQ$: $vTv^T=vQQ^Tv^T=v'(v')^T=v'\cdot v'$.

The transformation $Q$ can be further decomposed into a rotation $R$
and scaling $S$:
\[Q=RS,
R=\begin{bmatrix}
e_1 & e_2 & e_3
\end{bmatrix},
S=\begin{bmatrix}
\frac{1}{h_0} & 0 & 0 \\
0 & \frac{1}{h_1} & 0 \\
0 & 0 & \frac{1}{h_2} \\
\end{bmatrix}\]
Where $e_1,e_2,e_3$ are the principal axes of the transformed
space expressed as real space unit vectors and
$h_0,h_1,h_2$ are the desired edge lengths along each
principal axis.

The main complexity with this definition is that we have a non-trivial
metric tensor that varies depending on position in real space, which
makes measuring objects in real space using this metric field somewhat
difficult.

Algorithms in MeshAdapt are mainly interested in the length of edges
in metric space and the volume of elements in metric space.
There exists a generalized definition of volume called a measure,
which is currently computed as follows:

\[V=\int_{\Omega^e} |J(\xi)|\]

In particular, $|J(\xi)|=d\Omega^e$ is the determinant of the Jacobian $J=x_{,\xi}$.
Since we are interested in measuring edges (1D elements embedded in 3D)
and faces (2D elements embedded in 3D), then $J$ sometimes has zero rows
and $|J|$ is a more specialized computation that takes into account
the dimension of the element.
Regardless of dimension, $J$ represents the differential tangent vectors
along the element's local coordinates, and transforming them into the
metric space before taking the determinant is an simple way to obtain
differential volume in the metric space:

\[V'=\int_{\Omega^e} |J(\xi)Q(\xi)|\]

Both real and metric space measures are computed using Gaussian quadrature:

\[V'=\sum_{l=1}^{\text{nint}} |J(\xi_l)Q(\xi_l)|\]

If the metric field is encoded as a \nth{2}-order tensor $Q(x)$ distributed
over the mesh as a nodal field, then the existing framework for interpolation
of $Q$ and performing quadrature are leveraged to easily measure any
mesh entity in the metric space.

\end{document}


% !TeX root = /main.tex
% !TeX spellcheck = en_GB

\chapter{Abstract}
\label{sec:Abstract}
This project has had the aim to create a real time auto tuner for use on stage during live performances.
The scope was narrowed to get a better understanding of the necessary steps, and the end result focuses on creating a pitch shifter.
Starting with shifting only a single sine and presenting thoughts on a model which could be used to determine a complete tone.

A Matlab model based on determining the Instantaneous Frequency using the Hilbert Transform and generating a new sine has been created.

The Instantaneous Frequency finder has been implemented on the ADSP-BF533 using the CrossCore framework and the real time aspect of the issue has been tested.
A single sine input frequency can be determined and a new one generated in a maximum of \SI{3.21}{\milli\second}.