\chapter{Theory}
\label{sec:theory}

\section{Design Load Cases (DLCs)}
The user must specify the metocean conditions that drive the wind and
wave loads upon the floating substructure.  \textit{FloatingSE}
currently only uses the single load case of maximum thrust coincident
with maximum wave loading to drive the substructure design. The
assumption is that this load case would be the driver for substructure
sizing and stability.  Ideally, multiple DLCs and metocean conditions
would be used for design optimization.  The capability to optimize over
multiple DLCs will be added to future versions of the model.  By not
currently including a formal set of IEC DLCs, the conceptual designs
derived in this work should be considered preliminary and subject to
extensive revision once other load cases, and higher-fidelity analysis,
is brought to bear.

\section{Load Path}
As with other WISDEM models, the primary simplification in
\textit{FloatingSE} is the treatment of all loads as pseudo-static. This
approximation significantly reduces computational time and resources,
since an accurate calculation of dynamic loads requires more
sophisticated numerical tools and simulations.  However, dynamic effects
can still dominate drive component sizing for floating platforms, thus
the static loading assumption gives a rough approximation of the total
loading.  Furthermore, fatigue effects and structural lifetime estimates
are also excluded for now, but could be incorporated in future
developments.

A floating wind turbine undergoes loading from a number of sources.  The
primary loading source for the tower comes from the aerodynamic loads
induced by the rotor. The substructure must resist the combination of
both rotor loads and hydrodynamics loads, with the latter becoming more
and more important as water depth and wave heights increase.
\textit{FloatingSE}, together with other WISDEM modules, accounts for
these two dominant load sources, as well as the self-loading of gravity
loads.  Other sources of loading, such as installation loads, accidental
loads, vortex-induced vibrations, ice, and seismic loads are ignored.

\subsection{Wind and Wave Loads}
Wind drag loads are applied to the tower body and the upper part of the
substructure that extends above the waterline.  They are not applied to
connecting truss members that may be part of the substructure geometry.
These drag loads are computed assuming the tower and columns are smooth
circular cross-sections and that the drag coefficient can be selected as
a function of the flow Reynolds number \citep{Roshko}.  The aerodynamic
drag force is a function of height, since the wind profile and
cross-sectional geometry varies along that dimension.  For the wind
profile, the standard power-law scaling is used,
\begin{equation}
  U_a(z) = U_{ref}\left(\frac{z}{z_{ref}}\right)^{\alpha}\quad,
\end{equation}
where $U_a(z)$ is the wind velocity as a function of height, $U_{ref}$ is a
reference wind speed measured at a reference height, $z_{ref}$, and
$\alpha$ is the shear exponent used in the power-law approximation of
wind profiles.  The wind profile then feeds the aerodynamic drag,
Reynolds number, and drag coefficient,
\begin{equation} \label{eqn:drag}
  dF(z) = \frac{1}{2} \rho_a U_a^2(z) d(z) c_d(Re) dz;\qquad
  Re_d = \frac{\rho_a U_a(z) d(z)}{\mu_a}\quad,
\end{equation}
where $Re_d$ is the Reynolds number based on diameter, $\rho_a$ and
$\mu_a$ are the density and viscosity of air, $d(z)$ is the diameter of
the column as a function of height, $c_d$ is the 2-D drag coefficient, and
$dF(z)$ is the force per unit length in the z-direction.

Wave drag loads arise from similar processes, but are computed using
Morison's equation, a semi-empirical expression that predicts the total
hydrodynamic loads.  It is comprised of two components, one for viscous
drag contributions and another for inertial effects (which includes
incident, diffracted, and radiated wave effects).  For flow past
structures with circular cross sections, Morison's equation for force
per unit length ($dF(z)$) takes the form,
\begin{equation} \label{eqn:morison}
  dF(z) = \frac{\pi d^2(z)}{4} \rho_w C_m \dot{U}_w(z)dz + \frac{1}{2} \rho_w U_w^2(z) d(z) c_d(Re)dz\quad,
\end{equation}
where $C_m$ is the added mass coefficient (assumed to be $C_m=2$),
$U_w(z)$ is the current speed as a function of height, $\dot{U}_w(z)$ is
the acceleration as a function of height, and the Reynolds number is
computed by substituting in the appropriate properties for water,
\begin{equation}
Re_d = \frac{\rho_w U_w(z) d(z)}{\mu_w}\quad.
\end{equation}

To compute Morison's equation, expressions for local fluid velocity and
acceleration are required.  Wave particle velocity (not the same as the bulk
velocity of the wave) is assumed to follow linear (Airy) wave theory
\begin{equation} \label{eqn:Uwave}
U_w(z) = a\omega\frac{\cosh\left[\kappa\left(z + D \right)\right]}{\sinh\left(\kappa D\right)}\cosh\left(\kappa x -
  \omega t\right);
\qquad \omega=\frac{2\pi}{T} = \sqrt{ g \kappa \tanh\left(\kappa
    D\right) } \quad,
\end{equation}
where $\omega$ is the circular frequency, $T$ is the wave period, $a$ is
the wave amplitude (half of the significant wave height), $D$ is the
total water depth, $g$ is the acceleration of gravity, and $\kappa$ is
the wave number numerically computed from the dispersion relationship
given as the last expression in Equation \ref{eqn:Uwave}.  Note that the
horizontal particle velocity varies in time and space (by the
$\kappa x - \omega t$) term.  Thus, the individual particles in the wave
are also accelerating at different rates,
\begin{equation} \label{eqn:Awave}
\dot{U}_w(z) = a\omega^2\frac{\cosh\left[\kappa\left(z + D \right)\right]}{\sinh\left(\kappa D\right)}\sinh\left(\kappa x -
  \omega t\right)\quad.
\end{equation}
For
simplicity, \textit{FloatingSE} only considers the maximum velocity and
acceleration at a given height, and makes a conservative assumption that
they are concurrent in time and space.  This essentially means ignoring the
$\kappa x - \omega t$ term, since the maximum of any hyperbolic sine or cosine
term is one.

\subsection{Rotor Nacelle Assembly (RNA) Loads}
From a quasi-steady-state point of view, the RNA loads reduce to three
forces and three moments along the main coordinate axes
\citep{JacketSE}. The thrust is the biggest force responsible for the
bending moment distribution along the tower and loads on the
substructure.  There is the additional effect of the gravitational load
caused by the offset of the RNA center of mass from the tower
centerline.  This effect is more pronounced for downwind turbines than
upwind turbines, but is included regardless.  \textit{FloatingSE} does
not compute the force and moment components directly, but rather accepts
them as inputs from other WISDEM modules or from the user directly.

\section{Structural Analysis}
The analysis tool, Frame3DD, is an open-source tool for static and
dynamic structural analysis of 2-D and 3-D frames and trusses with
elastic and geometric stiffness. It computes the static deflections,
reactions, internal element forces, natural frequencies, and modal
shapes using direct stiffness and mass assembly \citep{frame3dd}.  The
WISDEM toolkit developed a python interface, \textit{pyFrame3DD}, to
avoid the use of intermediate input and output text files.  The
integration of all loads happens within Frame3DD, where the whole floating
turbine load path, from the rotor to the keel of the substructure, is
modeled with Timoshenko frame elements \citep{timoshenko}.

\subsection{Discretization}
For the finite element structural analysis of the substructure, the
discretization of the main columns into a handful of sections is still
too coarse to capture the appropriate physics. Long slender components,
such as the tower and substructure columns, are broken up into a
three-times finer discretization than the physical cans that they are
actually made of.  The sectional and nodal variables are re-sampled at
this finer spacing.  These additional discretization points give greater
resolution of internal forces and natural frequencies.  Substructure
pontoons are represented as single frame elements.  Frame elements are
described by their cross sectional properties (area, moments of inertia,
modulus of elasticity, and mass density) and starting and ending nodes.
For simple geometries, such as pontoons with tubular cross sections,
these properties are straightforward calculations.  For the turbine
tower, tubular cross section properties are also used, albeit at a finer
discretization.  For substructure columns, it is assumed that the
permanent or variable ballast and bulkheads are not load-bearing, so
tubular cross section properties are also used to represent the column
shell.  However, the material mass density of the frame element is
scaled to reflect the true mass of the whole section, including ballast,
to ensure that gravity loads are captured correctly.

For the tubular cross sections, the critical properties needed by
Frame3DD given user inputs of diameter, $d$, and tube (or wall)
thickness, $t$, are,
\begin{align*}
  \textrm{Outer radius, } r_o &= d/2\\
  \textrm{Inner radius, } r_i &= r_o - t\\
  \textrm{Material area, } A &= \pi \left( r_o^2 - r_i^2 \right)\\
  \textrm{Bending second moment of area, } I_{xx} &= I_{yy} = \frac{\pi}{4}\left( r_o^4 - r_i^4 \right)\\
  \textrm{Torsion second moment of area, } I_{zz} &= J_0 = I_{xx} + I_{yy}\\
  \textrm{Shear area, } A_{s} &= A / \left[ 1.124235 + 0.055610\left(\frac{r_i}{r_o}\right) +
           1.097134\left(\frac{r_i}{r_o}\right)^2 - 0.630057\left(\frac{r_i}{r_o}\right)^3 \right]\\
  \textrm{Bending modulus, } S &= I_{xx} / r_o \\
  \textrm{Torsion modulus (shear constant), } C &= I_{zz} / r_o
\end{align*}
Note that the shear area expression is an empirical relationship as
opposed to an analytical expression.

\begin{figure}[htb]
  \begin{center}
    \includegraphics[width=2in]{figs/frameCS.pdf}
    \caption{Coordinate system for frame element forces.}
    \label{fig:frameCS}
  \end{center}
\end{figure}

\subsection{Loads}
All of the loads described above are integrated together within
Frame3DD.  These loads include,
\begin{itemize}
\item Rotor-nacelle-assembly loads (thrust, moments, etc)
\item Mooring line force
\item Wind and wave loading
\item Gravity loads (weight distribution)
\item Hydrostatic pressure loads, including buoyancy
\end{itemize}

