%!TEX root = ../thesis.tex
%*******************************************************************************
%*********************************** Second Chapter *****************************
%*******************************************************************************

\chapter{Formulations of the Relativistic Hydrodynamics}  %Title of the Second Chapter

\ifpdf
    \graphicspath{{Chapter2/Figs/PDF/}{Chapter2/Figs/}}
\else
    \graphicspath{{Chapter2/Figs/}}
\fi

%********************************** %First Section  **************************************
\section{Relativistic Hydrodynamics} %Section - 2.1
In the previous chapter, we explored the formulation of the left hand side of the Einstein equations.
In this chapter, we focus on the right hand side of the equations,
specifically the 3+1 treatment of perfect fluid in conservative form \cite{marti1991numerical,rezzolla2013relativistic}.

\subsection{Perfect fluid}
\label{section2.1.1}
In this section, we consider relativistic \textit{perfect fluid} (i.e. no viscous effects and heat fluxes).
The energy-momentum tensor of perfect fluid is given by
\begin{align}
    T^{\mu\nu} = \rho h u^\mu u^\nu + p g^{\mu\nu},
\end{align}
where $\rho$ is the rest-mass density,
$u^\mu$ is the fluid 4-velocity,
$h = 1 + \epsilon + \frac{p}{\rho}$ is the enthalpy,
$p$ is the pressure,
and $\epsilon$ is the specific internal energy.\\
The \textit{Lorentz factor} $W$ of the fluid with respects to the Eulerian observers is given by
the projection of fluid 4-velocity $u^\mu$ to $n^\mu$
\begin{align}
    W \coloneqq - n_{\mu} u^\mu = \alpha u^t.
\end{align}
Thus, the spatial 4-velocity of a fluid measured by Eulerian observers is
\begin{align}
    v^\mu \coloneqq \frac{\gamma_{\nu}{}^{\mu} u^\nu} {W},
\end{align}
or in component form
\begin{align}
    v^t &= 0, & v^i &=  \frac{u^i}{W} + \frac{\beta^i}{\alpha}, \\
    v_t &= \beta_i v^i, & v_i &= \frac{u_i}{W}.
\end{align}
As a result, the \textit{Lorentz factor} can also be written as
\begin{align}
    W = \frac{1}{\sqrt{1-v_i v^i}}.
\end{align}
The dynamics of fluid are governed by the equations of rest-mass conservation and energy momentum conservation.
The system is closed by the equation of state (EOS) of the fluid,
which reflects the thermodynamic properties of the fluid at a macroscopic level.
Here, we consider two common analytic equation of state as follows:
\begin{enumerate}
    \item Ideal-gas
    \begin{align}
        p = (\Gamma-1)\rho \epsilon,
    \end{align}
    where $\Gamma$ is the polytropic index of the gas.
    \item Polytropic EOS
    \begin{align}
        p = K\rho^\Gamma,
    \end{align}
    where $\Gamma$ again is the polytropic index the gas, and $K$ is a constant of proportionality.
\end{enumerate}

\subsection{Rest-mass conservation}
\label{section2.1.2}
The general-relativistic conservation of rest-mass is given by
\begin{align}
    \nabla_\mu J^\mu &= 0, & J^\mu &\coloneqq \rho u^\mu,
\end{align}
where $J^\mu$ is the rest-mass current density.
Under 3+1 decomposition, the rest-mass conservation can be written as
\begin{align}\label{eq:mass_cons}
    \partial_t \left(\sqrt{\gamma}D\right) + \partial_i \left[\sqrt{\gamma} D \left(\alpha v^i - \beta^i \right) \right] = 0,
\end{align}
where
\begin{align}
    D \coloneqq \rho \alpha u^t = \rho W,
\end{align}
is the conserved quantity.

\subsection{Energy and momentum conservation}
\label{section2.1.3}
Other than the conservation of rest-mass, the energy and momentum conservation of the fluid must also be satisfied
\begin{align}
    \nabla_\nu T^{\mu\nu} = 0.
\end{align}
Following the 3+1 decomposition of stress-energy tensor introduced in equation (\ref{eq:T_decompose}),
the fluid quantities in the case of perfect fluid become
\begin{align}
    S^{\mu\nu} &= \rho h W^2 v^\mu v^\nu + p \gamma^{\mu\nu}, \\
    S^\mu &= \rho h W^2 v^\mu, \\
    E &= \rho h W^2 - p.
\end{align}
The conservation of energy and momentum hence leads to
\begin{align}
    &\partial_t \left( \sqrt{\gamma} S_j \right) + \partial_i \left[\sqrt{\gamma} \left(\alpha S^i{}_j - \beta^i S_j\right) \right]
    = \sqrt{\gamma} \left(\frac{1}{2} \alpha S^{ik} \partial_j \gamma_{ik} + S_i \partial_j \beta^i - E \partial_j \alpha\right), \label{eq:mom_cons} \\
    &\partial_t \left( \sqrt{\gamma} E \right) + \partial_i \left[ \sqrt{\gamma} \left(\alpha S^i - \beta^i E \right) \right]
    = \sqrt{\gamma} \left(\alpha K_{ij} S^{ij} - S^i \partial_i \alpha \right). \label{eq:E_cons}
\end{align}
Equation (\ref{eq:E_cons}) can also be written as
\begin{align}
    &\partial_t \left( \sqrt{\gamma} \tau \right) + \partial_i \left[\sqrt{\gamma} \left(\alpha\left(S^i - D v^i \right) - \beta^i \tau \right)\right]
    = \sqrt{\gamma} \left(\alpha K_{ij} S^{ij} - S^i \partial_i \alpha \right). \label{eq:tau_cons},
\end{align}
to obtain better numerical accuracy,
where the conserved quantity $\tau$ is defined as
\begin{align}
    \tau \coloneqq E - D.
\end{align}

\subsection{Conservative form of hydrodynamics equations}
\label{section2.1.4}
Here, we summarize \cref{eq:mass_cons,eq:mom_cons,eq:tau_cons} and express in conservative form
\begin{align}
    \partial_t \left(\sqrt{\gamma} \mathbf{Q} \right) \partial_i \left(\sqrt{\gamma} \mathbf{F}^i \right) = \sqrt{\gamma} \mathbf{S},
\end{align}
where the conserved variables $\mathbf{Q}$, flux terms $\mathbf{F}^i$ and source terms $\mathbf{S}$ are
\begin{align}
    & \mathbf{Q} =
    \begin{pmatrix}
    D \\
    S_j \\
    \tau
    \end{pmatrix}
    =
    \begin{pmatrix}
    \rho W \\
    \rho h W^2 v_j \\
    \rho h W^2 - p - D
    \end{pmatrix},\\
    & \mathbf{F}^i =
    \begin{pmatrix}
    D\left(\alpha v^i -\beta^i \right) \\
    S_j \left( \alpha v^i - \beta^i \right) + \alpha \delta^i{}_j p \right) \\
    \tau left( \alpha v^i - \beta^i \right) + \alpha p v^i \right)
    \end{pmatrix},\\
    & \mathbf{S} =
    \begin{pmatrix}
    0 \\
    \frac{1}{2} \alpha S^{ik} \partial_j \gamma_{ik} + S_i \partial_j \beta^i - E \partial_j \alpha \\
    \alpha K_{ij} S^{ij} - S^i \partial_i \alpha
    \end{pmatrix},
\end{align}
which is commonly known as the "\textit{Valencia formulation}" of the relativistic-hydrodynamics equatons. \\
The characteristic speeds of such system is given by
\begin{align}\label{eq:valencia}
    \lambda_0 &= \alpha v^i - \beta^i \qquad \text{(triple eigenvalue)},\\
    \lambda_{\pm} &= \frac{\alpha}{1-v^2 c_s^2} \left\{ v^i \left(1-c_s^2 \right)
    \pm c_s^2 \sqrt{\left(1-v^2 \right) \left[\gamma^ii \left(1- v^2 c_s^2 \right) - {v^i}^2\left(1-c_s^2 \right) \right]} \right\},
\end{align}
where $\lambda_{\pm}$ measures the propagation speeds of the \textit{acoustic waves} of the system,
and $\lambda_0$ corresponds to the propagation speed of \textit{matter waves}.

\subsection{Conserved to Primitive variables conversion}
\label{section2.1.5}
It is not trivial to convert the conserved variables $\left(D,S_i,\tau\right)$ introduced in section \ref{section2.1.4}
to primitive variables $\left(\rho, W, v^i, p\right)$ in relativistic hydrodynamics.
One must solve non-linear equations numerically.
In \texttt{Gmunu}, we adopted the routine used in \cite{galeazzi2013implementation}.
The implementation details are included here:
\begin{Step}
    \item Calculate the rescaled variables and some useful relations which are fixed during the iterations
    \begin{align}
        S &\coloneqq \sqrt{S_i S^i}, \\
        r &\coloneqq \frac{S}{D}, & q &\coloneqq \frac{\tau}{D}, & k &\coloneqq \frac{S}{\tau + D}.
    \end{align}
    \item Determine the bounds of the root
    \begin{align}
        z_- &\coloneqq \frac{k/2}{\sqrt{1-k^2/4}}, & z_+ &\coloneqq \frac{k}{\sqrt{1-k^2}}.
    \end{align}
    \item In the inverval $\left[z_-, z_+ \right]$, we solve
    \begin{align}\label{eq:cons2prim_root}
        f(z) = z - \frac{r}{\hat{h}(z)},
    \end{align}
    where
    \begin{align}
        \hat{h}(z) &= \left(1+\hat{\epsilon}(z) \right) \left( 1+ \hat{a}(z) \right),
    \end{align}
    \begin{align}
        \hat{\epsilon}(z) &= \hat{W}(z)q - zr + \frac{z^2}{1+\hat{W}(z)},
        & \hat{a}(z) &= \frac{\hat{p}(z)}{\hat{\rho}(z)\left( 1 + \hat{\epsilon}(z) \right) },
    \end{align}
    \begin{align}
        \hat{p}(z) &= p\left(\hat{\rho}(z), \hat{\epsilon}(z) \right),
        & \hat{\rho}(z) &= \frac{D}{\hat{W}(z)},
        & \hat{W}(z) &= \sqrt{1+z^2}.
    \end{align}
    Equation (\ref{eq:cons2prim_root}) is solved using Illinois algorithm in \texttt{Gmunu}.
    Note that during the iterations, we enforce the density $\rho$ and the specific energy $\epsilon$ fail into the validity region of the EOS,
    i.e., we evalue the updated $\rho$ and $\epsilon$ with
    $\hat{\rho}(z) = \max\left(\min\left(\rho_\max{},\hat{\rho}\right),\rho_\min{}\right)$ and
    $\hat{\epsilon}(z) = \max\left(\min\left(\epsilon_\max{},\hat{\epsilon}\right),\epsilon_\min{}\right)$.
    \item With the root $z_0$ of \cref{eq:cons2prim_root},
    we can then work out the primitive variables $\left(\rho, \epsilon, p\right)$ respectively with the equations used in step 3.
    For the velocity $v^i$, it can be obtained with $z$ by
    \begin{align}
        \hat{v}^i(z) = \frac{S^i/D}{\hat{h}(z)\hat{W}(z)}.
    \end{align}