The forces, moments, and mass properties of the rotor-nacelle assembly
(RNA) are inputs to \textit{FloatingSE} (mass properties are assumed to
be relative to the tower top position).  It assumed that the RNA is a
rigid body with respect to the tower modes and the mass properties,
forces, and moments, are applied to the corresponding node in the model.
The forces along each mooring line are applied to the connection
point nodes on the structure.  The wind and wave forces per unit length
in Equations \ref{eqn:drag} and \ref{eqn:morison} are applied as
trapezoidally varying loads along the column elements.  Other loads
applied to the structure include the gravity loads, and the buoyancy
acting on the submerged elements.

\subsection{Boundary Conditions}
Multiple boundary conditions are applied to the structure.  The mooring
system stiffness matrix (linearized about the neutral position) is
applied at the mooring connection nodes.  However, even with the mooring
stiffness, the finite element analysis would otherwise still regard the
structure as unrestrained and incapable of supporting any static loads.
Thus, in order to successfully compute stress and buckling limits in a
well-posed problem, an additional rigid boundary condition (in all 6
DOF) is imposed at the bottom node of the main column.

\subsection{Outputs}
Structural analysis outputs include mass properties of the structure,
member stresses, and summary forces and moments on the body.  Mass
properties include the total mass of the floating turbine and the mass
of the substructure itself.  The calculations also allow for easy
computation of the center of mass of the structure (not accounting for
variable ballast) and the center of buoyancy (centroid of the submerged
volume).  The first two natural frequencies of the structure are also
computed to compare against the range of standard wave frequencies and
rotor passing frequencies (1P and 3P).  Next, the reaction forces and
moments at the boundary node at the keel are taken as the total loading
on the structure.  These are used later in the static stability
calculations to ensure that the mooring lines provide adequate restoring
force and moment.  Finally, the axial and shear forces within each frame
element are extracted and converted to stresses using cross-sectional
properties. These element member follow the sign convention in Figure
\ref{fig:frameCS},
\begin{align*}
  \sigma_z &= \frac{N_z}{A} - \frac{\sqrt{M_x^2 + M_y^2}}{S}\\
  \tau_{z\theta} &= \frac{T_z}{C} + \frac{\sqrt{V_x^2 + V_y^2}}{A_s}
\end{align*}
where $N$ is the axial force (tension or compression), $T$ is the
torsional moment, $V$ is the shear force, $M$ is the bending moment,
$\sigma_z$ is the axial stress, and $\tau_{z\theta}$ is the shear
stress across axial and hoop principle directions.

Hoop stress of the tower is estimated from the dynamic pressure of the
wind loads using the Eurocode method \citep{Eurocode}.  Hoop stress of the submerged
columns is determined using the dynamic and static pressure heads of the
water.
\begin{align}
  \sigma_{\theta,Euro} &= k_w q_{max} \frac{d-t}{2t};\qquad q_{max} =
                         \frac{1}{2}\rho_a U_a^2\\
  \sigma_{\theta,hydro} &= \left(q_{max}+p_{hydro}\right) \frac{d-t}{2t};\qquad q_{max} =
                          \frac{1}{2}\rho_w U_w^2\\
  p_{hydro} &= \rho_w g \left( a\frac{\cosh\left[\kappa\left(z + D \right)\right]}{\cosh\left(\kappa D\right)} - z\right)
\end{align}
where $\sigma_{\theta}$ is the hoop stress, $q_{max}$ is the maximum
dynamic pressure on a cross-section, and $p_{hydro}$ is the hydrostatic
pressure with contributions from wave motion and the static head.  In
the Eurocode method, $k_w$ is the dynamic pressure factor for hoop
stress calculation using cylinder dimensions and an external pressure
buckling factor.  Note that the argument, $(z)$, was dropped from many
of the terms without losing generality.

\subsection{Code Compliance as Utilizations}
Once the stress components of all structural members are computed, they
are compared against design code standards for compliance, and serve as
design constraints when conducting optimization.  Multiple code
standards are used across all components.  For all columns, the tower,
and substructure pontoons, stress components (axial, shear, and hoop)
are combined into a von Mises, equivalent, stress,
\begin{equation}
  \sigma_{vm} = \sqrt{\sigma_a^2 + \sigma_{\theta}^2 -
    \sigma_a\sigma_{\theta} + 3\tau_{a\theta}^2}
\end{equation}
where $\sigma_{vm}$ is the von Mises stress, $\sigma_a$ is the axial
stress, $\tau_{a\theta}$ is the shear stress across axial and hoop
principle directions.  and $\sigma_{\theta}$ is chosen as the relevant
hoop stress.  The von Mises stress is compared against the yield stress,
$\sigma_y$, and a safety factor as a utilization criterion.

Main column, offset column, and tower segment stresses and geometry are
also evaluated against a shell buckling criterion published by
\citet{Eurocode} and a global buckling criterion published by
\citet{Germanischer}.  Note that the implementation of the Eurocode
buckling is modified slightly so as to produce continuously
differentiable output.  See \citet{JacketSE} for a more detailed
exposition.

For submerged columns, additional code standard utilization ratios are
taken from the \citet{api2U}, Bulletin 2U (specifically the procedure
outlined in Appendix B).  These standards also apply shell and general
buckling criterion with a margin of safety in a manner that accounts for
stiffeners and the common buckling modes of submerged structures.
Future efforts will also apply Bulletin 2V, the standards for plates, to
the legs that support taut mooring lines.

\section{Mooring Lines}
The quasi-steady mooring system analysis is handled by the external
Mooring Analysis Program (MAP++) library \citep{MAP}, which has
convenient Python bindings to access the simulation output, bundled into
the WISDEM \textit{pyMAP} module. MAP++ is designed to model the
steady-state forces on a Multi-Segmented, Quasi-Static (MSQS) mooring
line. Seabed contact, seabed friction, and multi-element mooring lines
with arbitrary connection configurations can be analyzed.  MAP++ inputs
include sea depth, geometry descriptions of the mooring line
connections, and material properties of the lines.  For chain and
rope-based cables, these material properties are not easily derived and
would be typically provided by a manufacturer.  We borrow from the
approach of the popular Orcina OrcaFlex software \citep{orca} and use
the following expressions,
\begin{align*}
MBL &= 2.74\times 10^7  d^2 \left(44 - 80d\right) \,[\unit{N}] \\
mass &= 19.9\times 10^3 d^2 \,[\unit{kg/m}]\\
A &= 2\left(\pi d^2 / 4 \right)\,[\unit{m^2}]\\
EA &= 8.54\times 10^{10} d^2\,[\unit{N}]\\
cost &= 3.415\times 10^4 d^2 \,[\unit{USD}]
\end{align*}
where $MBL$ is minimum breaking load, $d$ is the diameter of a single
half-chain link, $A$ is the chain cross-sectional area, $E$ is the
Young's modulus, $EA$ is the axial stiffness.  When conducting
optimization, the expression for $MBL$ is poorly posed due to its limited
range of diameter applicability, so a linear fit is used instead,
\begin{equation}
MBL = 1000 \max\left(1.0, -5445.3 + 176972.7 d\right)
\end{equation}

\section{Hydrostatic Stability}
\label{sec:static}
\subsection{Neutral Buoyancy}
Any floating body requires enough water displacement to create
sufficient buoyancy force such that the body stays afloat in the most
extreme loading and environmental conditions.  This level of
displacement would otherwise be overkill for more benign loading
conditions.  Since a floating turbine is designed for a constant hub
height, variable amounts of ballast are required to maintain a neutrally
buoyant system for all operating conditions.  The variable ballast is
simply ocean water that is pulled in or pumped out of holding areas
within the substructure columns.

In \textit{FloatingSE}, the variable ballast water mass is calculated as
the difference between the total mass of displaced water and the total
mass of the floating turbine.  This mass is then divided by the water
density to obtain the variable ballast volume, which is then compared to
the frustum shell cross section profile above the permanent ballast to
determine the height of the water ballast within the column.  Once this
is determined, the final center of mass of the system can be determined.

\subsection{Surge/Sway Stability}
Surge and sway stability is not actively tracked over the coarse of a
load case.  Instead the total surge force on the structure is calculated
at the initial conditions and compared to the restoring force of the
mooring system at the maximum allowable surge offset, which is specified
by the user.

The surge direction is assumed to be aligned with the wind vector, which
is aligned with the $x$-axis.  Since the rotor yaw is assumed to be
$0^{\circ}$, the surge forces on the turbine include the rotor thrust
and the wind and wave drag on the tower and substructure.  The final
surge force over the whole structure is taken from the $x$-direction
reaction force of the reaction node in Frame3DD.

The restoring force is calculated as the smallest possible restoring
force after a displacement in any angular direction in the mooring
model.  Since the alignment of the mooring lines relative to the
incoming wind direction is arbitrary, a maximum offset is simulated at
$2^{\circ}$ increments around the unit circle. Also recorded in this
survey is the maximum mooring line tension in any
line, in any direction, for comparison against the minimum breaking load
value,
\begin{equation}
  F_{x,restore} = \min_{i\in a} F_{x,i}\quad \mbb{T}_{moor} = \max_{l\in L,i\in a} \mbb{T}_{l,i}\,;
\qquad L=\left\{1,2\ldots nlines\right\}, \, a= \left\{0^{\circ}, 2^{\circ}\ldots 360^{\circ}\right\}
\end{equation}
where $F_x$ is the surge force and $\mbb{T}$ is the tension.  If
restoring force at this maximum offset is greater than the surge force
applied, then the system is considered stable in surge.  Since the wind
and wave profiles are essentially 2-D in the $x-z$ plane, the sway
stability is given the same status as surge stability.

\subsection{Pitch Stability}
The approach to pitch stability determination is similar to that of
surge stability.  The total pitching moment on the floating turbine is
calculated and compared to the restoring moment at the maximum allowable
angle of heel.  If the restoring moment at this max heel angle is
greater than the pitching moment applied, the system is said to be
statically stable in pitch.

Similar to the surge force calculation, the total pitching moment is
determined from the reaction moment at the boundary condition
in the Frame3DD analysis.  The pitching moment has contributions from
the wind and wave loads on the structure, the rotor forces and torques,
the buoyancy forces on the submerged substructure, and the off-center
weight of components (e.g. the RNA).

The restoring pitching moment has two primary contributions.  The first
is from the mooring lines.  Similar to the surge force calculation, here
the floating turbine is deflected in pitch by the maximum allowable heel
angle and the mooring forces are recorded.  The restoring moment
contribution from the mooring system is computed as,
\begin{equation}
  \mbf{M_{moor}} = \sum_i \mbf{r_{cm-l}} \times \mbf{F_l}