\end{Step}

%********************************** %Second Section  *************************************
\section{The reference-metric formalism} %Section - 2.2
\label{section2.2}
The reference-metric formalism, a generalization of the "\textit{Valencia}" formulation, was original proposed by Montero \cite{montero2014general} in 2014 for general relativistic hydrodynamics (GRHD)
and later extended to ideal magnetohydrodynamics.
With the conformal decomposition introduced in section \ref{section1.3.1},
the determinant of the spatial metric can be rewritten as
\begin{align}\label{eq:reference_metric_1}
    \begin{split}
    \sqrt{\gamma} &= \psi^6 \sqrt{\tilde{\gamma}} \\
    &= \sqrt{\hat{\gamma}} \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}},
    \end{split}
\end{align}
where $\hat{\gamma}_{ij}$ is the \textit{time-independent reference metric}
which can be chosen to fit the mesh grid in curvilinear coordinate.
Therefore, the "\textit{Valencia}" formulation in equation (\ref{eq:valencia}) can be generalized as
\begin{align}
    \partial_t \mathbf{q} + \hat{\nabla}_i \mathbf{f}^i = \mathbf{s},
\end{align}
where $\hat{\nabla}_i$ is the corvariant derivatives sociated with the time-independent reference metric $\hat{\gamma}_{ij}$,
$\left(\mathbf{q},\mathbf{f}^i,\mathbf{s}\right)$ are the $\textit{conformally rescaled}$ conserved variables,
fluxes and source terms respectively.\\
Comparing to the "\textit{Valencia}" formulation,
the hydrodynamical equations in reference-metric approach are numerically more accurate in curvilinear coordinates in multi-dimensional simulation,
especially when symmetry is imposed.
Equation (\ref{eq:reference_metric_1}) can be further written as
\begin{align}
    \partial_t \mathbf{q} + \frac{1}{\sqrt{\hat{\gamma}}}\partial_j \left(\sqrt{\hat{\gamma}} \mathbf{f}^j \right) = \mathbf{s} + \mathbf{s}_{geom},
\end{align}
where $\mathbf{s}_{geom}$ are the \textit{geometrical} source terms
which contain the 3-Christoffel symbols $\hat{\Gamma}^i{}_{jk}$ associated with the reference metric $\hat{\gamma}_{ij}$. \\
Note that the momentum conservation in this expression satisfy to \textit{machine precision} rather than to the level of truncation error
due to the fact that the geometrical source terms $\mathbf{s}_{geom}$ are identically vanishing
for the components associated with ignorable coordinates in the metric.

\subsection{General relativistic hydrodynamics (GRHD) equations}
\label{section2.2.1}
The equations of relativistic hydrodynamics in reference-metric approach is given by
\begin{align}
    \partial_t \left( q_{D} \right) + \frac{1}{\sqrt{\hat{\gamma}}} \partial_j \left[ \sqrt{\hat{\gamma}} \left( f_{D} \right)^j \right]
    &= 0, \\
    \partial_t \left( q_{S_i} \right) + \frac{1}{\sqrt{\hat{\gamma}}} \partial_j \left[ \sqrt{\hat{\gamma}} \left( f_{S_i} \right)^j \right]
    &= s_{S_i} + \hat{\Gamma}^l{}_{ik}\left( f_{S_l} \right)^k, \\
    \partial_t \left( q_{\tau} \right) + \frac{1}{\sqrt{\hat{\gamma}}} \partial_j \left[ \sqrt{\hat{\gamma}} \left( f_{\tau} \right)^j \right]
    &= s_{\tau}, \\
\end{align}
The conformally rescaled conserved quantities $\mathbf{q}$ are
\begin{align}
    q_D & \coloneqq \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} D = \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} \left( \rho W \right), \\
    q_{S_i} & \coloneqq \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} S_i = \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} \left( \rho h W^2 v_i \right), \\
    q_\tau & \coloneqq \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} \tau = \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} \left( \rho h W^2 - p - D \right).
\end{align}
The flux terms $\mathbf{f}^i$ are
\begin{align}
    \left(f_D \right)^i & \coloneqq \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} \left( D \hat{v}^i \right), \\
    \left(f_{S_j} \right)^i & \coloneqq \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} \left(S_j \hat{v}^i + \delta^i{}_j \alpha p \right), \\
    \left(f_\tau \right)^i & \coloneqq \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}} \left(\tau \hat{v}^i + \alpha p v^i \right),
\end{align}
where $\hat{v}^i \coloneqq \alpha v^i -\beta^i$.\\
Finally, the source terms $\mathbf{s}$ are
\begin{align}
    s_D &= 0, \\
    s_{S_i} &= \alpha \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}}
    \left[ - T^{00} \alpha\partial_i \alpha + T^0{}_k \hat{\nabla}_i \beta^k
    + \frac{1}{2} \left( T^{00} \beta^j \beta^k + 2 T^{0j} \beta^k + T^{jk} \right) \hat{\nabla}_i \gamma_{jk} \right], \\
    s_\tau &= \alpha \psi^6 \sqrt{\tilde{\gamma}/\hat{\gamma}}
    \left[ T^{00} \left(K_{ij}\beta^i \beta^j - \beta^k \partial_k \alpha \right)
    + 2 T^{0j} \left( 2 K_{jk} \beta^k - \partial_j \alpha \right)
    + T^{ij} K_{ij} \right].
\end{align}


\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amsfonts,tikz,hyperref}
\usepackage{fontenc}
\usepackage{graphicx}
\usepackage[euler-digits]{eulervm}
\title{FinElt Quick Start Guide}
\author{William McLean}
\date{\today}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\maketitle
To use FinElt you need to install \href{www.julialan.org}{Julia}~and
\href{www.geuz.org/gmsh/}{Gmsh}~\cite{Gmsh}.  Versions for Windows or
OS~X can be downloaded from the project websites.  Under Linux, you
might be able to use your distribution's package manager.  For
example, I develop FinElt on \href{www.fedoraproject.org}{Fedora~31},
and can simply do
\begin{verbatim}
# dnf install julia gmsh
\end{verbatim}
At the time of writing (January 2020), this command installs Julia~1.2.0 and
Gmsh~4.4.1.

Whatever platform you are using, once Julia is installed you can
easily set up FinElt:
\begin{verbatim}
julia> Pkg.clone("https://github.com/billmclean/FinElt.jl")
\end{verbatim}
This guide will walk you through two examples.  The first is a
``hello world'' problem, that explains the basic usage of FinElt.
The second is more elaborate and shows more of the capabilities of
the package.  The source code for both problems is in the
\texttt{examples/keyhole} directory of the package on github.
You should copy this directory to a convenient location.