\end{equation}
where $r_{cm-l}$ is the vector from the center of mass to the mooring
connection, and $F_l$ is the force applied by the $l$-\th\~mooring
line.  As above, $F_l$ is taken as the minimum set over the possible
orientations of the mooring lines relative to the direction.

\begin{figure}[htb]
  \begin{subfigure}[b]{0.49\linewidth}
    \centering \includegraphics[height=3.5in]{figs/metacenterA.pdf}
    \caption{}
  \end{subfigure}
  \begin{subfigure}[b]{0.49\linewidth}
    \centering \includegraphics[height=3.5in]{figs/metacenterB.pdf}
    \caption{}
  \end{subfigure}\\
  \caption{Static stability of floating offshore wind turbines.}
  \label{fig:metacenter}
\end{figure}

The second contributing restoring moment comes from the motion of the
center of buoyancy away from alignment with the center of mass.  This is
a standard calculation in naval architecture \citep{thiagarajan2014} and is
diagrammed in Figure \ref{fig:metacenter}.  In this diagram, the center
of mass is denoted, $G$, the center of buoyancy is $B$, and the
metacenter is $M$.  In neutral conditions (Figure \ref{fig:metacenter}a),
all of these points are vertically aligned.

As the structure lists or heels, the center of buoyancy shifts toward
the side of the structure that is more submerged (from $B$ to $B'$) and
the buoyancy force no longer passes through the center of mass.
Instead, the buoyancy force passes through the metacenter with an
effective moment arm of $GZ$ from the center of mass (Figure
\ref{fig:metacenter}b).  The metacenter is defined as the common point
through which the buoyancy force acts as it pitches through small
displacements, for bodies with sufficient freeboard margin.

The metacenteric height, $GM$ is most easily calculated as an offset from the
center of buoyancy ($BM$) by,
\begin{equation}
  h_{meta} = M - G = GM = BM + BG;\quad BM = \frac{I_w}{V}
\end{equation}
where $BG$, the distance between the centers of buoyancy and gravity is
easily calculated, $I_w$ is the second moment of area of the substructure waterplane
(with units of \unit{$m^4$}) and $V$ is the total volume of displacement
(with units of \unit{$m^3$}).  Note that for semisubmersible type
geometries, $I_w$ is calculated with the parallel axis theorem for all
of the columns at the waterplane,
\begin{equation}
  I_w = \sum_i \left( I_{w,i} + S_ir_i^2 \right)
\end{equation}
where $S_i$ is the waterplane cross sectional area of the $i$-\th column and $r_i$
is the distance from the waterplane centroid to the $i$-\th column centroid.

The restoring moment is then the buoyancy force acting through the
restoring arm, $GZ$,
\begin{equation}
  M_{meta} = F_B GZ = F_B GM \sin \varphi
\end{equation}
where $\varphi$ is the angle of heel.

For this reason, the metacenter must be located above the center of mass
for static stability.  This condition is imposed on the design as a
constraint.  Note that the total volume of displacement, and the
subsequent buoyancy force, is not recalculated in the perturbed
configuration.  It is assumed that the angles of deflection are small
and that there is sufficient freeboard and design symmetry such that the
total displacement is constant.

The total restoring pitching moment is then the sum of two
contributions,
\begin{equation}
  M_{y,restore} = M_{y,moor} + M_{meta}
\end{equation}

\section{Hydrodynamic Stability}
Floating bodies are typically modeled, for small motions and linearized
behavior, as a second-order differential system with mass, damping, and
spring stiffness terms,
\begin{equation}
  \left(\mbf{M} + \mbf{A}\right)\ddot{\mbf{x}} + \mbf{C}\dot{\mbf{x}} +
  \mbf{K} = \mbf{F}\left( t \right)
\end{equation}
where $\mbf{x}\in\mbb{R}^6$ is the six-degree of freedom vector
(commonly ordered as 1-surge, 2-sway, 3-heave, 4-roll, 5-pitch,
6-yaw), $\mbf{M}$ is the mass matrix, $\mbf{A}$ is the added mass
matrix, $\mbf{C}$ is the damping matrix, and $\mbf{K}$ is the stiffness
matrix.  The right-hand side of the equation captures the time-dependent
summation of all forces.

As a low-fidelity, quasi-static sizing and cost module,
\textit{FloatingSE} does not attempt to capture all of the matrix
entries or forcing terms of the hydrodynamics.  A more sophisticated
time- or frequency-domain solver, where these quantities are calculated,
may be linked or included into \textit{FloatingSE} in the future.
Nevertheless, it does attempt to compute the diagonal entries of the
mass and stiffness matrices in order to derive the rigid body natural
frequencies of the system,
\begin{equation}
  f_i = \frac{\omega_i}{2\pi} =
  \frac{1}{2\pi}\sqrt{\frac{K_{ii}}{M_{ii}+A_{ii}}}, \quad \forall i \in
  \left[1\ldots6\right]
\end{equation}
where $f_i$ are the frequencies of the eigenmodes and $\omega_i$ is the
circular frequency.  The mass matrix diagonal entries, $M_{ii}$, are simply the mass and
moments of inertia of the whole system,
\begin{equation}
  M_{11} = M_{22} = M_{33} = m_{sys};\quad M_{44} = I_{xx,sys};\quad M_{55} = I_{yy,sys};\quad M_{66} = I_{zz,sys};
\end{equation}
Where the coordinate system notation is consistent with that of Figure
\ref{fig:diagram}.

The added mass matrix diagonal entries are evaluated via standard strip
theory for the tapered vertical columns.  The added mass for the system is a
summation over the columns, using the parallel axis theorem for the
rotational degrees of freedom.  Pontoon contributions to system added
mass are currently ignored.  The column quantities are calculated as,
\begin{equation}
  A_{11} = A_{22} = \rho V;\quad A_{33} =
  \left(\frac{1}{2}\right)\frac{8}{3} \rho \max \left[ R^3(z)\right] ; \quad A_{44} =
  A_{55} = \pi\rho\int\left(z-z_{cb}\right)R^2(z)dz;\quad A_{66} = 0.0;
\end{equation}
where $\rho$ is the water density, $R(z)$ is the column radius along its
axis, and $V$ is the submerged volume.  The extra factor of $1/2$ in
$A_{33}$ is included to account for the fact that the top of the column
extends above the waterline.  Also, the integral in $A_{55}$ is only evaluated
along the submerged portion of the column.

The stiffness matrix is comprised of contributions from the mooring
and hydrostatic stiffness.  The mooring linearized stiffness matrix is output
directly from MAP++ and needs no additional processing within
\textit{FloatingSE}.  The hydrostatic stiffness, for a vertical column, is derived from the same
principals described above regarding the metacentric height,
\begin{equation}
  K_{ii} = K_{ii}^{moor} + K_{ii}^{hydro};\quad K_{33}^{hydro} = \rho g
  S_{sys};\quad K_{44}^{hydro} =  K_{55}^{hydro} = \rho g V h_{meta}
\end{equation}
where $S_{sys}$ is the waterplane area of the system.

Once the rigid body natural frequencies (eigenmodes) of the system are
calculated, they are compared against the standard wave frequencies
range, \unit[0.5--5]{Hz}, and expressed as a design constraint (with a
partial safety factor).


\documentclass{bioinfo}
\copyrightyear{2017}
\pubyear{2017}

\usepackage{hyperref}
\usepackage{amsmath}
\usepackage[ruled,vlined]{algorithm2e}
\newcommand\mycommfont[1]{\footnotesize\rmfamily{\it #1}}
\SetCommentSty{mycommfont}
\SetKwComment{Comment}{$\triangleright$\ }{}

\usepackage{natbib}
\bibliographystyle{apalike}

\begin{document}
\firstpage{1}

\title[Pairwise alignment with DP]{On pairwise alignment with dynamic programming}
\author[Li]{Heng Li}
\address{Broad Institute, 415 Main Street, Cambridge, MA 02142, USA}

\maketitle

\begin{abstract}
This \emph{informal} note introduces important literatures on pairwise
biological sequence alignment with dynamic programming (DP), disambiguates a
few different formulations, investigates the choice of gap cost function and
discusses the implementation of DP-based alignment with a focus on practical
applications. It targets developers who are interested in the history of
DP-based alignment and want to understand it in depth.  Importantly, this note
is not a general tutorial. Audience should be familiar with the basis of
pairwise alignment before reading the note.
\end{abstract}

\begin{methods}
\section{Alignment with dynamic programming}

Let $T$ be the \emph{target} sequence or the \emph{reference} sequence of
length $n=|T|$ and $Q$ be the \emph{query} sequence of length $m=|Q|$. Gaps on
the target sequence are \emph{deletions}; gaps on the query sequence are
\emph{insertions}. Function $s(i,j)$, $0\le i<n$ and $0\le j<m$, gives the
score between the $T[i]$ and $Q[j]$. We will focus on global alignment
algorithms because it is usually more complex than local alignment due to
non-trivial initial conditions.

\subsection{Levenshtein distance}

\emph{Levenshtein distance}~\citep{Levenshtein:1966aa} is the minimum sum of
substitutions, insertions and deletions among all possible alignments between
two sequences. The author proposed the measurement but did not provide an
algorithm to compute the distance. Levenshtein distance is the most common
measure of edit distance. Other variants of edit distances may include fewer
(e.g. no substitutions) or more types of primitive edit operations (e.g.
transpositions).

Levenshtein distance can be computed with dynamic programming (DP). Let
$H_{ij}$ be the distance between prefixes $T[0..i]$ and $Q[0..j]$. The distance
between the full sequences will be $H_{n-1,m-1}$, which can be recursively
computed with
\begin{equation}\label{eq:ed}
H_{ij}=\min\{H_{i-1,j-1}+1-\delta_{T[i],Q[j]}, H_{i-1,j}+1, H_{i,j-1}+1\}
\end{equation}
where $\delta_{ab}$ is the Kronecker delta function, which equals 1 if $a=b$ or
0 otherwise. The initial conditions are: $H_{-1,j}=j+1$ and $H_{i,-1}=i+1$.
This is an $O(mn)$ algorithm.

Practically faster algorithms exist. \citet{Landau:1986aa} found an $O(kn)$
algorithm that guarantees to find the optimal solution if the edit distance is
no larger than $k$. It is particularly fast if the distance is
small~\citep{Sosic:2015aa}.

Following the idea behind the 4-Russian problem~\citep{Arlazarov:1970aa},
\citet{Wu:1996aa} made an important observation that the differences
between adjacent cells
\[\left\{\begin{array}{l}
u_{ij}\triangleq H_{ij}-H_{i-1,j}\\
v_{ij}\triangleq H_{ij}-H_{i,j-1}
\end{array}\right.\]
only take values $-1$, $0$ or $1$. They transformed Eq.~(\ref{eq:ed}) to
\begin{equation}
\left\{\begin{array}{l}
z_{ij}=\min\{1-\delta_{T[i],Q[j]},v_{i-1,j}+1,u_{i,j-1}+1\}\\
u_{ij}=z_{ij}-v_{i-1,j}\\
v_{ij}=z_{ij}-u_{i,j-1}
\end{array}\right.
\end{equation}
and used a lookup table to speed up the computation. \citet{Myers:1999aa}
furthered this idea with bit-level parallelization, resulting in an $O(mn/w)$
algorithm where $w$ is the size of a machine word in bits. Combined with
bounding~\citep{Ukkonen:1985aa}, Myers' algorithm is significantly faster than
Eq.~(\ref{eq:ed}) for long sequences.  Edlib~\citep{Sosic:2017aa} provides an
efficient implementation of this algorithm with added functionality.

\subsection{Linear gap cost}

When \citet{Needleman:1970aa} first proposed to align a pair of biological
sequences with DP, they focused on a linear gap cost function
$\gamma_0(k;e)=k\cdot e$, $e>0$. Let the optimal score up to cell $(i,j)$ be
$H_{ij}$. It can be computed with
\begin{equation}\label{eq:linear}
H_{ij}=\max\{H_{i-1,j-1}+s(i,j), H_{i-1,j}-e, H_{i,j-1}-e\}
\end{equation}
This equation is a generalization of Eq.~(\ref{eq:ed}). It gives matches,
mismatches and gaps different weights. Typically, we require $2e$ to be larger
than the mismatch cost; otherwise the alignment would always prefer two gaps
over a mismatch -- the final alignment would not contain any mismatches.

The Needleman-Wunsch algorithm has a history of multiple inventions in
different fields. Readers are referred to \citet{Navarro:2001aa} for a more
complete survey.

It is also possible to apply Myer's bit-parallelis to the linear gap cost
if $s(i,j)$ and $e$ are small integers~\citep{Loving:2014aa}.

\subsection{Classical formulation of affine gap cost}

With a linear cost function, a long gap is considered to arise from a series of
small gaps independently. In evolution, however, a long gap at times results
from one event (e.g. a transposon insertion). A linear gap cost often breaks a
long gap into small pieces and complicates the interpretation of alignment.
Therefore, it is discouraged to use a linear cost to produce alignment for
evolutionarily related sequences.

The limitation of linear cost motivated \citet{Waterman:1976aa} to use a more
general cost function. This work was later folded to \citet{Smith:1981aa},
\emph{the} Smith-Waterman paper. With a general cost, the time complexity to
find the optimal alignment is $O(mn\max\{m,n\})$. \citet{Gotoh:1982aa} showed
that when the cost function takes a form $\gamma_1(k;q,e)=q+k\cdot e$, which is
called \emph{affine gap cost}, it is possible to solve the alignment problem in
$O(mn)$ time. \citet{Altschul:1986aa} fixed an issue in the original Gotoh's
algorithm and introduced the formulation we commonly use today.

\subsubsection{Durbin's formulation}

To give alignment a probablitistic interpretation, \citet{Durbin:1998uq}
introduced
\begin{equation}\label{eq:durbin}
\left\{\begin{array}{l}
M_{ij}=\max\{M_{i-1,j-1}, E_{i-1,j-1}, F_{i-1,j-1}\} + s(i,j)\\
E_{ij}=\max\{M_{i-1,j}-q, E_{i-1,j}\} - e\\
F_{ij}=\max\{M_{i,j-1}-q, F_{i,j-1}\} - e
\end{array}\right.
\end{equation}
This formulation has a natural connection to pair-HMM with each state having a
clear meaning in alignment. It, however, has one problem: it disallows
transitions between $E$ and $F$ states and thus forbids insertions immediately
followed by deletions (and vice versa). When the gap extension cost $e$ is
smaller than the half of a mismatch cost, transitions between $E$ and $F$ may
yield a better alignment score. It is possible to add transitions between $E$
and $F$ in Eq.~(\ref{eq:durbin}), but in practice, AE86's
formulation~\citep{Altschul:1986aa} will be simpler and faster to implement.

\subsubsection{AE86's formulation}

In Eq.~(\ref{eq:durbin}), if we let:
\[H_{ij}\triangleq\max\{M_{ij},E_{ij},F_{ij}\}\]
Durbin's formulation allowing $E$--$F$ transitions becomes
\begin{equation}\label{eq:ae86-ori}
\left\{\begin{array}{l}
E_{ij}=\max\{H_{i-1,j}-q, E_{i-1,j}\} - e \\
F_{ij}=\max\{H_{i,j-1}-q, F_{i,j-1}\} - e \\
H_{ij}=\max\{H_{i-1,j-1}+s(i,j), E_{ij}, F_{ij}\}
\end{array}\right.
\end{equation}
This is AE86's formulation. In practice, we sometimes compute the cells in the
following order
\begin{equation}\label{eq:ae86}
\left\{\begin{array}{l}
H_{ij}=\max\{H_{i-1,j-1}+s(i,j), E_{ij}, F_{ij}\}\\
E_{i+1,j}=\max\{H_{ij}-q, E_{ij}\} - e \\
F_{i,j+1}=\max\{H_{ij}-q, F_{ij}\} - e
\end{array}\right.
\end{equation}
with initial conditions
\begin{equation}
\left\{\begin{array}{ll}
H_{-1,-1}=0\\
H_{-1,j}=-q-e-j\cdot e & (0\le j<m)\\
H_{i,-1}=-q-e-i\cdot e & (0\le i<n)\\
E_{0j}=-2q-2e-j\cdot e & (0\le j<m)\\
F_{i0}=-2q-2e-i\cdot e & (0\le i<n)
\end{array}\right.
\end{equation}
We don't need $E_{-1,\cdot}$ or $F_{\cdot,-1}$ because Eq.~(\ref{eq:ae86})
does not start with these initial values.

AE86 can be impelmented in different ways depending on the order of computation
and how row scores are stored. Algorithm~\ref{algo:ae86} gives one
implementation. At the beginning of each iteration at line 2, $f=F_{ij}$,
$h=H_{i,j-1}$, $H[j]=H_{i-1,j-1}$ and $E[j]=E_{ij}$. The loop computes
$H$ in cell $(i,j)$, $E$ in the next row and $F$ in the next column.
This algorithm uses a query profile at line 1. It is a common techique
to accelerate the inner loop.

\begin{algorithm}[tb]
\DontPrintSemicolon
\footnotesize
\KwIn{Target sequence $T$ and query $Q$; scoring matrix $S(\cdot,\cdot)$ and
affine gap cost $\gamma_1(k;q,e)=q+k\cdot e$}
\KwOut{Best alignment score between $T$ and $Q$}
\BlankLine
\textbf{Function} {\sc AlignScore}$(T,Q,q,e)$
\Begin {
	\nl\For (\Comment*[f]{Generate query profile}) {$a\in\Sigma$} {
		\For{$j\gets0$ \KwTo $|Q|-1$} {
			$P[a][j]\gets S(Q[j],a)$\;
		}
	}
	\For{$j\gets0$ \KwTo $|Q|-1$} {
		$H[j]\gets-q-j\cdot e$\Comment*[r]{$H[j]=H_{-1,j-1}$}
		$E[j]\gets-2q-2e-j\cdot e$\Comment*[r]{$E[j]=E_{0j}$}
	}
	$H[j]\gets 0$\Comment*[r]{$H_{-1,-1}=0$}
	\For{$i\gets0$ \KwTo $|T|-1$} {
		$f\gets-2q-2e-i\cdot e$\Comment*[r]{$f=F_{i0}$}
		$h\gets-q-e-i\cdot e$\Comment*[r]{$h=H_{i,-1}$}
		$p\gets P[T[i]]$\;
		\For{$j\gets0$ \KwTo $|Q|-1$} {
			\nl$s\gets p[j]$\Comment*[r]{$s=S(Q[j],T[i])$}
			$h'\gets\max\{H[j]+s,E[j],f\}$\;
			$H[j]\gets h$\Comment*[r]{$H[j]=H_{i,j-1}$}
			$h\gets h'$\Comment*[r]{$h=H_{ij}$}
			$E[j]\gets\max\{h-q,E[j]\}-e$\Comment*[r]{$E[j]=E_{i+1,j}$}
			$f\gets\max\{h-q,f\}-e$\Comment*[r]{$f=F_{i,j+1}$}
		}
		$H[|Q|]\gets h$\;
	}
	\Return $H[|Q|]$\;
}
\caption{AE86's formulation with affine gap cost}\label{algo:ae86}
\end{algorithm}

\subsubsection{Effect of affine gap cost}\label{sec:affine-eff}

For simplicity, we use one score $a>0$ for all types of matches and one cost
$b>0$ for all types of mismatches. Ignore gaps for now. If the identity between
$T$ and $Q$ is below $1-a/(a+b)$, $T$ and $Q$ will get a negative alignment
score. The $b:a$ ratio sets the minimum identity. Now suppose we have a long
deletion. If $\lceil q/(a+b)\rceil$ or more residues on the query adjacent to
the gap are mismatches but have a perfect match to a subsequence in the gap,
the perfect match will yield a higher alignment score and split the long gap in
two. Gap open cost $q$ determines how easily a long gap to be split into two or
more smaller gaps. Gap extension $e$ is directly related to $E$--$F$
transitions: if $b>2e$, there may be insertions immediately followed by
deletions. $q$ and $e$ together control the total number of gaps. Suppose in a
small region there are $x$ mismatches and one gap. We may achieve a better
score by opening a new gap and add $2y$ gap extensions if $x\cdot b>q+2y\cdot
e$, approximately. We also note that scoring must satisfy $2(q+e)>b$; otherwise
the alignment would not contain any mismatches.

\subsection{Affine gap cost: SIMD acceleration}

SIMD CPU instructions perform one action on a vector of data at the same time.
For example, with SSE2, a type of SIMD, we can compute the sum of two vectors
of sixteen 8-bit integers with one CPU instruction. This is much faster than
summing with sixteen standard instructions. How many data can be processed with
one SIMD instruction depends on the number of bits in the vector and the max
value of each element in the vector. For example, SSE instructions operate on
128-bit vectors. We can process four 32-bit integers or eight 16-bit integers
at the same time. AVX instructions operate on 256-bit vectors. It doubles the
bandwidth of SSE.

SIMD has been used to speed up DP-based pairwise alignment. There are two
general classes of SIMD algorithms: inter-sequence and intra-sequence.
Inter-sequence algorithms~\citep{Rognes:2011aa} align multiple pairs of
sequences at the same time. It is conceptually easier to implement and faster
to run but it is tricky to use with other alignment routines. Intra-sequence
algorithms align one sequence at a time. There are several ways to implement
intra-sequence pairwise alignment, depending on how to organize multiple data
into one vector.

For simplicity, we assume each vector consists of four elements.
\citet{Wozniak:1997aa} put $(H_{ij},H_{i+1,j-1},H_{i+2,j-2},H_{i+3,j-3})$
into a vector and fills the DP matrix along its diagonal.
\citet{Rognes:2000aa} took a block of column cells into a vector
$(H_{ij},H_{i,j+1},H_{i,j+2},H_{i,j+3})$. \citet{Farrar:2007hs} interleaved columns
into $(H_{ij},H_{i,t+j},H_{i,2t+j},H_{i,3t+j})$ in a striped manner, where
$t=\lfloor(m+3)/4\rfloor$ -- the algorithm collates cells distant apart. In
practice, Farrar's striped algorithm is the fastest and most often
used~\citep{Szalkowski:2008aa,Zhao:2013aa}. \citet{Daily:2016aa} developed a
programming library that implements all three intra-sequence algorithms.

\subsection{Affine gap cost: Suzuki's formulation}

When working with long sequences that yield large alignment scores,
we may need to use 32-bit integers to hold the score arrays. With SSE, we can
only process four cells at a time. Inspired by \citet{Myers:1999aa} and
\citet{Loving:2014aa}, \href{https://github.com/ocxtal}{Hajime Suzuki} proposed
to rewrite Eq.~(\ref{eq:ae86}) with differences between cells:
\begin{equation}
\left\{\begin{array}{l}
u_{ij}\triangleq H_{ij}-H_{i-1,j}\\
v_{ij}\triangleq H_{ij}-H_{i,j-1}\\
x_{ij}\triangleq E_{i+1,j}-H_{ij}\\
y_{ij}\triangleq F_{i,j+1}-H_{ij}
\end{array}\right.
\end{equation}
as
\begin{equation}\label{eq:suzuki}
\left\{\begin{array}{l}
z_{ij}=\max\{s(i,j),x_{i-1,j}+v_{i-1,j},y_{i,j-1}+u_{i,j-1}\}\\
u_{ij}=z_{ij}-v_{i-1,j}\\
v_{ij}=z_{ij}-u_{i,j-1}\\
x_{ij}=\max\{0,x_{i-1,j}+v_{i-1,j}-z_{ij}+q\}-q-e\\
y_{ij}=\max\{0,y_{i,j-1}+u_{i,j-1}-z_{ij}+q\}-q-e
\end{array}\right.
\end{equation}
where $z_{ij}$ is a temporary variable that does not need to be stored.  We can
prove that all variables in these equations are bounded by gap costs and the
extreme match and mismatch scores, but not by the sequence lengths or the peak
alignment score. For small scores, we can encode 16 cells in one SSE vector.

In practice, Suzuki's formulation is about twice as slow as Algorithm~1 without
SSE vectorization, because it involves more computation and cannot use
a query profile. For long sequences when the peak score does not fit 16-bit
integers, 16-way vectorized Suzuki's formulation is twice as fast as striped
4-way vectorization~\citep{Farrar:2007hs}. Another advantage of Suzuki's
algorithm is that it can be adapted for banded alignment.

\subsection{Piece-wise affine gap cost}

Affine gap cost still has issues with long gaps. Recall that an exact match of
length $\lceil q/(a+b)\rceil$ in the middle of a long gap splits the gap into
two if moving this exact match to either edge of the gap leads to mismatches
(Section~\ref{sec:affine-eff}). For noisy reads, it is not infrequent for a
long gap to be split by incidental sequencing errors. We would prefer to
increase the gap open cost $q$ to avoid such a split, but this would contradict
the high INDEL error rate of some sequencing data.

The root cause of this dilemma is that gaps are caused by two different
mechanisms: evolution which may create a long gap with one event, and
sequencing errors which generate gaps as relatively independent events. A
better gap cost should be concave, such that $\gamma(k+1)-\gamma(k)$ is smaller
with larger $k$.

\citet{Miller:1988aa} found an $O(mn\log\max\{m,n\})$ algorithm for a concave
gap cost function $\gamma(k)$. When $\gamma(k)$ is a piece-wise affine cost
composed of $p$ affine cost functions, their algorithm finds the optimal
alignment in $O(mn\log p)$ time. \citet{Gotoh:1990aa} proposed an $O(mn\cdot
p)$ algorithm, which is simpler and probably faster for small $p$ in practice.

When $p=2$, the two-piece affine cost takes the form
\[
\gamma_2(k;q,e,\tilde{q},\tilde{e})=\min\{q+k\cdot e,\tilde{q}+k\cdot\tilde{e}\}
\]
It is concave on the condition that $q+e<\tilde{q}+\tilde{e}$ and
$e>\tilde{e}$. Effectively, this cost function applies $\gamma_1(k;q,e)$ to
gaps shorter than $\lceil(\tilde{q}-q)/(e-\tilde{e})\rceil$ and applies
$\gamma_1(k;\tilde{q},\tilde{e})$ to longer gaps. We can compute the maximal
alignment score under $\gamma_2(k)$ with
\begin{equation}\label{eq:affine2}
\left\{\begin{array}{l}
H_{ij} = \max\{H_{i-1,j-1}+s(i,j),E_{ij},F_{ij},\tilde{E}_{ij},\tilde{F}_{ij}\}\\
E_{i+1,j}= \max\{H_{ij}-q,E_{ij}\}-e\\
F_{i,j+1}= \max\{H_{ij}-q,F_{ij}\}-e\\
\tilde{E}_{i+1,j}= \max\{H_{ij}-\tilde{q},\tilde{E}_{ij}\}-\tilde{e}\\
\tilde{F}_{i,j+1}= \max\{H_{ij}-\tilde{q},\tilde{F}_{ij}\}-\tilde{e}
\end{array}\right.
\end{equation}
Eq.~(\ref{eq:suzuki}) can be extended to work with piece-wise affine cost in a
similar manner.

\end{methods}

\bibliography{aln-dp}
\end{document}


\section{Backend} \label{back}
In this section we illustrate the design and implementation of the backend of compiler of $\lambda_Q$.
The backend consists of four parts: lexer, parser, qubit allocation and optimization.
\subsection{Lexer \& Parser}
We use Lex/Yacc to implement the lexer and parser of a modified version of OpenQasm2.0 in backend.

Subcircuit definition is not available in our OpenQasm2.0. Besides $\{U3,CX\}$ that are available in the original OpenQasm2.0, we add $\{H,X,Y,Z\}$ to the built-in gate set.

This part consists of 600 lines of C code formatted in Lex/Yacc file's syntax.
Readers can refer to \textit{lex.l} and \textit{parser.y} to get more detailed information.

\subsection{Qubit Allocation}
In recent years, some companies like IBM have made quantum computers available to wide community.
Users can build their experiments based on a circuit representation on the cloud platform. However, today's quantum computer prototypes have tight resources constraints.
For instance, you can only apply two qubits operations to a subset of qubit pairs which is specificed by a partial network.

In \textit{qubit\_allocation.cpp}, we implement a heuristic algorithm  to allocate physical qubits to logic qubits.

\subsubsection{Problem Definition}
The most basic form of Qubit Allocation Problem is: given a quantum circuit and an architecture, we want to know if it is possible to map logic qubits in the former to physical qubits in the latter.
Notice that even this basic problem is NP-hard.

In some cases, the constraints of the architecture is impossible to satisfy, and we need some circuit transformation to relax these constraints.

There are three kinds of transformations we can apply:
\begin{itemize}
    \item[Reversal] Apply $CX$ to $(p,q)$ when $(q,p)$ is available in the architecture.
    \item[Bridge] Apply $CX$ to $(p,q)$ when $(p,s)$ and $(s, q)$ is available.
    \item[Swap] Swap the state of $p$ and $q$ when $(p,q)$ or $(q,p)$ is available.
\end{itemize}

All these transformation need extra gates to implement, so we need to find a qubit mapping and circuit transformations to satisfy the constraints with minimum number of extra gates involved.

\subsubsection{Algorithm}

Our algorithm~\cite{qa} has two stages:

\textbf{First stage}: Find an intial mapping

We first sort the logic qubits in descending order of their occurrence counts.

Then, for each logic qubit $q$ in order, we allocate $q$ to a physical qubit with the nearest out-degree(both the quantum circuit and the architecture can be regarded as a directed graph whose vertex is qubit)

After $q$ is allocated to $p$, for each edge $(q,q')$, we try to allocate $q'$ to some $p'$ with edge $(p,p')$ and has the nearest out-degree.

Repeat the above process for $q'$ if it is successfully allocated.

After this BFS-like allocation we allocate the rest unallocated logic qubit to a free physical qubit.

\textbf{Second stage}: Adjust the mapping and apply circuit transformation

The mapping $l$ in the output of the first stage may not satisfy all constraints, so we need to adjust it and apply circuit transformations to the quantum circuit.

For any two qubits operation on $(p,q)$, if $(l(p),l(q))$ can't be implemented in current mapping, then:
\begin{itemize}
    \item[1.] if $(p,q)$ appears more than once in the circuit, we use a Swap transformation to move $q$ closer to $p$ (Here we can use BFS to find the shortest path to $p$) and then re-evaluate these four cases.
    \item[2.] else if $(l(q), l(p))$ can be implemented, then we use a Reversal transformation to $l(q)$ and $l(p)$.
    \item[3.] else if $\exists s$ s.t. $(l(p),s)$ and $(s, l(q))$ are both available, we can use a Bridge transformation to $l(p), s, l(q)$.
    \item[4.] else use Swap transformation like case 1.
\end{itemize}
\subsection{Optimization}

Optimization \cite{Nam_2018} for arbitary unitary gates is sophisticated, so we only consider cases when gates are chosen from a discrete set.

In this section, we implement two basic optimization method for gate set $\{H, RZ, CX, X\}$

Our work in this section can be divided into four parts: graph conversion, gate decomposition, Hardmard reduction and gate cancellation.

Readers can refer to \textit{generator.cpp, optimization.cpp, graph.h} for detailed information.
\subsubsection{Graph Conversion}

At first, we only store quantum circuit in the AST constructed by yacc and write \textit{generator.cpp} for code generation from AST (It retains this function in the final version)

However, tree structure is not suitable for gate optimization, since we often access the adjacent gate of a given gate, and they can be distant in AST.

Therefore, in \textit{generator.cpp}, we construct a graph from AST whose edge connects gates that are adjacent in the circuit.

In \textit{graph.h}, we implement function $Graph::toposort$ to generate code from a given graph.

\subsubsection{Gate Decomposition}
Since available gate set in our modified OpenQasm2.0 is different from the gate set on which we implement gate optimization, we should first decompose the given circuit in the new basis gate set.

Notice that $HXH = Z, ZX = iY, U(\theta, \phi, \lambda) = R_z(\phi)R_x(-\frac{\pi}{2})R_z(\theta)R_x(\frac{\pi}{2})R_z(\lambda)\\$ and $HR_x(\theta)H = R_z(\theta)$, it is easy to implement this decomposition.

    \subsubsection{Hardmard Reduction}
    In this section, we implement Hardmard Reduction to reduce the number of Hardmard gate.

    It is a simple pattern (\ref{pattern}) matching algorithm. We can traverse the graph, find serveral subcircuit pattern and replace it with a simplfied equivalent subcircuit.

    \begin{center}
        \begin{figure}
            \label{pattern}
            \centering
            \includegraphics[width=0.9\linewidth]{images/hardmard_reduction.png}
            \caption{Subcircuit patterns in Hardmard Reduction}
        \end{figure}
    \end{center}

    \subsubsection{Gate Cancellation}
    When a pair of conjugate transpose gates are adjacent, they can both be cancelled.

    In this section, we implement gate cancellation for $RZ$ gate, we traverse all $RZ$ gates and try to move it by swapping with adjacent commutative subcircuit if posible (we only consider serveral  built-in commutation rules (\ref{commutation}) since it is hard to determine whether two gates are commutative) until encountering its conjugate transpose or reaching endpoints of the circuit.

\begin{center}
    \begin{figure}
        \label{commutation}
        \centering
        \includegraphics[width=0.9\linewidth]{images/gate_cancellation.png}
        \caption{Commutation rules for RZ gate}
    \end{figure}
\end{center}


% --- [ Conservativeness ] -----------------------------------------------------

\subsection{Conservativeness}

Reports whether the source type exists within the type range (lower and upper bound) of the recovered type.

The distance measurement as defined by TIE did not distinguish between multi-level pointers (e.g. \texttt{int*} and \texttt{int**} are equivalent, i.e. on the same level in the type lattice). Thus SecondWrite proposed a refinement to measure the ratio between the recovered pointer level and the source pointer level \cite{second_write_scalable_type_detection}.


%!TEX root = Lefley - Mesh to voxel transformations for optimised physics-based interactions.tex
\chapter{Implementation}

This chapter will discuss the stages of development. The starting point, implementation and result of each pipeline stage will be detailed as well as any difficulties faced.

\section{Process}

The process for development was iterative, implementing each pipeline stage in order. This was because each stage required the output of the previous stage to function and, while mock results could have been generated and forwarded, often the easiest way to input interesting data was to generate it from the previous stage because of the size of the data structures being used.

Stages were kept as encapsulated as possible so that any changes that had to be made would not cascade through later stages or require changes to those previous.

Testing and debugging were done on each stage as it was completed to test the performance of that particular implementation and gauge whether changes or a new algorithm were needed. This also improved the ease of finding bugs in comparison with debugging at the end of the pipeline.

\section{Preprocessing}

\label{sect:pre}

The simplest way to satisfy the requirement of applying the correct resultant movement vector to each fragment is to perform the fragmentation before the collision takes place. This allows the Unity3D physics engine to properly apply force to each fragment when the incoming particle makes contact.

It is therefore necessary to predict and extrapolate possible collisions before they occur. This was achieved by adding a bounding sphere to destructible objects and using Algorithm~\ref{alg:extrap}.

\begin{algorithm}[H]
 \KwData{Object to be destroyed: d, Bounding sphere: s, Incoming object: p}
 \KwResult{Force magnitude exerted on each object: f, Collision point on d: c}
 Ray r = cast ray from p along p.velocity\;
 \If{r intersects d}{
 	Point c = intersection point\;
 	Vector n = c.normal\;
 	n = n*2\;

 	Double md = d.mass\;
 	Double mp = p.mass\;

 	Vector vd = d.velocity\;
 	Vector vp = p.velocity\;

 	Double t = Physics.timestep\;

 	f = Dot(n, (mpvd - mdvp))\;
 	f = f / (md+mp)\;
 }
 \caption{Collision extrapolation}
 \label{alg:extrap}
\end{algorithm}

This algorithm relies on the following equations which approximately calculate the magnitude of the force which will be exerted on each object\footnote{Dylan Kennedy, personal communication, January 14, 2015}:

\begin{equation}
F = {\beta \over t} \quad \text{$t$ = time objects are in contact for}
\end{equation}

\begin{equation}
\beta = {2\mathbf{\hat{N_1}}\cdot (m_{2}\mathbf{v_1}-m_{1}\mathbf{v_2}) \over m_{1}+m_{2}}
\end{equation}

As the colliding objects are rigid we take the time that they will be in contact for to be one time-step of the Unity3D physics engine.

\subsection{Assumptions}

As we are extrapolating the collision data at the point when they enter the bounding sphere, some assumptions are made.

\begin{itemize}
\item{The velocity of the two objects involved will not change between this point and any collision}
\item{A third object will not move to obstruct any collision after this point}
\item{The rotation of either object will not change the result of any collision}
\end{itemize}

By tightening the bounding sphere around our destructible object we can take these assumptions to hold for simplicity.

\section{Voxelisation}

Originally it was planned for only a portion of the destructible object to be voxelised, depending on the physical forces involved. However it was found that the computational complexity of determining which mesh triangles fell within this portion was equal to that of voxelising these triangles. Therefore, for simplicity, the whole mesh is voxelised.

The solution for voxelisation used is based on an implementation of the Schwartz method found in GPU Pro 3\cite{Schwarz:2010:Vox}\cite{Engel:2012:GPA:2331213}.

This method is made up of two phases, a triangle phase and a propagation phase. Both of these are separate shaders run on the GPU to allow for parallel processing within the phases.

\subsection{Data structures}

The data structures used in this stage of the pipeline are primarily buffers as these can be passed to and from the GPU shaders as input and output.

The inputs to the first shader are the triangles defining the object's mesh. These are stored in two buffers. A `vertex' buffer stores a list of floating point numbers, each one being an x, y or z coordinate in a triangle's vertex, relative to the position of the object\footnote{Therefore the world position is not factored into the vertices.}. These values are always grouped such that for each vertex the x, y and z coordinates are adjacent and in sequence. There is no further ordering imposed. A second `index' buffer stores an integer list of indices into the vertex buffer. This buffer is ordered such that, when divided into strides of three, each index within that triplet refers to the point of a triangle when used with the vertex buffer. This is shown in Figure~\ref{fig:3.1}.

\begin{figure}
\centerline{\includegraphics[scale=0.5]{buffers13.pdf}}
\caption{The triangle (c) is represented by three consecutive indices, one for each vertex, in (b) which each point to the beginning of three consecutive floats which define that vertex in (a).}
\label{fig:3.1}
\end{figure}

The output from both shaders and input to the second is a three dimensional array of bits defining which voxels exist. This is stored as a single integer buffer, with each integer encoding 32 voxels. The three dimensional array is flattened, first along the $Z$ direction, then $X$, then $Y$. The $Z$ direction is padded such that all of the voxels in a integer will have the same $X$ and $Y$ coordinates. On being outputted from the second shader this flattened array is wrapped in a helper class which allows easy lookup into the array as if it were three dimensional as well as helper functions such as getting the array's size in any of the three dimensions represented.

%Figure?

\subsection{Triangle Phase}

During this phase, each triangle in the object to be voxelised is processed in its own GPU thread. First the triangle is translated and scaled by a pair of matrices defined by the object's bounding box and the requested voxel resolution\footnote{The $X$, $Y$ and $Z$ dimensions of the voxel grid.}. This transforms object relative world coordinates into `voxel coordinates'.

The object relative coordinates are defined by taking a tight bounding box around the object, the centre of the box is $(0,0,0)$ and the box extends to $0.5$ in each dimension. Voxel coordinates define $(0,0,0)$ to be a corner of the bounding box and each axis extends to a defined magnitude depending on the voxel resolution desired. This is shown in Figure~\ref{fig:3.2}.

\begin{figure}
\centerline{\includegraphics[scale=0.5]{coordinates13.pdf}}
\caption{The box (a) represents a voxel space of resolution $7\times9\times7$. (b) shows the same box in object relative coordinates.}
\label{fig:3.2}
\end{figure}

Triangles are then projected onto the $XZ$ plane and all of the intersecting voxel columns are found\footnote{Voxel columns extending along the $Y$ axis.}. This is shown in Figure~\ref{fig:3.2.1}. For all of these columns the first voxel below the triangle, in the $Y$ direction, is set.

\begin{figure}
\centerline{\includegraphics[scale=0.5]{projection13.pdf}}
\caption{The red triangle has been projected onto the $XZ$ plane and the intersecting voxel columns marked in green.}
\label{fig:3.2.1}
\end{figure}

\subsection{Propagation Phase}

In the propagation phase we move up the $Y$ axis, XORing each voxel with the one below in the $Y$ direction. This allows us to fill in the solid volume. As we move up, when the first set voxel is met all those above will then become set until we reach another that had been set by the triangle phase. Each $Y$ column is processed in parallel, with 32 columns being processed in parallel on the same thread as we are XORing integers which are encoding 32 voxels.

\subsection{Progress}

\label{sect:voxprog}

Both shaders were taken from the GPU Pro 3 library mostly unaltered\footnote{There were methods in the first shader for other, unneeded, forms of voxelisation which were removed.}. The {\sc{C++}} driver found in the library was used to gain insight on interfacing with the shaders when writing the {\sc{C\#}} driver used. The completed driver and wrapper for the voxel grid output were heavily inspired by a {\sc{Javascript}} CPU implementation of voxelisation in Unity3D\cite{CPUVoxel}.

Achieving binary solid voxelisation on the GPU was the first major milestone completed. Several other libraries and methods were tried and tested before a suitable one was found. It also took much more time than anticipated to complete integration of the library which was used.

A scene was constructed where several objects differing in triangle resolution and shape were used for debugging the implementation. Figure~\ref{fig:3.3} demonstrates the output with the voxel structure being displayed for debugging.

\begin{figure}[b!]
\centerline{\includegraphics[scale=0.6]{Stanford_Bunny_Voxelised.png}}
\caption{Voxelisation of the `Stanford Bunny' model, composed of 69,666 triangles. The voxelisation shown is lower resolution than that which is typically used in the final implementation resulting in 1,723 voxels shown in red.}
\label{fig:3.3}
\end{figure}

\section{Physical Destruction}

\label{sect:destr}

The process of physically destroying an object involves partitioning its volume into fragments. This is done by assigning each voxel to a fragment, which will be referred to as `colouring'.

The method used is based on Voronoi diagrams as these are commonly used for achieving visually realistic fracturing effects\cite{Muller:2013:RTD:2461912.2461934}. This choice was made because of time restrictions and the encapsulated pipeline nature of Dynamic Volumetric Fragmentation would allow a more physically accurate algorithm to easily take its place.

\subsection{Data structures}

This pipeline stage takes the voxel grid from the voxelisation stage as an input and outputs a list of `fragment' classes and an altered voxel grid.

The fragment class stores:

\begin{itemize}
\item{An integer `colour' for that fragment, which acts as an identifier.}
\item{A list of points that make up the volume for that fragment.}
\item{A minimum and maximum $X$, $Y$ and $Z$ coordinate which define the bounding box for that fragment in voxel space.}
\end{itemize}

The altered voxel grid is a three dimensional array of integer values with each one corresponding to the colouring of the voxel in that position.

Duplicate information is returned here as different algorithms further down in the pipeline, primarily the meshing phase, require different input data structures. Some work on the point cloud provided by the fragment objects while others work optimally on the grid where neighbours can be found in constant time.

\subsection{Finding Generating Points}

To fragment the object using a Voronoi diagram, a series of generating points have to be found.

Firstly, the collision point from the preprocessing stage of the pipeline is transformed into voxel space. A number of vectors are then generated from this point with their magnitudes normally distributed within a given radius. The number of points and radius are calculated from both user defined physical properties of the object such as `brittleness' and `strength' as well as the collision force. This ensures that the fragmentation is different depending on the physical characteristics of the collision and therefore more accurate.

The vectors have normally distributed magnitudes so that there are more generating points closer to the collision point. This results in many smaller fragments about the point of impact as you would expect.

\subsection{Partitioning}

Given the generating points $P_i$, a Voronoi diagram is a partitioning of space such that a cell contains all points in space which are closer to $P_i$ than any $P_j$. This is formally defined by equation~\ref{eq:3.1} and shown in Figure~\ref{fig:3.4}.

\begin{equation}
\text{Given a set } S=\{p_1, p_2\dotsc p_n\} \quad \text{A Cell } C(S,p_i)=\{p\in R^d\mid |p-p_i|<|p-p_j|, i\neq j\}
\label{eq:3.1}
\end{equation}

\begin{figure}
\centerline{\includegraphics[scale=0.25]{VoronoiEx.png}}
\caption{A Voronoi diagram\cite{voronoipict}.}
\label{fig:3.4}
\end{figure}

A fragment object is made for each generating point and all voxels are looped over. For each voxel, all generating points are checked and the closest found. That voxel is then added to the corresponding fragment object, also updating the minimum and maximum coordinates for that fragment, and the voxel is given the correct integer colouring in the new grid.

\subsection{Finding Islands}

\label{sect:islands}

A Voronoi partitioning is always guaranteed to produce convex solids when applied to a convex solid. However, as Dynamic Volumetric Fragmentation works on concave models this cannot be relied on. If a partitioning spans a concavity then it may produce unconnected islands as shown in Figure~\ref{fig:3.5}. Meshing such a partition into a rigid solid would result in floating areas as the physics engine cannot reason within a mesh as seen in Figure~\ref{fig:3.5.1}.

\begin{figure}
\centerline{\includegraphics[scale=0.5]{island13.pdf}}
\caption{The blue Voronoi cell creates two unconnected partitions of the concave object.}
\label{fig:3.5}
\end{figure}

\begin{figure}
\centerline{\includegraphics[scale=0.5]{islands.png}}
\caption{If the unconnected ears and body are a single mesh then the physics engine cannot act on the ears causing them to fall.}
\label{fig:3.5.1}
\end{figure}

To find and remove any islands a flood fill algorithm is used. Algorithms \ref{alg:flinit} and \ref{alg:flood} demonstrate how this works.

\begin{algorithm}[]
 \KwData{Dictionary of fragments indexed by colour: d, Greatest fragment colour: c, Coloured grid with islands: g}
 \KwResult{Dictionary of new fragments with no islands: o, Coloured grid with no islands: g}
 Dictionary$<$integer, fragment$>$ o\;
 \For{Each fragment f in d}{
 	\For{Each voxel v in f}{
 		\If{g[v.x,v.y,v.z] == f.colour}{
 			Fragment r\;
 			r.colour = ++c\;
 			o.Store(r.colour, r)\;
 			Flood(v.x, v.y, v.z, f.colour, r.colour, r, o)\;
 		}
 	}
 }
 \caption{Flood initiation}
 \label{alg:flinit}
\end{algorithm}

\begin{algorithm}[]
 \KwData{Vector to flood from: v, Old colouring: f, New colouring: r, Dictionary of fragments indexed by colour: o, Coloured grid with islands: g}
 \KwResult{Dictionary of new fragments with no islands: o, Coloured grid with no islands: g}
 Queue$<$Vector$>$ neighbours\;
 HashSet$<$Vector$>$ visited\;
 neighbours.Enqueue(v)\;
 visited.Add(v)\;
 \While{neighbours is nonempty}{
 	Vector deq = neighbours.Dequeue()\;

    int x = deq.x\;
    int y = deq.y\;
    int z = deq.z\;

    g[x, y, z] = r\;

    colouring.Add(v)\;

    \For{i from -1 to 1} {
        \For{j from -1 to 1} {
            \For{k from -1 to 1} {
                int xi = x + i\;
                int yj = y + j\;
                int zk = z + k\;

                \If{i == 0 AND j == 0 AND k == 0}{continue\;}
                \If{xi out of bounds in g OR yj out of bounds in g OR zk out of bounds in g}{continue\;}

                \If {g[xi, yj, zk] == f}{
                    \If{!(visited.Contains(xi, yj, zk))}{
                        neighbours.Enqueue(xi, yj, zk)\;
                        visited.Add(xi, yj, zk)\;
                    }
                }
            }
        }
    }
 }
 \caption{Flooding}
 \label{alg:flood}
\end{algorithm}

For every voxel in every fragment, if that voxel is still coloured with the same value as that fragment then it has not been reached by a previous flood for that fragment. Therefore it is not connected to the already flooded portion of that fragment and should instead be part of a new fragment. As should all connected voxels found by flooding from the voxel.

\subsection{Progress}

All of the code for this stage of the pipeline was written from scratch. Most time was spent optimising for both time and space complexity once the algorithms used had been implemented.

Debugging was done by partitioning the voxel structure of a cube and colouring the voxels according to their fragments. The generating points were also visualised. This is shown in Figure~\ref{fig:3.6}.

\begin{figure}[b!]
\centerline{\includegraphics[scale=1]{Voronoi.png}}
\caption{A visualisation of the Voronoi partitioning of the voxel structure of a cube.}
\label{fig:3.6}
\end{figure}

\subsection{Advantages}

As discussed, while the partitioning here is done using a Voronoi method which is common when working with surface representations, having a volumetric representation of an object could allow more complex and physically accurate algorithms. For example, the grid of voxels could be taken to represent the crystalline structure of some solids with the `bonds' between neighbouring voxels acting as they would in a real collision.

Also, the method works on both convex and concave models equally which is uncommon in other approaches as discussed in Section~\ref{sect:prob}.

\section{Intermediate Processing}

Before the partitioned voxels can become rigid meshes, preprocessing is needed. This is in order to prepare the data for the different algorithms used.

\subsection{Separating Border Voxels}

For the chosen meshing processes, the voxel grid is trimmed so that only interior border voxels remain, as shown in Figure~\ref{fig:3.7}. The reason for this is that both meshing processes require only the surface of the fragments defined by the voxels and not the solid volume. Separation is done by checking for every voxel whether it has a neighbouring voxel with a different colouring and keeping only those that do.

\begin{figure}[b!]
\centerline{\includegraphics[scale=0.9]{border213.pdf}}
\caption{A fragmented voxelised rectangle. The interior border voxels are green and the exterior voxels are blue. The unneeded interior voxels are red.}
\label{fig:3.7}
\end{figure}

Voxels on the surface of the object, with a non-existent neighbour, are recorded for entry into a k-d~tree.

A k-d tree is a binary tree based data structure which features an average $\mathcal{O}(n\log{}n)$ lookup for the nearest vector in the tree to a given vector in space.

An implementation of k-d trees in {\sc{C\#}} for Unity3D was found and used as there was little point reimplementing a well used data structure\cite{kdtree}.

Voxels both on the surface and on the interior borders with other fragments are also stored in the fragment they belong to.

\section{Mesh Generation}

Once the solid volume for each fragment has been found, it needs to be transformed into a rigid mesh for use in the physics engine. These meshes are constructed via two processes. The first splits the original object mesh and the second forms new meshes around the solid voxel structures.

\subsection{Data Structures}

The mesh partitioning procedure takes as an input the k-d tree of surface voxels from the intermediate processing stage as well as the original object mesh. The output is a list of fragment submeshes and for each one, a k-d tree of the vertices which make up the border of that submesh. These meshes will be referred to as the external meshes. This is shown in Figure~\ref{fig:3.8}.

\begin{figure}[b!]
\centerline{\includegraphics[scale=0.35]{mesh_border.png}}
\caption{A partitioning of the Stanford Bunny mesh. The vertices which make up the border of the green submesh are highlighted in red. The gap between partitions is caused by the loss of triangles which have vertices in different partitions.}
\label{fig:3.8}
\end{figure}

The marching tetrahedra algorithm runs for each fragment and takes as an input the grid of coloured border voxels from the intermediate processing stage as well as the k-d tree of the vertices which make up the fragment's external mesh border as outputted by the mesh partitioning procedure above. The algorithm outputs a mesh which represent the surface defined by the voxels (referred to as the solid mesh), and surface mesh, for that fragment.

\subsection{Mesh Partitioning}

\label{sect:part}

In order to preserve the original surface of the object the correct sections of the original mesh need to be mapped onto the computed fragments.

To do this the original object mesh is partitioned according to the colouring of the nearest voxel for every vertex.

This is the purpose of having all of the surface voxels in a k-d tree. There is no need to have the internal voxels as there will always be a surface voxel which is closer.

The process loops over all triangles and each vertex in that triangle. If all of the vertices have a nearest voxel of the same colouring then that triangle is added to the mesh for the fragment of that colouring. If the nearest voxel colours differ then the triangle is discarded and the vertices are added to the boundary k-d tree for their fragments.

The result of this process is demonstrated in Figure ~\ref{fig:3.8}.

\subsection{Marching Tetrahedra}

\subsubsection{Marching Cubes}

Marching cubes is an algorithm used to extract a polygonal mesh of an implicit surface from a three-dimensional discrete scalar field\cite{Lorensen:1987:MCH:37401.37422}. The binary field of voxels\footnote{The colouring of the voxels is for identifying which fragment they belong to, they are still treated as binary present or not present for meshing purposes.} representing the solid volume of an object in this case is such an example.

The algorithm proceeds through the scalar field, taking a `cube' of eight adjacent locations at a time. The polygon(s) needed to represent the part of the implicit surface that passes through this cube are determined by creating an index into a pre-calculated array of 256 configurations from the eight scalar values.

Ordinarily each vertex of the generated polygons would be placed on the appropriate position along the cube's edge by linearly interpolating the two scalar values that are connected by that edge. However, in this case the scalar values only have two possibilities and so interpolating between them always results in a placement of the vertices half way between the voxels. This leads to a meshed surface which reveals the blocky voxel structure as opposed to a smoother surface which would be extracted if dealing with a field of actual scalars. This is shown in Figures \ref{fig:3.9} and \ref{fig:3.10}.

\begin{figure}[b!]
\centerline{\includegraphics[scale=8]{marchingtetrahedrons.jpg}}
\caption{Marching tetrahedra applied to a scalar field generated from perlin noise\cite{ScrawkMarching}.}
\label{fig:3.9}
\end{figure}
\begin{figure}
\centerline{\includegraphics[scale=0.75]{Marching.png}}
\caption{Marching tetrahedra applied to the voxel grid of a fragmented Stanford Bunny.}
\label{fig:3.10}
\end{figure}

Ambiguous cases are present in the polygonisation where there exist at least two correct interpretations of the implicit surface. This is shown in two dimensions\footnote{These ambiguities would therefore be for the marching squares algorithm but the premise is the same.} in Figure~\ref{fig:3.11}.

\begin{figure}
\centerline{\includegraphics[scale=0.5]{ambiguous.png}}
\caption{The two possible surfaces for the imaginary square shown with dashed lines with two points inside the surface and two outside.}
\label{fig:3.11}
\end{figure}

\clearpage
\subsubsection{Marching Tetrahedra}

Marching tetrahedra is an algorithm based on marching cubes which solves these ambiguities as well as producing a surface which matches the voxel data more closely at the cost of generating more vertices\cite{Tetrahedra}.

In marching tetrahedra, each cube is split into six irregular tetrahedra by cutting the cube in half diagonally three times as shown in Figure~\ref{fig:3.12}. These tetrahedra are then used to find the implicit surface in much the same way as marching cubes however there are now nineteen edge intersections per cube instead of twelve.

\begin{figure}[b!]
\centerline{\includegraphics[scale=0.8]{Marching_tetrahedrons.png}}
\caption{A cube split into six irregular tetrahedra\cite{marchingpict}.}
\label{fig:3.12}
\end{figure}

\clearpage
\subsubsection{Modification}

As two separate meshes are being produced in this stage, a section of the original mesh and a surface representing the solid volume, the two need to be combined and joined.

The marching tetrahedra library used was modified to take the grid of coloured border voxels as well as the set of voxels lying both on the exterior and on the fragment border. The k-d tree of the vertices which make up the fragment's external mesh border is also used. These border voxels are meshed using marching tetrahedra. However, when a voxel also lying on the exterior is found, the calculated vertices are discarded and instead their nearest neighbours in the k-d tree are used. This process knits the gap that would have otherwise existed between the two generated meshes, the external mesh and the solid mesh. A small amount of random noise is also applied to the rest of the vertices in an effort to disguise some of the blocky underlying structure. The results of this can be seen in Figure~\ref{fig:3.13}.

\begin{figure}
\centerline{\includegraphics[scale=0.75]{collision.png}}
\caption{The Stanford Bunny after the entire pipeline has completed.}
\label{fig:3.13}
\end{figure}

\subsection{Progress}

This stage of the pipeline took the longest to complete and was the final milestone when done. The stage went through several iterations of varying success before the above method was devised.

Originally the fragment meshes were to be only generated using marching tetrahedra with no splitting or use of the original external mesh. This resulted in an important detail loss as seen in Figure~\ref{fig:3.10} and was not viable for use. Increasing the voxel resolution improved this but added too much of a computational overhead.

A second method involved only splitting the original external mesh and not using marching tetrahedra at all. The resultant fragment meshes were duplicated and had their normals flipped before being combined. This gave results that resembled hollow porcelain objects as seen in Figure~\ref{fig:3.14}. This could not be used as it did not satisfy the requirement of modelling the internal structure.

\begin{figure}
\centerline{\includegraphics[scale=1]{Porcelain2.png}}
\caption{The Stanford Bunny fractured as if it were a hollow object.}
\label{fig:3.14}
\end{figure}

Producing the final method, involved modifying the marching cubes library found to stitch the external and solid meshes together as discussed. The algorithm found in the library was also optimised. Originally the algorithm would produce duplicate vertices for triangles which should share a vertex. This was solved by using a dictionary of vertices and indices into the vertex list. All vertices required by a triangle are checked in the dictionary, if they exist as a key then the index stored is used else the vertex is added to the vertex list and a new index stored in the dictionary with that vertex and used in the triangle. This dramatically reduced vertex counts in the meshes produced which is necessary as Unity3D imposes a limit of 65,534 vertices for any mesh.

\section{Post-processing}

After the fragment meshes have been generated, some post processing must take place in order for the meshes to be used in the physics simulation.

\subsection{Physics}

\label{sect:postphysics}

One advantage of fragmenting a voxel structure is that the mass of each fragment, $m_f$, can be calculated using Equation~\ref{eq:mass}.

\begin{equation}
\begin{split}
m_f=m_o\times v_f/v_o \quad \text{$v$ is the number of voxels}
\label{eq:mass}
\end{split}
\end{equation}

\subsection{Game-object Generation}

Finally, the fragment meshes and masses are passed to Unity3D so that they can be instantiated into the simulated world. Depending on the number of vertices in each mesh this can add a large time overhead which will be discussed in Section~\ref{sect:over}. This overhead is a limitation of Unity3D and not Dynamic Volumetric Fragmentation.

\section{Result}

\label{sect:result}

The result is a library which can be used to fragment objects on collision based on the physical attributes of the object and of the collision.

The library produced requires that two scripts be attached to the destructible object, one as a driver for the destruction process and the other to allow the physical properties of the object to be defined. A Unity3D object with a `sphere collider' must also be attached with a script which triggers the destruction process as detailed in Section~\ref{sect:pre}. All of these elements are added to an existing object and none require any existing features of the object to be changed.

When an object is given the above attributes and a projectile fired at it, the object is broken into fragments and these fragments then receive force from the projectile causing them to explode out as would be expected. This is shown in Figure~\ref{fig:3.15}.

A video demonstrating the results can be found at \url{https://www.screenr.com/NRQN}.

\begin{figure}
\centerline{\includegraphics[scale=0.7]{voxel_exploded.png}\includegraphics[scale=0.686]{voxel_exploded2.png}}
\caption{Fragments exploding out of the Stanford Bunny after a cubic projectile, shown in red, has been fired at it.}
\label{fig:3.15}
\end{figure}

The nature of the fragmentation differs depending on the forces involved as shown in Figure~\ref{fig:3.16}.

\begin{figure}
\centerline{\includegraphics[scale=0.85]{voxel_forces.png}}
\caption{The biggest fragments after three Stanford Bunnies have been fragmented. Compared to the middle, the right was given a higher strength while the left was hit with a faster projectile.}
\label{fig:3.16}
\end{figure}

\section{Conclusion}

In order for the proposed solution to be realised, four stages of implementation had to take place:

\begin{enumerate}
\item{Preprocessing}
\label{point:pre}
\item{Voxelisation}
\label{point:vox}
\item{Meshing}
\label{point:mesh}
\item{Postprocessing}
\label{point:post}
\end{enumerate}

Intermediate stages were also completed to process data passed between the above sections.

Points \ref{point:vox} and \ref{point:mesh} required adapting existing implementations of the algorithms used whereas the remaining sections were developed from scratch.