After working through these two examples, I recommend that you
download and study the
\href{http://www.geuz.org/gmsh/doc/texinfo/gmsh.pdf}{Gmsh manual}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{First Example}

Consider the keyhole-shaped region~$\Omega$ shown in
Figure~\ref{fig: simple bvp}, with boundary~$\Gamma=\partial\Omega$.
We seek the solution~$u$ of the Poisson problem
\begin{equation}\label{eq:  simple bvp}
\begin{aligned}
-\nabla^2 u&=4&&\text{in $\Omega$,}\\
u&=0&&\text{on $\Gamma$,}
\end{aligned}
\end{equation}
where $\nabla^2u=\nabla\cdot(\nabla u)=u_{xx}+u_{yy}$ denotes the
Laplacian of~$u$. Recall that the Sobolev space~$H^1(\Omega)$
consists of the functions in~$L_2(\Omega)$ whose first-order, weak
partial derivatives also belong to~$L_2(\Omega)$, and that
\[
H^1_0(\Omega)=\{\,v\in H^1(\Omega):\text{$u=0$ on~$\partial\Omega$}
	\,\}.
\]
The first Green identity asserts that
\begin{equation}\label{eq: first Green}
\int_\Omega\nabla u\cdot\nabla v=\int_\Omega(-\nabla^2 u)v
	+\int_{\partial\Omega}\frac{\partial u}{\partial n}\,v,
\end{equation}
where $\boldsymbol{n}$ denotes the outward unit normal to~$\Omega$,
and consequently we say that $u\in H^1_0(\Omega)$ is a \emph{weak
solution} of the boundary-value problem~\eqref{eq:  simple bvp} if
\begin{equation}\label{eq: weak bvp}
\int_\Omega\nabla u\cdot\nabla v=\int_\Omega 4v
	\quad\text{for all $v\in H^1_0(\Omega)$.}
\end{equation}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
\caption{A simple boundary-value problem.}
\label{fig: simple bvp}
\begin{center}
\begin{tikzpicture}[scale=1.5]
\draw[blue, thick] (-1,0) -- (-1,-2) -- (1,-2) -- (1,0);
\draw[blue, thick] (1,0) arc
[radius=sqrt(2), start angle=-45, end angle=225];
\node at (0,0.5) {$-\nabla^2u=4$};
\node[above,right] at (1,2) {$u=0$};
\end{tikzpicture}
\end{center}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
\caption{Reading the geometry description file into Gmsh}
\label{fig: open file}
\begin{center}
\includegraphics[scale=0.3]{images/open_geo_file.png}
\end{center}
\end{figure}

\begin{figure}
\caption{The Gmsh options window.}
\label{fig: options}
\begin{center}
\includegraphics[scale=0.4]{images/options.png}
\end{center}
\end{figure}

\begin{figure}
\caption{A triangulation of $\Omega$.}
\label{fig: triangulation}
\begin{center}
\includegraphics[scale=0.3]{images/triangulation.png}
\end{center}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paragraph{Geometry description.}
To compute a numerical approximation to this weak solution, we start
by triangulating $\Omega$.  Use a text editor to read the
geometry description file~\verb!keyhole.geo! and observe how the
domain~$\Omega$ is defined by first specifying the coordinates of
points around its boundary, and then specifying how these points are
connected by line segments or circular arcs whose union is~$\Gamma$.
Notice that Gmsh thinks of $\Omega$ as a surface in 3D (lying in the
plane~$z=0$).

Start Gmsh and use the \verb!File! menu to open
\verb!keyhole.geo! as shown in Figure~\ref{fig: open file}.
From the \verb!Tools! menu, open the \verb!Options! window, select
\verb!Geometry! in its left pane, and tick the checkbox to display
\verb!Point labels!; see Figure~\ref{fig: options}.  The main Gmsh
window should now display the keyhole domain~$\Omega$ and show the
locations of the points defined in \verb!keyhole.geo!.

\paragraph{Mesh generation.}
To generate a triangulation, click on the \verb!+! next to
the \verb!Mesh! label in the left pane of the main Gmsh window and
then click on \verb!2D!.  The result should look something like
Figure~\ref{fig: triangulation}.  From the \verb!File! menu, select
the \verb!Export ...! option to create a text file
\verb!keyhole.msh!.

\paragraph{Important:} FinElt does not support more recent Gmsh file
formats, so when the \verb!MSH Options!  window opens you must select
\verb!Version 2 ASCII! from the drop-down menu.

\paragraph{Finite element solution.}
Let $\Omega_h$ denote the triangulated domain, where, in the customary
way, $h$ is the maximum diameter of the triangles.  Since $\Omega_h$
is a polygon it can only approximate $\Omega$, whose boundary
$\Gamma$ contains circular arcs.  We introduce the finite element
space~$\mathcal{S}_h$ made up of the functions
$v:\Omega_h\to\mathbb{R}$ that are continuous, piecewise-linear and
vanish on~$\partial\Omega_h$.  The finite element
solution~$u_h\in\mathcal{S}_h$ is then defined by requiring that
\begin{equation}\label{eq: finite elt problem}
\int_{\Omega_h}\nabla u_h\cdot\nabla v=\int_{\Omega_h} 4v
	\quad\text{for all $v\in\mathcal{S}_h$,}
\end{equation}
which is a finite-dimensional approximation to the variational
problem~\eqref{eq: weak bvp}.

\paragraph{Julia script.}
Use a text editor to read the file \verb!keyhole.jl!.  This
Julia script begins by reading the mesh data file \verb!keyhole.msh!
and creating a data structure called \verb!mesh! that stores (amongst
other things) the coordinates of the vertices of the triangulation as
well as the connectivity matrix that specifies which points make up
each triangle.  Look in the file
\verb!src/FinElt/Gmsh.jl! to see how this data structure is defined via
the \verb!Mesh! type.

The script then creates a second data structure~\verb!vp! that
describes the variational problem; look in \verb!FinElt/FEM.jl!.  We
specify that an essential (that is, Dirichlet) boundary condition
applies over all of~$\Gamma$.  (Zero boundary values are assumed by
default.)  Next, we specify the bilinear form on the LHS
of~\eqref{eq: finite elt problem}, and the linear functional on the
RHS.

Once \verb!vp! is completely specified, the script generates the
(sparse) linear system for the degrees of freedom, that is, the
values of~$u_h$ at the interior nodes of the triangulation.  This
linear system is solved using the \verb!\! operator and the full
nodal vector~\verb!u! is constructed by including the values at both
the free and fixed nodes (the latter being all zeros).  As output,
the script writes a postprocessing file \verb!keyhole.pos!.

\paragraph{Output and visualization.}
Execute the script in the usual way:
\begin{verbatim}
julia> include("keyhole.jl")
\end{verbatim}
To visualize the solution, return to the Gmsh main window.  From
the \verb!File! menu, select \verb!Open! and choose
\verb!keyhole.pos!; the result should look like
Figure~\ref{fig: postprocess}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
\caption{View after merging the postprocessing file.}
\label{fig: postprocess}
\begin{center}
\includegraphics[scale=0.4]{images/postprocess.png}
\end{center}
\end{figure}

\begin{figure}
\caption{The Warp plugin.}
\label{fig: Warp}
\begin{center}
\includegraphics[scale=0.4]{images/warp.png}
\end{center}
\end{figure}

\begin{figure}
\caption{View after warping the surface.}
\label{fig: warped surface}
\begin{center}
\includegraphics[scale=0.4]{images/warped_surface.png}
\end{center}
\end{figure}

\begin{figure}
\caption{View after using the mouse to rotate the surface in 3D.}
\label{fig: 3D view}
\begin{center}
\includegraphics[scale=0.4]{images/3Dview.png}
\end{center}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

In the left pane of the Gmsh window, under \verb!Post-processing!,
are two check boxes labelled \verb!u!~and \verb!u_warp!.
Uncheck the second of these; the display should now look more
reasonable.  However, because Gmsh is really a 3D mesh generator,
when solving a 2D problem we have to use something
of a kludge to obtain a surface plot of the solution.  From the
\verb!Tools! menu, open the \verb!Plugins! window,
scroll to the bottom of its left pane and select \verb!Warp!.  In the
right pane, change \verb!View! from \verb!-1! to \verb!0!, and change
\verb!OtherView! from~\verb!-1! to~\verb!1!; see Figure~\ref{fig:
Warp}.  After clicking the \verb!Run! button, you should see something
like Figure~\ref{fig: warped surface}.  By left-clicking and dragging
the display, you can rotate the surface to obtain a view like the one
in Figure~\ref{fig: 3D view}.

\paragraph{Exercise.}
Solve the problem again using a finer mesh.  Hint: select \verb!Mesh!
in the left pane of the \verb!Options! window, choose the
\verb!General! tab and adjust the \verb!Min/Max element size!.  You
might also want to go to the \verb!Visibility! tab and
uncheck the \verb!Surface edges! box
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{Second Example}
Suppose now that $\Omega$ is the keyhole-shaped region with an
interior circular hole shown in Figure~\ref{fig: complicated bvp}.
We want to find $u$ satisfying $-\nabla\cdot(a\nabla u)=f$
in~$\Omega$, where the coefficient $a(x)$ and source term~$f(x)$ are
piecewise constant: $a=1$~and $f=1$ in the part of~$\Omega$ that is
shaded light blue, whereas $a=10$~and $f=4$ in the part shaded
light green. In addition, we impose Dirichlet boundary conditions on
the parts of~$\Gamma=\partial\Omega$ coloured dark blue or black, and
Neumann conditions on the part coloured violet or red.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
\caption{A more complicated boundary-value problem.}
\label{fig: complicated bvp}
\begin{center}
\begin{tikzpicture}[scale=1.5]
\path[fill=blue!10] (-1,0) -- (-1,-2) -- (1,-2) -- (1,0)
arc [radius=sqrt(2), start angle=-45, end angle=225];
\draw[blue,thick] (1,0)
arc [radius=sqrt(2), start angle=-45, end angle=225];
\draw[red,thick,fill=white] (0,1) circle [radius=sqrt(2)/2];
\draw[green!40,fill=green!40] (-0.5,-0.5) -- (-0.5,-1.5) --
(0.5,-1.25) -- (0.5, -0.75) -- (-0.5,-0.5);
\draw[black,thick] (-1,-2) -- (1,-2);
\node[above,blue] at (0,2.4142) {$u=-|\boldsymbol{x}|/2$};
\node[below] at (0,-2) {$u=0$};
\draw[violet,ultra thick] (-1,0) -- (-1,-2);
\node[left,violet] at (-1.0,-1.0)
{$\dfrac{\partial u}{\partial n}=-1$};
\draw[violet,ultra thick] (1,0) -- (1,-2);
\node[right,violet] at (1.0,-1.0)
{$\dfrac{\partial u}{\partial n}=-1$};
\node[red] at (0,1) {$\dfrac{\partial u}{\partial n}=0$};
\node at (-4,2) {$-\nabla\cdot(a\nabla u)=f$};
\draw[blue!10,fill=blue!10] (-4.5,1) -- (-3.5,1) -- (-3.5,0)
-- (-4.5,0) -- (-4.5,1);
\node at (-4,0.75) {$a=1$};
\node at (-4,0.25) {$f=1$};
\draw[green!40,fill=green!40] (-4.5,-1) -- (-3.5,-1) -- (-3.5,-2)
-- (-4.5,-2) -- (-4.5,-1);
\node at (-4,-1.25) {$a=10$};
\node at (-4,-1.75) {$f=4$};
\end{tikzpicture}
\end{center}
\end{figure}

\begin{figure}
\caption{The computed solution for the second example.}
\label{fig: second soln}
\begin{center}
\includegraphics[scale=0.4]{images/complic_keyhole.png}
\end{center}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paragraph{Weak formulation.}
Define the trial set~$\mathcal{S}$ and test space~$\mathcal{T}$ by
\begin{align*}
\mathcal{S}&=\{\,v\in H^1(\Omega):
\text{$v=-|x|/2$ for $x\in\text{DarkBlue}$, $v=0$ for
$x\in\text{Black}$}\,\},\\
\mathcal{T}&=\{\,u\in H^1(\Omega):
\text{$v=0$ for $x\in\text{DarkBlue}\cup\text{Black}$}\,\}.
\end{align*}
Based on the first Green identity~\eqref{eq: first Green}, the weak
solution~$u\in\mathcal{S}$ satisfies
\begin{multline*}
\int_{\text{LightBlue}}\nabla u\cdot\nabla v
	+10\int_{\text{LightGreen}}\nabla u\cdot\nabla v\\
	=\int_{\text{LightBlue}}v+\int_{\text{LightGreen}}4v
	-\int_{\text{Violet}}v
\quad\text{for all $v\in\mathcal{T}$.}
\end{multline*}

\paragraph{Finite element approximation.}
We approximate $\Omega$ by a triangulated polygon~$\Omega_h$ and
define a finite dimensional trial set~$\mathcal{S}_h$ that consists
of all continuous, piecewise-linear functions~$v$ such that
\[
v(\boldsymbol{x})=\begin{cases}
-|\boldsymbol{x}|/2,&
\text{$\boldsymbol{x}$ is a node in~$\text{DarkBlue}_h$,}\\
0,&\text{$\boldsymbol{x}$ is a node in~$\text{Black}_h$,}\\
\end{cases}
\]
where $\text{DarkBlue}_h$~and $\text{Black}_h$ are the parts
of the boundary of~$\Omega_h$ corresponding to $\text{DarkBlue}$~and
$\text{Black}$.  The finite dimensional test
space~$\mathcal{T}_h$ is the set of~$\mathcal{S}_h$ consisting of
those~$v$ that vanish on~$\text{DarkBlue}_h$ and
on~$\text{Black}_h$.  The finite element
solution~$u_h\in\mathcal{S}_h$ is then defined by
\begin{multline*}
\int_{\text{LightBlue}_h}\nabla u_h\cdot\nabla v
	+10\int_{\text{LightGreen}_h}\nabla u_h\cdot\nabla v\\
	=\int_{\text{LightBlue}_h}v+\int_{\text{LightGreen}_h}4v
	-\int_{\text{Violet}_h}v
\quad\text{for all $v\in\mathcal{T}_h$.}
\end{multline*}

\paragraph{Computing and visualizing the solution.}
Use a text editor to look at the geometry description
in \verb!complic_keyhole.geo!, and then look at the source code in
\verb!complic_keyhole.jl!.  Notice that the Julia script runs Gmsh
twice, using the latter's command-line interface.  (The
\verb!-format msh22! option is needed to generate the older file format.)
The first call performs the mesh generation, creating the file
\verb!complic_keyhole.msh!, and the second runs the Gmsh
script \verb!complic_keyhole.script! to display a surface plot of the
solution.  Thus, the whole process requires only the single command
\begin{verbatim}
julia> include("complic_keyhole.jl")
\end{verbatim}
to produce the output shown in Figure~\ref{fig: second soln}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{thebibliography}{0}
\bibitem{Gmsh}
C.~Geuzaine and J.-F.~Remacle. Gmsh: a three-dimensional finite
element mesh generator with built-in pre- and post-processing
facilities. \emph{International Journal for Numerical Methods in
Engineering} 79(11), pp.~1309--1331, 2009.
\end{thebibliography}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}


\documentclass[12pt]{cdblatex}
\usepackage{fancyhdr}
\usepackage{footer}

\begin{document}

% =================================================================================================
% create checkpoint file

\bgroup
\CdbSetup{action=hide}
\begin{cadabra}
   import cdblib
   checkpoint_file = 'tests/semantic/output/geodesic-lsq-midpt.json'
   cdblib.create (checkpoint_file)
   checkpoint = []
\end{cadabra}
\egroup

% =================================================================================================
\section*{Geodesic mid-point for arc-length}

\input{metric.cdbtex}
\input{geodesic-lsq.cdbtex}

This code uses the results of {\tts geodesic-lsq} and {\tts metric} to show that the 2nd and 3rd
order estimates for $L^2_{PQ}$ can be recovered using a mid-point estimate. For the 3rd order estimate
we have
\begin{align*}
   g_{ab}(x) &= \cdb{gab4.601} + \BigO{\eps^4}\\
   L^2_{PQ}  &= \cdb{lsq4.301} + \BigO{\eps^4}
\end{align*}
The code below verifies that
\begin{equation*}
   L^2_{PQ} = g_{ab}(\bar x) Dx^{a} Dx^{b} + \BigO{\eps^4}
\end{equation*}
where $\bar x$ is the \emph{coordinate} midpoint of the geodesic
\begin{equation*}
   {\bar x^a} = \frac{1}{2}\left(x^{a}_{P} + x^{a}_{Q}\right)
\end{equation*}
This result holds true only for the 2nd and 3rd order estimates. Note that the \emph{coordinate} midpoint
is not the \emph{geometric} midpoint of the geodesic.

It might be interesting to see if the higher order estimates could
be recovered by sampling the metric at points other than the mid point.

\clearpage

\begin{cadabra}
   {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w#}::Indices(position=independent).

   \nabla{#}::Derivative.

   g_{a b}::Metric.
   g^{a b}::InverseMetric.

   R_{a b c d}::RiemannTensor.

   import cdblib

   gab = cdblib.get('g_ab','metric.json')

   lsq2 = cdblib.get('lsq2','geodesic-lsq.json')
   lsq3 = cdblib.get('lsq3','geodesic-lsq.json')
   lsq4 = cdblib.get('lsq4','geodesic-lsq.json')
   lsq5 = cdblib.get('lsq5','geodesic-lsq.json')

   substitute (gab,$x^{a}->(p^{a}+q^{a})/2$)   # evaluate rnc gab at mid-point
   distribute (gab)

   defgab := g_{a b} -> @(gab).

   mid := g_{a b} (q^{a}-p^{a}) (q^{b}-p^{b}).

   substitute     (mid,defgab)
   distribute     (mid)
   sort_product   (mid)
   rename_dummies (mid)
   canonicalise   (mid)

   tst2 := @(lsq2) - @(mid).                             # cdb (tst2.201,tst2)
   tst3 := @(lsq3) - @(mid).                             # cdb (tst3.201,tst3)
   tst4 := @(lsq4) - @(mid).                             # cdb (tst4.201,tst4)
   tst5 := @(lsq5) - @(mid).                             # cdb (tst5.201,tst5)

   substitute     (tst2,$Dx^{a} -> q^{a}-p^{a}$)
   substitute     (tst2,$x^{a} -> p^{a}$)
   distribute     (tst2)
   sort_product   (tst2)
   rename_dummies (tst2)
   canonicalise   (tst2)                                 # cdb (tst2.202,tst2)

   substitute     (tst3,$Dx^{a} -> q^{a}-p^{a}$)
   substitute     (tst3,$x^{a} -> p^{a}$)
   distribute     (tst3)
   sort_product   (tst3)
   rename_dummies (tst3)
   canonicalise   (tst3)                                 # cdb (tst3.202,tst3)

   substitute     (tst4,$Dx^{a} -> q^{a}-p^{a}$)
   substitute     (tst4,$x^{a} -> p^{a}$)
   distribute     (tst4)
   sort_product   (tst4)
   rename_dummies (tst4)
   canonicalise   (tst4)                                 # cdb (tst4.202,tst4)

   substitute     (tst5,$Dx^{a} -> q^{a}-p^{a}$)
   substitute     (tst5,$x^{a} -> p^{a}$)
   distribute     (tst5)
   sort_product   (tst5)
   rename_dummies (tst5)
   canonicalise   (tst5)                                 # cdb (tst5.202,tst5)

\end{cadabra}

\clearpage

% =================================================================================================
\section*{Reformatting}

\begin{cadabra}
   def truncateR (obj,n):

   # I would like to assign different weights to \nabla_{a}, \nabla_{a b}, \nabla_{a b c} etc. but no matter
   # what I do it appears that Cadabra assigns the same weight to all of these regardless of the number of subscripts.
   # It seems that the weight is assigned to the symbol \nabla alone. So I'm forced to use the following substitution trick.

       Q_{a b c d}::Weight(label=numR,value=2).
       Q_{a b c d e}::Weight(label=numR,value=3).
       Q_{a b c d e f}::Weight(label=numR,value=4).
       Q_{a b c d e f g}::Weight(label=numR,value=5).

       tmp := @(obj).

       substitute (tmp, $\nabla_{e f g}{R_{a b c d}} -> Q_{a b c d e f g}$)
       substitute (tmp, $\nabla_{e f}{R_{a b c d}} -> Q_{a b c d e f}$)
       substitute (tmp, $\nabla_{e}{R_{a b c d}} -> Q_{a b c d e}$)
       substitute (tmp, $R_{a b c d} -> Q_{a b c d}$)

       ans = Ex(0)

       for i in range (0,n+1):
          foo := @(tmp).
          bah = Ex("numR = " + str(i))
          keep_weight (foo, bah)
          ans = ans + foo

       substitute (ans, $Q_{a b c d e f g} -> \nabla_{e f g}{R_{a b c d}}$)
       substitute (ans, $Q_{a b c d e f} -> \nabla_{e f}{R_{a b c d}}$)
       substitute (ans, $Q_{a b c d e} -> \nabla_{e}{R_{a b c d}}$)
       substitute (ans, $Q_{a b c d} -> R_{a b c d}$)

       return ans

   tst2 = truncateR (tst2,2)  # cdb (tst2.301,tst2)
   tst3 = truncateR (tst3,3)  # cdb (tst3.301,tst3)
   tst4 = truncateR (tst4,4)  # cdb (tst4.301,tst4)
   tst5 = truncateR (tst5,5)  # cdb (tst5.301,tst5)
\end{cadabra}

\clearpage

% =================================================================================================
\section*{Errors is mid-point estimates for $L^2_{PQ}$}

\begin{dgroup*}
   \begin{dmath*} \left(L^2_{PQ} - g_{ab}(\bar x) Dx^a Dx^b\right)_2 = \cdb{tst2.301} \end{dmath*}
   \begin{dmath*} \left(L^2_{PQ} - g_{ab}(\bar x) Dx^a Dx^b\right)_3 = \cdb{tst3.301} \end{dmath*}
   \begin{dmath*} \left(L^2_{PQ} - g_{ab}(\bar x) Dx^a Dx^b\right)_4 = \cdb{tst4.301} \end{dmath*}
   \begin{dmath*} \left(L^2_{PQ} - g_{ab}(\bar x) Dx^a Dx^b\right)_5 = \cdb{tst5.301} \end{dmath*}
\end{dgroup*}

% =================================================================================================
% export checkpoints in json format

\bgroup
\CdbSetup{action=hide}
\begin{cadabra}
   for i in range( len(checkpoint) ):
      cdblib.put ('check{:03d}'.format(i),checkpoint[i],checkpoint_file)
\end{cadabra}
\egroup

\end{document}