%!TEX root = ../dissertation.tex

\chapter{Background: State of the art}
\label{chapter:evaluation}
\section{Planning Optimal Grasps}
\label{section:LMRW}

This paper \cite{ferrari1992planning} explains the metric of the "Largest-minimum resisted wrench" that attempts to find a largest resisted wrench in any direction. To do this, the metric takes into account the total fingers force and the maximum of all forces done by each finger.
\par
It is assumed that the grasp's configuration used is a Force Closure Grasp (FCG), whose definition is a grasp that is able to balance externally applied forces and torques on the object.
It is also assumed that the contacts between the object and the points of contact are "Hard-Contact", i.e. between the two contact surfaces (of the object and the contact point) exists friction.
\par
The forces and torques that acts on an object or on contact points can be represented in a 6 dimensions space (3 dimensions for the total momentum acting on the object and the other 3 dimensions to represent the force). This space is called the wrench space ($\mathcal{W}$). To simplify, a wrench can be expressed as set of force ($F$) and torque ($\tau$) vectors, and from a mathematical point of view, the wrench can be defined as $w = [F^T\ \tau^T]^T$ and its magnitude by $||w|| = \sqrt{||F||^2 + \lambda||\tau||^2}$, where $\lambda$ is a scaling value between force and torque.

\subsection{The quality of the grasp}
When it comes time to choose the quality measure, there may be configurations that are better than others, i.e. there are configurations can balance these external wrenches without having to apply too much force. An intuitive way to quantify the grasp quality would be to use the ratio of the magnitude of the largest resisted wrench in any direction and the magnitude of the forces applied by the fingers.

\subsubsection{Representing the finger forces}

In order to compute the forces made by the fingers on the objects, it is necessary to ensure that there is no slipping or detachment of the object at that contact point.
For this to happen, it is necessary that the Coulomb's law should be verified.

Coulomb's law can be defined as: $f_i^{\bot} \ge \mu f_i^t$ where $f_i^{\bot}$ represents the force along the normal to the object's surface on the contact point and $ f_i^t$ is the tangential force to the object surface.
This law can be graphically interpreted through a friction cone, that when the force exerted on the object is inside that cone, the contact point is stable, otherwise there is slippage of the object or its detachment.

The forces acting on the object can be decomposed as linear combinations of the extrema of the friction cone. So in order to do this, the friction cone can be approximated by a with a pyramid of $m$ edges.
Thus the force applied at the contact point ($f_i$) can be given by the expression \eqref{eq:primitive_forces}, where $\alpha_h > 0$ and $\sum_{h=1}^{m}\alpha_h = 1$
\begin{equation}\label{eq:primitive_forces}
    f_i= \sum_{h=1}^{m}\alpha_{i,j}f_{i,h}
\end{equation}
It is known that only the normal component of the contact force ($f_i$) is not sufficient to specify the contact force, since there are several contact forces satisfying the equation \eqref{eq:primitive_forces} and that have the same normal magnitude.

Let be defined a vector g composed of the normal forces in $n$ contact points by $g= (f_1^{\bot}, \dots, f_n^{\bot})^T $ and a predicate $A: \mathcal{W} \times \mathcal{G} \rightarrow \{T, F\}$, where $\mathcal{G}$ is a set of all possible generalized forces $g$. $wAg$ is true if the wrench $w$ belongs to the set of wrenches that can be resisted through generalized force $g$.
\par
Also, $wA$ can be defined as the set of generalized forces that can resist a wrench $w$, and $Ag$ is a set of wrenches $w$ that can be resisted through a generalized force $g$. This can be represented by the equation \eqref{eq:defintion_Apredicate}.
\begin{equation}\label{eq:defintion_Apredicate}
    wA= \Big\{g\ |\ wAg\ is\ true \Big\} \quad and   \quad  Ag= \Big\{w\ |\ wAg\ is\ true \Big\}
\end{equation}

\subsubsection{Grasp quality measure}
The local quality measure ($LQ$) is the best ratio between the resulting wrench and a given generalized force for that wrench. This measure can be given by \eqref{eq:LQ_measure}.
\begin{equation}\label{eq:LQ_measure}
        LQ_w=   \max_{g \in wA}\frac{||w||}{||g||}
\end{equation}
With this, the grasp quality measure ($Q$) can be given as the minimum of all maxima wrenches that can be resisted by each contact point. Which is the worst-case scenario where the object can fall from the hand.
\begin{equation}\label{eq:Q_LMRW}
    Q= \min_w LQ_w
\end{equation}
Due to the invariance of $Q$, minimizing $w$ means minimize over the directions of $w$. Thus \eqref{eq:Q_LMRW} can be rewritten as in \eqref{eq:Q_LMRW2}, where $\hat{w} = w/||w||$ and $||w||$ is such that $||g||= 1 $.
\begin{equation}\label{eq:Q_LMRW2}
    Q=\min_{\hat{w}}\ LQ_{\hat{w}}
\end{equation}
Also, it can be defined a set $B \subset A$, such as $B = \{ (w,g)\ |\ wAg\ is\ true\ and\ ||g||=1 \}$,  which is equivalent to define a predicate $B:\mathcal{W} \times \mathcal{G} \rightarrow \{ T, F \}$, such that $wBg$ is true, $w \in Ag$ and $||g|| = 1$.
And like what was defined with the predicate A in equation \eqref{eq:defintion_Apredicate}, it can be done the same with predicate B, as can be seen in equation~\eqref{eq:defintion_Bpredicate}.
\begin{equation}\label{eq:defintion_Bpredicate}
    wB= \Big\{g\ |\ wAg\ is\ true\ and\ ||g||=1 \Big\} \quad and   \quad  Bg= \Big\{w\ |\ wAg\ is\ true\ and\ ||g||=1 \Big\}
\end{equation}
So, $LQ_{\hat{w}}$ can be rewritten like in \eqref{eq:LQ2}, where $B\mathcal{G}$ is a set of all sets $Bg$.
\begin{equation}\label{eq:LQ2}
    LQ_{\hat{w}}= \max_{w \in B \mathcal{G}} ||w||
\end{equation}
Taking the maximum of the wrench module that belongs to the set $B\mathcal{G}$,  means taking the wrenches that are on the boundary of  that set. And thus $LQ_{\hat{w}}$ and $Q$ can be written like \eqref{eq:LQ_Q_new}.
\begin{equation}\label{eq:LQ_Q_new}
    LQ_{\hat{w}} = \Big\{   ||w||\ |\ w\ \in Bd(B\mathcal{G}) \Big\} \quad and \quad Q = \min_{\hat{w}} \Big\{ ||w||\ |\ w \in Bd(B\mathcal{G} \Big\}
\end{equation}
$Q$ can  be also seen as the distance from the closest point of the boundary $B\mathcal{G}$ to the wrench space origin, in other words, $Q$ is the radius of the largest sphere centered on the origin and it's contained on the boundary $B\mathcal{G}$. So Q is given by \eqref{eq:Q_lasgest_radius}.

\begin{equation}\label{eq:Q_lasgest_radius}
    Q= \min_{w \in Bd(B\mathcal{G}} ||w||
\end{equation}

\subsubsection{Minimizing the maximum finger force}
The optimal grasp configuration is the one that can resist the largest wrench in any direction, with the minimum applied force by each finger. Moreover, the force that a finger can do is upper bounded and the value considered for this upper limit is 1. This only can be assumed because the metric considers the ratio between wrenches and applied forces, that scale linearly with each other.

Considering the equation \eqref{eq:force_and_torque} that gives the force at the i-th ($f_i$) contact and the reacting torque $\tau_i$, where $r_i$ is the vector pointing from the object's center of mass to the contact point.
\begin{equation}\label{eq:force_and_torque}
     f_i= \sum_{j=1}^{m}\alpha_{i,j}f_{i,j} \quad and \quad  \tau_i= \sum_{j=1}^{m}\alpha_{i,j}( r_i \times f_{i,j} )
\end{equation}
Thus the wrench ($w_i$) and the set of all possible wrenches originated at the contact $i$ ($W_i$) can be given by \eqref{eq:conctact_point_wrench}.
\begin{equation}\label{eq:conctact_point_wrench}
    w_i= \sum_{j=1}^{m}\alpha_{i,j}w_{i,j} \quad and \quad
    W_i=\bigg\{w_i | w_i=\sum_{j=1}^{m}\alpha_{i,j}w_{i,j}, \alpha_{i,j}\ge 0, \sum_{j=1}^{m}\alpha_{i,j}\ge 0 \bigg\}
\end{equation}
And therefore the total wrench ($w$) applied to the object is the sum of all wrenches that are applied at each contact. So, now it's is possible to generate a set ($B\mathcal{G}$) with all possible wrenches that can be applied to the object, as shown in the expression \eqref{eq:total_wrench_all_possible_wrench}.
\begin{equation}\label{eq:total_wrench_all_possible_wrench}
    w=\sum_{i=1}^n \quad and \quad
       B\mathcal{G}=W_{L_{\infty}}=W_1 \oplus ... \oplus W_n
\end{equation}
The set with all combinations of the wrenches that can be applied at the object can be obtained through the Minkowski sum of convex sets of contact points $W_i$.
Also the the Minkowski sum can be exchanged with the Convex Hull operation, so the Convex Hull can be given by the expression \eqref{eq:convex_hull}.
\begin{equation}\label{eq:convex_hull}
    W_{L_{\infty}}= Convex Hull\Bigg(\bigoplus_{i=1}^{n} \{ w_{i,1}, ..., w_{i,m} \} \Bigg)
\end{equation}
The advantage of using the Convex Hull relies on the efficient way to compute $W_{L_{\infty}}$, starting from the primitive wrenches which describes each contact point.
The quality measure ($Q_{\infty}$) can be seen as the distance of nearest facet of the Convex Hull from the origin.

\subsubsection{Minimizing the total finger force}
In this case, it is assumed that the force exerted by all the fingers is upper bounded, being this bound equals to 1, which is equivalent to say $||g|| = 1$.
The goal is to minimize the force done by all fingers in the object, so the total force can be defined as in \eqref{eq:total_force}, moreover, every $f_i$ is on the friction cone and thus the total force can be written as the convex combination of the vector along the extrema of the friction cone.
\begin{equation}\label{eq:total_force}
    f= \sum_{i=0}^{n}f_i \quad and \quad
    f= \sum_{i=0}^{n}\sum_{j=0}^{m}\alpha_{i,j}f_{i,j} \quad where \quad \alpha_{i,j} \ge 0 \quad and \quad \sum_{i=0}^{n}\sum_{j=0}^{m}\alpha_{i,j}f_{i,j} \le 1
\end{equation}
Just like the total force to the object, the total wrench can be expressed as \eqref{eq:total_wrench}.
\begin{equation}\label{eq:total_wrench}
    w= \sum_{i=0}^{n}\sum_{j=0}^{m}\alpha_{i,j}w_{i,j}
\end{equation}
The total wrench exerted on the object belongs to a set such that the wrenches correspond to the primitive contacts on the object. So, the set of all possible wrenches can be given by \eqref{eq:convex_hull2}, which can be computed through the Convex Hull over a finite set of points. The quality measure ($Q_1$) can be seen as the nearest facet of the Convex Hull from the origin.
\begin{equation}\label{eq:convex_hull2}
    W_{L_1}= Convex Hull\Bigg(\bigcup_{i=0}^{n}\{w_{i,1},..., w_{i,m}\}\Bigg)
\end{equation}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% GRASP QUALITY EVALUATION IN UNDER-ACTUATED HANDS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Grasp Quality Evaluation in Underactuated Robotic Hands}
There are several types of metrics based on the geometric location of the contact points and the configuration of the hand.
In the case of underactuated hands, these metrics are not straightforward due to their nature.
But because of the way the hand is drawn, it can take care of his shape when grasping an object and thus it's no longer necessary to find specific contact points or pre-compute the configuration of the hand. \par
The consideration of the limit of the forces that the hand can apply on the object facilitates the definition of contact robustness, i.e., how far the contact is from violating the contact constrains.
There are two grasp quality measures that can be defined through the effective capacity of the robotic hand to apply contact forces.
This metrics are: the Potential Contact Robustness (PCR) and the Potential Grasp Robustness (PGR).

\subsection{Measures based on the wrench space}
Different quality measures analyze the Grasp Wrench Space (GWS) in order to find the best grasp. One of the most known of these metrics is the largest minimum resisted wrench.
As stated in the section \ref{section:LMRW}, there are two ways to construct the set of wrenches that can be applied to the object. One limits the sum of all contact forces ($GWS_S$), while the other limits the individual contact forces ($GWS_F$).
The $GWS_S$ is more relevant for hands with a single actuator, while $GWS_F$  is more suitable for hands with multiple actuators. \par
In the case of multi-fingered underactuated hands, there may be some contacts that are controlled by one actuator or contacts that are individually  controlled by one actuator.
To take this into account, a actuation matrix $A  \in \rm I\!R^{n_a \times n_c}$ is defined, where $n_a$ is the number of actuators and $n_c$ is the number of contact points. For each actuator (i.e each row), the contact point (column) is filled with 1 in case of the actuator has direct influence on those contact, otherwise it will be filled with 0.\par
Through the actuation matrix, it is possible to know the set of combinations of wrenches affected by the same actuator. This set can be given by equation \eqref{eq:atuator-wise}.
\begin{equation}\label{eq:atuator-wise}
    w_i^{d,a}= \bigcup_{j=1}^{n_c}
        \begin{cases}
        w_j^{d,c} & \ \text{if } \texttt{A}_{i,j} = 1\\
        \textit{empty} &  \text{otherwise}
    \end{cases}
\end{equation}

Also, all the sets of wrenches affected by each actuator can be grouped into a larger set $GWS_U$. Thus this set can be given by the expression \eqref{eq:minkowski_actuator_wise}

\begin{equation}\label{eq:minkowski_actuator_wise}
    GWS_U = CH\Bigg[
    \mathcal{P}=\bigcup_{i=1}^{n_a}\Bigg(\bigcup_{j=1}^{{}^iC_{n_a}} \big( \bigoplus \mathcal{W}_j^a \big) \Bigg) \Bigg]
    \quad with \quad \mathcal{W}^a_j \in
\left( \begin{array}{c}
             \mathcal{W}^a    \\
              i
    \end{array} \right)
\end{equation}

The computation of the maximum contact forces realizable by each finger can be describe as follow. The unit contact normal force $f_i$ of each contact $i$ can be represented by $\mathfrak{f}_i$.  $\mathfrak{F}_j$ is the set of all unit contact forces generated by the finger $j$. The torques $\tau_j$ needed to achieve  $\mathfrak{F}_j$ are calculated with the joint configuration $q_j$ and the corresponding body Jacobian $J(q_j)$ like it can be seen on the equation \eqref{eq:torqueThroughforces}.
\begin{equation}\label{eq:torqueThroughforces}
    \tau_j = J(q_j)^T \cdot \mathfrak{F}_j
\end{equation}

The finger torque $\tau_j$ is scaled by a factor $k$ until one of the joints reaches its limit. Then the maximum realizable normal force at the contact point $i$ is given by $k\mathfrak{f}_i$ and by using the realizable force for each contact, the quality measure represents the maximum magnitude wrench the a finger can resist.

\subsection{Measures of Contact and Grasp Robustness}

\subsubsection{Potential Contact Robustness}

Once that the hand is underactuated, the contacts and joints are not perfectly rigid and their stiffness can be linearly modeled by $K_s \in \rm I\!R^{3n_c \times 3n_c} $, which is contact stiffness matrix, and $K_p \in \rm I\!R^{n_q \times n_q} $ is the joint stiffness matrix.
Therefore, the variation of grasp variables can be written as in \eqref{eq:force_torque_variation}, where $\Delta q_r$ is a variation of the reference joint configuration.

\begin{equation}\label{eq:force_torque_variation}
     \Delta f = K_s(J \Delta q - G^T\Delta u) \quad and \quad
     \Delta \tau = K_p(\Delta q_r - \Delta q)
 \end{equation}

The vector $d$ (shown in \eqref{eq:vetor_d}) represents how far a grasp is from violating the friction constrains and the maximum force limits.
\begin{equation}\label{eq:vetor_d}
    d(f) = [d_{1,c}, d_{1,f}, d_{1,max}, \dots, d_{n_c,c}, d_{n_c,f}, d_{n_c,max}]
\end{equation}
Where $d_{i,c}$ is the normal component of the $i^{th}$ contact force ($d_{i,c} = f_{i,n} $), $d_{i,f}$ is the distance of \texttt{$f_i$} from the friction cone and $d_{i,max} = f_{i,max} - ||f_i||$.\par

Then, $||\Delta f|| \le d_{min}$ is sufficient to have a contact force perturbation $\Delta f$ such that constrains of Coulomb law are not violated and $d_{min}$ is the minimum value of $d$.

Through the constrain above, the constraint of the external disturbance $\Delta w$ acting on the object can be represented as in \eqref{eq:deltaW}.
 \begin{equation}\label{eq:deltaW}
     ||\Delta w || = \frac{d_{min}}{\sigma_{max}(\texttt{G}_K^R)}
 \end{equation}
 Where $\texttt{G}_K^R = \texttt{KG}^T(\texttt{GKG}^T)$ and $ \texttt{K} =( \texttt{K}_s^{-1} + \texttt{JK}_p^{-1}\texttt{J}^T)$ is the grasp stiffness matrix, and $\sigma_{max}(\texttt{G}_K^R)$ is the maximum singular value of $\texttt{G}_K^R$.
 Also, $f = -G_K^R w + Ey$ represents the controllable contact forces and where $E$ is a basis for the subspace $\mathcal{F}_a$ of the controllable internal forces. $y$ is a vector that parameterizes that subspace.
 \par
 The Potential Contact Robustness (PCR) is defined in \eqref{eq:PCR}, where $d_{min}^{\mathcal{F}_a}= \min\{d(G_K^R w+ Ey\}$ is a function of $y$.
 \begin{equation}\label{eq:PCR}
    PCR = \max_y\frac{d_{min}^{\mathcal{F}_a}}{\sigma_{max}(G_K^R)}
\end{equation}

Any disturbance wrench $\Delta w$ that $||\Delta w||< PCR$ can be resisted without having any object's slippage or detachment, since that the internal forces are actuated.

\subsubsection{Potential Grasp Robustness}
Grasps that contain many points of contact (such as grasps performed by underactuated hands) can still be stable and be able to resist external wrenches even if there are detachment or slippage from contact points. However, PCR may underestimate the grasp quality.

The PGR extends the PCR, admitting that a grasp can still be stable even if there are contacts that do not satisfy the friction constrains. These friction constrain are given by \eqref{eq:positive_contrain} and \eqref{eq:comlumbLaw}.

\begin{equation}\label{eq:positive_contrain}
    f_{i,n} \ge 0
\end{equation}

\begin{equation}\label{eq:comlumbLaw}
    \sqrt{f_{i,t_1}^2+f_{i,t_2}^2} \le \mu_i  f_{n,t_2}
\end{equation}
Thus the PGR admits that each contact point is in one of the following 3 cases:
\begin{itemize}
    \item State 1: It considers as valid the equations \eqref{eq:positive_contrain} and \eqref{eq:comlumbLaw}, being that the contact force can be transmitted in any direction.
    \item State 2: Only the constraint \eqref{eq:positive_contrain} is verified, and the force is transmitted through the normal direction of the contact.
    \item State 3: Non of the constrains are verified. Then it's considered that the contact is detached.
\end{itemize}
Assuming that there are $n_c$ contact points and that each of the contacts may be in one of the 3 previous states, there will be $3^{n_c}$ possible combinations $C_j$ and each of them will have a global matrix of stiffness.
The PGR can be seen as the maximum PCR index of all possible combinations $C_j$ and it can be computed as in \eqref{eq:PGR}.
\begin{equation}\label{eq:PGR}
    PGR = \max_{G_j, j=1,\dots, n_c}PCR(C_j)
\end{equation}
Also PCR can be seen as a specific case of PGR, where the best grasp have all contact points in the state 1.\par
These metrics take into account the hands actuated by postural synergies. These synergies are highly coordinated movements by the brain, which control the shape of the hand when grasping the object.
These synergies can be used to reduce the number of actuators without affecting the hand's performance. \par
When comparing the two metrics it is verified that both the PGR and the PCR are not decreasing with the increase in the use of the synergies. Moreover, the greater the number of synergies used, the greater the subspace of controllable internal forces. \par
In conclusion, PGR is less conservative but more realistic than PGR, and thus it is better to detect stable grasps.

\section{Physically Based Grasp Quality Evaluation Under
Pose Uncertainty}
While there has been a breakthrough in robot grasp planning, grasps made by the robotic hand are not as robust as people's.
Most of the metrics focus on measuring the quality of the contacts after the establishment of the grasp and choosing the best. But in reality, this better grasp calculated by these metrics is difficult to implement in the robotic hand. \par
This paper explores the use of dynamic simulation to estimate the success or failure of the grasp in the real world. The investigated factors that affect the success of the grasp on the object are its dynamic and its pose uncertainty.\par
Most grasp quality metrics only focus on the final hand configuration, or the situation where the robot is already grasping the object and through this choose the best grasp to be performed.


\label{ch:diffusion}

\section{Thermal Diffusion}

Castro incorporates explicit thermal diffusion into the energy equation.
In terms of the specific internal energy, $e$, this appears as:
\begin{equation}
\rho \frac{De}{Dt} + p \nabla \cdot \ub = \nabla \cdot \kth \nabla T
\end{equation}
where $\kth$ is the thermal conductivity, with units
$\mathrm{erg~cm^{-1}~s^{-1}~K^{-1}}$.

To see the similarity to the thermal diffusion equation, consider the special
case of constant conductivity, $\kth$, and density, and assume an
ideal gas, so $e = c_v T$, where $c_v$ is the specific heat at constant volume.
Finally, ignore hydrodynamics, so $\ub = 0$.  This gives:
\begin{equation}
\frac{\partial T}{\partial t} = D \nabla^2 T
\end{equation}
where $D \equiv \kth/(\rho c_v)$.  Solving this equation
explicitly requires a timestep limiter of
\begin{equation}
\Delta t_\mathrm{diff} \le \frac{1}{2} \frac{\Delta x^2}{D}
\end{equation}
(this is implemented in \code{ca\_estdt\_temp\_diffusion} in {\tt
  Castro/Source/driver/timestep.F90}).

Support for diffusion must be compiled into the code by setting {\tt
  USE\_DIFFUSION = TRUE} in your {\tt GNUmakefile}.  It is treated
explicitly, by constructing the contribution to the evolution as a
source term.  This is time-centered to achieve second-order accuracy
in time.

The following parameter affects diffusion:
\begin{itemize}
\item \runparam{castro.diffuse\_temp}:  enable thermal diffusion (0 or 1; default 0)
\end{itemize}

A pure diffusion problem (with no hydrodynamics) can be run by setting
\begin{verbatim}
castro.diffuse_temp = 1
castro.do_hydro = 0
\end{verbatim}

To complete the setup, a thermal conductivity must be specified.  The
interface for the conductivity is:
\begin{lstlisting}[language=fortran]
  subroutine thermal_conductivity(eos_state, therm_cond)

    use extern_probin_module, only: const_conductivity

    type (eos_t), intent(in) :: eos_state
    real (kind=dp_t), intent(inout) :: therm_cond
\end{lstlisting}
The density, temperature, and mass fractions come in through the {\tt
  eos\_state} type.  An EOS call is done in \castro\ just before the
call to \code{thermal\_conductivity}, so you can assume that the entire
state is consistent.

There are two conductivity routines provided with \castro\ by default:
\begin{itemize}
\item {\tt constant} : A simple constant thermal conductivity.  This can be
  selected by setting
\begin{verbatim}
Conductivity_dir := constant
\end{verbatim}
in your {\tt GNUmakefile}.  To set the value of the conductivity (e.g., to
$100$), you add to your {\tt probin} file's {\tt \&extern} namelist:
\begin{verbatim}
const_conductivity = 100.0
\end{verbatim}

\item {\tt constant\_opacity} : A simple constant opacity.  This is
  converted to an opacity as:
  \begin{equation}
    \kth = \frac{16 \sigma_B T^3}{3 \kappa_\mathrm{const} \rho}
  \end{equation}
where $\kappa_\mathrm{const}$ is the opacity, with units $\mathrm{cm^2~g^{-1}}$.
This is selected by setting
\begin{verbatim}
Conductivity_dir := constant_opacity
\end{verbatim}
in your {\tt GNUmakefile}.  To set the value of the opacity, e.g., to
0.2 (e.g., for electron scattering), set:
\begin{verbatim}
const_opacity = 0.2
\end{verbatim}
in the {\tt \&extern} namelist of your {\tt probin}.

\end{itemize}

The diffusion approximation breaks down at the surface of stars,
where the density rapidly drops and the mean free path becomes
large.  In those instances, you should use the flux limited diffusion
module in Castro to evolve a radiation field.  However, if your
interest is only on the diffusion in the interior, you can use
the \runparam{castro.diffuse\_cutoff\_density} parameter to specify a density,
below which, diffusion is not modeled.  This is implemented in the
code by zeroing out the conductivity and skipping the estimation
of the timestep limit in these zones.

A simple test problem that sets up a Gaussian temperature profile
and does pure diffusion is provided as {\tt diffusion\_test}.

\section{Enthalpy Diffusion}

\castro\ can also diffuse enthalpy \MarginPar{these need to be documented}

Note this uses the same interface for the transport coefficients as
thermal diffusion, so the two cannot be used at the same time.

\section{Species Diffusion}

\castro\ can also diffuse species.

Note this uses the same interface for the transport coefficients as
thermal diffusion, so the two cannot be used at the same time.

\section{Viscosity}


\section{Replicated Growable Array}
\label{sect.rga}

The RGA, introduced by \citet{Roh:2011dw}, is a replicated ordered list (sequence) datatype that supports \emph{insert} and \emph{delete} operations.
It can be used for collaborative editing of text by representing a string as an ordered list of characters.

The convergence of RGA has been proved by hand in previous work (see Section~\ref{sect.related.verification}); we now present the first (to our knowledge) mechanised proof that RGA satisfies the specification of SEC from Section~\ref{sect.abstract.convergence}.
We perform this proof within the causal broadcast model defined in Section~\ref{sect.network}, and without making any assumptions beyond the six aforementioned network axioms.
Since the axioms of our network model are easily justified, we have confidence in the correctness of our formalisation.
Our proof makes extensive use of the general-purpose framework that we have established in the last two sections.

\subsection{Specifying Insertion and Deletion}\label{sect.rga.spec}

In an ordered list, each insertion and deletion operation must identify the position at which the modification should take place.
In a non-replicated setting, the position is commonly expressed as an index into the list.
However, the index of a list element may change if other elements are concurrently inserted or deleted earlier in the list; this is the problem at the heart of Operational Transformation (see Section~\ref{sect.related.ot.crdts}).
Instead of using indexes, the RGA algorithm assigns a unique, immutable identifier to each list element.

Insertion operations place the new element \emph{after} an existing list element with a given ID, or at the head of the list if no ID is given.
Deletion operations refer to the ID of the list element that is to be deleted.
However, it is not safe for a deletion operation to completely remove a list element, because then a concurrent insertion after the deleted element would not be able to locate the insertion position.
Instead, the list retains \emph{tombstones}: a deletion operation merely sets a flag on a list element to mark it as deleted, but the element actually remains in the list.
A garbage collection process can be used to purge tombstones \cite{Roh:2011dw}, but we do not consider it here.

The RGA state at each node is a list of elements.
Each element is a triple consisting of the unique ID of the list element (of some type $\isacharprime\isa{id}$), the value inserted by the application (of some type $\isacharprime\isa{v}$), and a flag that indicates whether the element has been marked as deleted (of type $\isa{bool}$):
\begin{isabelle}
\isacommand{type{\isacharunderscore}synonym} {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ {\isacharequal}\ {\isachardoublequoteopen}{\isacharprime}id\ {\isasymtimes}\ {\isacharprime}v\ {\isasymtimes}\ bool{\isachardoublequoteclose}%
\end{isabelle}

The $\isa{insert}$ function takes three parameters: the previous state of the list, the new element to insert, and optionally the ID of an existing element after which the new element should be inserted.
It returns the list with the new element inserted at the appropriate position, or $\isa{None}$ on failure, which occurs if there was no existing element with the given ID.
The function iterates over the list, and for each list element $\isa{x}$, it compares the ID (the first component of the $\isacharprime\isa{id} \mathbin{\isasymtimes} \isacharprime\isa{v} \mathbin{\isasymtimes} \isa{bool}$ triple, written $\isa{fst x}$) to the requested insertion position:
\begin{isabelle}
~~~~{\isachardoublequoteopen}insert\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ \=e\ {\isacharparenleft}Some\ i{\isacharparenright}\ \={\isacharequal}\ {\isacharparenleft}\=\kill
\isacommand{fun}\ insert\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcolon}{\isacharcolon}{\isacharbraceleft}linorder{\isacharbraceright}{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ {\isasymRightarrow}\ {\isacharprime}id\ option\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ option{\isachardoublequoteclose}\\
\isakeyword{where}\\
~~~~{\isachardoublequoteopen}insert\ xs\ \>e\ None\ \>{\isacharequal}\ Some\ {\isacharparenleft}insert{\isacharunderscore}body\ xs\ e{\isacharparenright}{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}insert\ {\isacharbrackleft}{\isacharbrackright}\ \>e\ {\isacharparenleft}Some\ i{\isacharparenright}\ \>{\isacharequal}\ None{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}insert\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ \>e\ {\isacharparenleft}Some\ i{\isacharparenright}\ \>{\isacharequal}\ {\isacharparenleft}\>if\ fst\ x\ {\isacharequal}\ i\ then\ Some\ {\isacharparenleft}x{\isacharhash}insert{\isacharunderscore}body\ xs\ e{\isacharparenright}\\
\>\>\>else\ insert\ xs\ e\ {\isacharparenleft}Some\ i{\isacharparenright}\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}t{\isachardot}\ Some\ {\isacharparenleft}x{\isacharhash}t{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
When the insertion position is found (or, in the case of insertion at the head of the list, immediately), the function $\isa{insert-body}$ is invoked to perform the actual insertion:
\begin{isabelle}
~~~~{\isachardoublequoteopen}insert{\isacharunderscore}body\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ \=\kill
\isacommand{fun} insert{\isacharunderscore}body\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcolon}{\isacharcolon}{\isacharbraceleft}linorder{\isacharbraceright}{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}insert{\isacharunderscore}body\ {\isacharbrackleft}{\isacharbrackright} \>e\ {\isacharequal}\ {\isacharbrackleft}e{\isacharbrackright}{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}insert{\isacharunderscore}body\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\>e\ {\isacharequal}\ {\isacharparenleft}if\ fst\ x\ {\isacharless}\ fst\ e\ then\ e{\isacharhash}x{\isacharhash}xs\ else\ x{\isacharhash}insert{\isacharunderscore}body\ xs\ e{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}

In a non-replicated datatype it would be sufficient to insert the new element directly at the position found by the $\isa{insert}$ function.
However, a replicated setting is more difficult, because several nodes may concurrently insert new elements at the same position, and those insertion operations may be processed in a different order by different nodes.
In order to ensure that all nodes converge towards the same state (that is, the same order of list elements), we sort any concurrent insertions at the same position in descending order of the inserted elements' IDs.
This sorting is implemented in $\isa{insert-body}$ by skipping over any elements with an ID that is greater than that of the newly inserted element (the $\isa{fst x} > \isa{fst e}$ case), and then placing the new element before the first existing element with a lesser ID (the $\isa{fst x} < \isa{fst e}$ case).

Note that the type of IDs is specified as $\isacharprime\isa{id}\isacharcolon\isacharcolon\isacharbraceleft\isa{linorder}\isacharbraceright$, which means that we require the type $\isacharprime\isa{id}$ to have an associated total (linear) order.
$\isa{linorder}$ is the name of a type class supplied by the Isabelle/HOL library.
This annotation is required in order to be able to perform the comparison $\isa{fst x} < \isa{fst e}$ on IDs.
To be precise, RGA requires the total order of IDs to be consistent with causality, which can easily be achieved using the logical timestamps defined by \citet{Lamport:1978jq}.

The delete operation searches for the element with a given ID, and sets its flag to $\isa{True}$ to mark it as deleted:
\begin{isabelle}
~~~~{\isachardoublequoteopen}delete\ {\isacharparenleft}{\isacharparenleft}i{\isacharprime}{\isacharcomma}\ v{\isacharcomma}\ flag{\isacharparenright}{\isacharhash}xs{\isacharparenright}\ \=i\ {\isacharequal}\ {\isacharparenleft}\=\kill
\isacommand{fun}\ delete\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcolon}{\isacharcolon}{\isacharbraceleft}linorder{\isacharbraceright}{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ {\isasymRightarrow}\ {\isacharprime}id\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ option{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}delete\ {\isacharbrackleft}{\isacharbrackright}\>i\ {\isacharequal}\ None{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}delete\ {\isacharparenleft}{\isacharparenleft}i{\isacharprime}{\isacharcomma}\ v{\isacharcomma}\ flag{\isacharparenright}{\isacharhash}xs{\isacharparenright} \>i\ {\isacharequal}\ {\isacharparenleft}\>if\ i{\isacharprime}\ {\isacharequal}\ i\ then\ Some\ {\isacharparenleft}{\isacharparenleft}i{\isacharprime}{\isacharcomma}\ v{\isacharcomma}\ True{\isacharparenright}{\isacharhash}xs{\isacharparenright}\\
\>\>else\ delete\ xs\ i\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}t{\isachardot}\ Some\ {\isacharparenleft}{\isacharparenleft}i{\isacharprime}{\isacharcomma}v{\isacharcomma}flag{\isacharparenright}{\isacharhash}t{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
\end{isabelle}
Note that the operations presented here are deliberately inefficient in order to make them easier to reason about.
One can see our implementations of $\isa{insert-body}$, $\isa{insert}$, and $\isa{delete}$ as functional specifications for RGAs, which could be optimised into more efficient algorithms using data refinement, if desired.

\subsection{Commutativity of Insertion and Deletion}

Recall from Section~\ref{sect.ops.commute} that in order to prove the convergence theorem we need to show that for the datatype in question, all its concurrent operations commute.
It is straightforward to demonstrate that $\isa{delete}$ always commutes with itself, on concurrent and non-concurrent operations alike:
\begin{isabelle}
\isacommand{lemma}\ delete{\isacharunderscore}commutes{\isacharcolon}\\
~~~~{\isachardoublequoteopen}delete\ xs\ i{\isadigit{1}}\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}ys{\isachardot}\ delete\ ys\ i{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ delete\ xs\ i{\isadigit{2}}\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}ys{\isachardot}\ delete\ ys\ i{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}

It is a little more complex to demonstrate that two $\isa{insert}$ operations commute.
Let $\isa{e1}$ and $\isa{e2}$ be the two new list elements being inserted, each of which is a $\isacharprime\isa{id} \mathbin{\isasymtimes} \isacharprime\isa{v} \mathbin{\isasymtimes} \isa{bool}$ triple.
Further, let $\isa{i1} \mathbin{\isacharcolon\isacharcolon} \isacharprime\isa{id option}$ be the position after which $\isa{e1}$ should be inserted (either $\isa{None}$ for the head of the list, or $\isa{Some i}$ where $\isa{i}$ is the ID of an existing list element), and similarly let $\isa{i2}$ be the position after which $\isa{e2}$ should be inserted.
Then the two insertions commute only under certain assumptions:
\begin{isabelle}
~~~~\isakeyword{assumes}\ \=\kill
\isacommand{lemma}\ insert{\isacharunderscore}commutes{\isacharcolon}\\
~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}fst\ e{\isadigit{1}}\ {\isasymnoteq}\ fst\ e{\isadigit{2}}{\isachardoublequoteclose}\\
~~~~~~~~\isakeyword{and}\>{\isachardoublequoteopen}i{\isadigit{1}}\ {\isacharequal}\ None\ {\isasymor}\ i{\isadigit{1}}\ {\isasymnoteq}\ Some\ {\isacharparenleft}fst\ e{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}\\
~~~~~~~~\isakeyword{and}\>{\isachardoublequoteopen}i{\isadigit{2}}\ {\isacharequal}\ None\ {\isasymor}\ i{\isadigit{2}}\ {\isasymnoteq}\ Some\ {\isacharparenleft}fst\ e{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\\
~~~~\isakeyword{shows}\>{\isachardoublequoteopen}insert\ xs\ e{\isadigit{1}}\ i{\isadigit{1}}\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}ys{\isachardot}\ insert\ ys\ e{\isadigit{2}}\ i{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ insert\ xs\ e{\isadigit{2}}\ i{\isadigit{2}}\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}ys{\isachardot}\ insert\ ys\ e{\isadigit{1}}\ i{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
\noindent
That is, $\isa{i1}$ cannot refer to the ID of $\isa{e2}$ and vice versa, and the IDs of the two insertions must be distinct.
We prove later that these assumptions are indeed satisfied for all concurrent operations.
Finally, $\isa{delete}$ commutes with $\isa{insert}$ whenever the element to be deleted is not the same as the element to be inserted:
\begin{isabelle}
~~~~\isakeyword{assumes}\ \=\kill
\isacommand{lemma}\ insert{\isacharunderscore}delete{\isacharunderscore}commute{\isacharcolon}\\
~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}i{\isadigit{2}}\ {\isasymnoteq}\ fst\ e{\isachardoublequoteclose}\\
~~~~\isakeyword{shows}\>{\isachardoublequoteopen}insert\ xs\ e\ i{\isadigit{1}}\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}ys{\isachardot}\ delete\ ys\ i{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ delete\ xs\ i{\isadigit{2}}\ {\isasymbind}\ {\isacharparenleft}{\isasymlambda}ys{\isachardot}\ insert\ ys\ e\ i{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}

\subsection{Embedding RGA in the Network Model}

In order to obtain a proof of the strong eventual consistency of RGA, we embed the insertion and deletion operations in the network model of Section~\ref{sect.network}.
We first define a datatype for operations (which are sent across the network in messages), and an interpretation function as introduced in Section~\ref{sect.ops.interpretation}:
\begin{isabelle}
~~~~{\isachardoublequoteopen}interpret{\isacharunderscore}opers\ {\isacharparenleft}Insert\ e\ n{\isacharparenright}\ \=\kill
\isacommand{datatype} {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ operation\ {\isacharequal} Insert\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt{\isachardoublequoteclose}\ {\isachardoublequoteopen}{\isacharprime}id\ option{\isachardoublequoteclose}\ {\isacharbar} Delete\ {\isachardoublequoteopen}{\isacharprime}id{\isachardoublequoteclose}\\[4pt]
\isacommand{fun} interpret{\isacharunderscore}opers\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcolon}{\isacharcolon}linorder{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ operation\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ option{\isachardoublequoteclose}\\
\isakeyword{where}\\
~~~~{\isachardoublequoteopen}interpret{\isacharunderscore}opers\ {\isacharparenleft}Insert\ e\ n{\isacharparenright}\>xs\ \ {\isacharequal}\ insert\ xs\ e\ n{\isachardoublequoteclose}\ {\isacharbar}\\
~~~~{\isachardoublequoteopen}interpret{\isacharunderscore}opers\ {\isacharparenleft}Delete\ n{\isacharparenright}\>xs\ \ {\isacharequal}\ delete\ xs\ n{\isachardoublequoteclose}
\end{isabelle}

As discussed above, the validity of operations depends on some assumptions: IDs of insertion operations must be unique, and whenever an insertion or deletion operation refers to an existing list element, that element must exist.
As introduced in Section~\ref{sect.network.ops}, we can describe these requirements by using a predicate to specify what messages a node is allowed to broadcast when in a particular state:
\begin{isabelle}
~~~~~~~~\={\isacharparenleft}i{\isacharcomma}\ Insert\ e\ {\isacharparenleft}\=Some\ \=pos{\isacharparenright}\={\isacharparenright}\ \={\isasymRightarrow}\ fst\ e\ {\isacharequal}\ i\ {\isasymand}\ \=\kill
\isacommand{definition}\ valid{\isacharunderscore}rga{\isacharunderscore}msg\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}id{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ elt\ list\ {\isasymRightarrow}\ {\isacharprime}id\ {\isasymtimes}\ {\isacharparenleft}{\isacharprime}id{\isacharcolon}{\isacharcolon}linorder{\isacharcomma}\ {\isacharprime}v{\isacharparenright}\ operation\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\\
~~~~{\isachardoublequoteopen}valid{\isacharunderscore}rga{\isacharunderscore}msg\ list\ msg\ {\isasymequiv}\ case\ msg\ of\\
\>{\isacharparenleft}i{\isacharcomma}\ Insert\ e \>None \>\>{\isacharparenright}\ \>{\isasymRightarrow}\ fst\ e\ {\isacharequal}\ i\ {\isacharbar}\\
\>{\isacharparenleft}i{\isacharcomma}\ Insert\ e\ {\isacharparenleft}Some\ pos{\isacharparenright}{\isacharparenright}\ {\isasymRightarrow}\ fst\ e\ {\isacharequal}\ i\ {\isasymand}\ pos\ {\isasymin}\ set\ {\isacharparenleft}map\ fst\ list{\isacharparenright}\ {\isacharbar}\\
\>{\isacharparenleft}i{\isacharcomma}\ Delete \>\>pos \>{\isacharparenright} \>{\isasymRightarrow} \>pos\ {\isasymin}\ set\ {\isacharparenleft}map\ fst\ list{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
We can now define RGA by extending $\isa{network-with-constrained-ops}$. The interpretation function is instantiated with $\isa{interpret-opers}$, the initial state with the empty list $\isacharbrackleft\,\isacharbrackright$, and the validity predicate with $\isa{valid-rga-msg}$:
\begin{isabelle}
\isacommand{locale}\ rga\ {\isacharequal}\ network{\isacharunderscore}with{\isacharunderscore}constrained{\isacharunderscore}ops\ {\isacharunderscore}\ interpret{\isacharunderscore}opers\ {\isachardoublequoteopen}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\ valid{\isacharunderscore}rga{\isacharunderscore}msg
\end{isabelle}

Within this locale, we prove that whenever an insertion or deletion operation $\isa{op2}$ references an existing list element, there is always a prior insertion operation $\isa{op1}$ that created the element being referenced:
\begin{isabelle}
~~~~\isakeyword{assumes}\ \={\isachardoublequoteopen}n\ {\isacharequal}\ None\ {\isasymor}\ {\isacharparenleft}{\isasymexists}e{\isacharprime}\ n{\isacharprime}{\isachardot}\ \=\kill
\isacommand{lemma}\ allowed{\isacharunderscore}insert{\isacharcolon}\\
~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}Broadcast\ {\isacharparenleft}Insert\ e\ n{\isacharparenright}\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}{\isachardoublequoteclose}\\
~~~~\isakeyword{shows}\>{\isachardoublequoteopen}n\ {\isacharequal}\ None\ {\isasymor}\ {\isacharparenleft}{\isasymexists}e{\isacharprime}\ n{\isacharprime}{\isachardot}\>n\ {\isacharequal}\ Some\ {\isacharparenleft}fst\ e{\isacharprime}{\isacharparenright}\ {\isasymand}\\
\>\>Deliver\ {\isacharparenleft}Insert\ e{\isacharprime}\ n{\isacharprime}{\isacharparenright}\ {\isasymsqsubset}\isactrlsup i\ Broadcast\ {\isacharparenleft}Insert\ e\ n{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\\[4pt]
\isacommand{lemma}\ allowed{\isacharunderscore}delete{\isacharcolon}\\
~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}Broadcast\ {\isacharparenleft}Delete\ x{\isacharparenright}\ {\isasymin}\ set\ {\isacharparenleft}history\ i{\isacharparenright}{\isachardoublequoteclose}\\
~~~~\isakeyword{shows}\>{\isachardoublequoteopen}{\isasymexists}n{\isacharprime}\ v\ b{\isachardot}\ Deliver\ {\isacharparenleft}Insert\ {\isacharparenleft}x{\isacharcomma}\ v{\isacharcomma}\ b{\isacharparenright}\ n{\isacharprime}{\isacharparenright}\ {\isasymsqsubset}\isactrlsup i\ Broadcast\ {\isacharparenleft}Delete\ x{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
Since the network ensures causally ordered delivery, all nodes must deliver the insertion $\isa{op1}$ before the dependent operation $\isa{op2}$.
Hence we show that in all cases where operations do not commute, one operation happens before another.
Conversely, whenever operations are concurrent, we show that they commute:
\begin{isabelle}
\isacommand{theorem}\ concurrent{\isacharunderscore}operations{\isacharunderscore}commute{\isacharcolon}\\
~~~~\isakeyword{shows}\ {\isachardoublequoteopen}hb{\isachardot}concurrent{\isacharunderscore}ops{\isacharunderscore}commute\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ {\isacharparenleft}history\ i{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}
\end{isabelle}
Furthermore, although the type signature of the interpretation function allows an operation to fail by returning $\isa{None}$, we can prove that this failure case is never reached in any execution of the network:
\begin{isabelle}
\isacommand{theorem}\ apply{\isacharunderscore}operations{\isacharunderscore}never{\isacharunderscore}fails{\isacharcolon}\\
~~~~\isakeyword{shows}\ {\isachardoublequoteopen}hb.apply{\isacharunderscore}operations\ {\isacharparenleft}node{\isacharunderscore}deliver{\isacharunderscore}messages\ {\isacharparenleft}history\ i{\isacharparenright}{\isacharparenright}\ {\isasymnoteq}\ None{\isachardoublequoteclose}
\end{isabelle}
It is now easy to show that the $\isa{rga}$ locale satisfies all of the requirements of the abstract specification $\isa{strong-eventual-consistency}$ (Section~\ref{sect.abstract.sec.spec}), which demonstrates formally that RGA provides SEC.


\hypertarget{group__numpp__structures__matrices__dense}{}\section{Dense}
\label{group__numpp__structures__matrices__dense}\index{Dense@{Dense}}

Module containg constexpr dense matrix implementation.

\subsection*{Classes}
\begin{DoxyCompactItemize}
\item
class \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense$<$ T, Rows, Columns $>$}
\item
class \hyperlink{classtuple__size}{tuple\+\_\+size}
\begin{DoxyCompactList}\small\item\em \hyperlink{classtuple__size}{tuple\+\_\+size} specialization for \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense} \end{DoxyCompactList}\item
class \hyperlink{classtuple__element}{tuple\+\_\+element}
\begin{DoxyCompactList}\small\item\em \hyperlink{classtuple__element}{tuple\+\_\+element} specialization for \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense} \end{DoxyCompactList}\end{DoxyCompactItemize}
\subsection*{Functions}
\begin{DoxyCompactItemize}
\item
{\footnotesize template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Columns, Rows $>$ \hyperlink{group__numpp__structures__matrices__dense_ga07f80d900be174247ad3a3c42e9244fd}{numpp\+::matrix\+::transpose} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \hyperlink{group__numpp__structures__matrices__dense_ga60cc656d6425b919b2876e520854d029}{std\+::pow} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&matrix, U \&\&exp)
\item
{\footnotesize template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \hyperlink{group__numpp__structures__matrices__dense_gaad33179f3c1ba4df7469b7e3b0da7dbf}{std\+::log} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \hyperlink{group__numpp__structures__matrices__dense_ga5455e1c6ea8020055f4873c6c07d5810}{std\+::exp} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \hyperlink{group__numpp__structures__matrices__dense_gaa1377585547eae134c6ce13018e08a6b}{std\+::abs} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \hyperlink{group__numpp__structures__matrices__dense_gac89face89afdd17bfd0c07fda3997db2}{std\+::sqrt} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \hyperlink{group__numpp__structures__matrices__dense_ga3cccd3987b35936ecd0368f9dc4d6832}{std\+::sin} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \hyperlink{group__numpp__structures__matrices__dense_gaf4c3368b8cb2cdb05c0dd5a4d1790480}{std\+::cos} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_ga9fdd727151e15fa8f6a806b9828d06d4}{numpp\+::matrix\+::operator+} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&first, const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&second)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_ga1a99075b6985b2ccafb41a6d9ad91824}{numpp\+::matrix\+::operator-\/} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&first, const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&second)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows\+Columns, std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_ga9f59a9112db4704ed081eaf0c2b738b5}{numpp\+::matrix\+::operator$\ast$} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Rows\+Columns $>$ \&first, const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows\+Columns, Columns $>$ \&second)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_gaeaace68ab41170931eb69e1cdb4fa381}{numpp\+::matrix\+::multiply} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&first, const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&second)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_ga4ba3829a99216c5210cd95f49b703cf0}{numpp\+::matrix\+::operator$\ast$} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&matrix, const U scalar)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_ga6eabf8b5b95a1aeea6b7dc2e4344619e}{numpp\+::matrix\+::operator$\ast$} (const U scalar, const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&matrix)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_ga47bac473f5d6fe8ca8e085f8897d3f81}{numpp\+::matrix\+::operator/} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&matrix, const U scalar)
\item
{\footnotesize template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr auto \hyperlink{group__numpp__structures__matrices__dense_ga1a70f81ac03f3832f97467af1dd782fc}{numpp\+::matrix\+::operator/} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&first, const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&second)
\item
{\footnotesize template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr T \& \hyperlink{group__numpp__structures__matrices__dense_gaa9d630e00d9adfc653c428dad39d1b56}{numpp\+::matrix\+::get} (\hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&n)
\item
{\footnotesize template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr T \& \hyperlink{group__numpp__structures__matrices__dense_ga161ec12506af265f6c407b695b06974c}{numpp\+::matrix\+::get} (\hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&\&n)
\item
{\footnotesize template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr const T \& \hyperlink{group__numpp__structures__matrices__dense_ga5587c6c4095d1147e35da4860e22df52}{numpp\+::matrix\+::get} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&n)
\item
{\footnotesize template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ }\\constexpr const T \&\& \hyperlink{group__numpp__structures__matrices__dense_ga8a016cefdf00f72d041d313318e7a2fc}{numpp\+::matrix\+::get} (const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&\&n)
\end{DoxyCompactItemize}

\subsection{Detailed Description}
Module containg constexpr dense matrix implementation.

{\bfseries \begin{DoxyWarning}{Warning}
Compilation time of this matrix may mitigate any runtime speedup.~\newline
For dissertation of the problem see /ref praca
\end{DoxyWarning}
This matrix implementation uses heavy T\+MP tricks and C++17 functionality is required in order for it to work.}

{\bfseries {\bfseries \begin{DoxyWarning}{Warning}
If you are looking for more compile-\/runtime balanced implementations check Eigen, Armadillo or other libraries
\end{DoxyWarning}
{\bfseries Example\+:}
\begin{DoxyCode}
\textcolor{comment}{//Declaration of matrix}
\hyperlink{classnumpp_1_1matrix_1_1dense}{numpp::matrix::dense<double, 3, 3>} mat\{
                                              0,  2,   3.15
                                              4,  8,   12,
                                              5., 7.7, 4.2
                                              \};
\textcolor{comment}{//Perform matrix multiplication}
\textcolor{comment}{//Other operations have operator overloaded as well}
\textcolor{keyword}{auto} \textcolor{keyword}{new} = mat*mat;
\textcolor{comment}{//Operation against scalar}
\textcolor{keyword}{auto} divided = mat/3.14;

\textcolor{keyword}{auto} transposed = \hyperlink{group__numpp__structures__matrices__dense_ga07f80d900be174247ad3a3c42e9244fd}{transpose}(mat);

\textcolor{comment}{//Uses iterators, so you can print it this way:}
\textcolor{keywordflow}{for}(\textcolor{keyword}{const} \textcolor{keyword}{auto}& row: mat)\{
  \textcolor{keywordflow}{for}(\textcolor{keyword}{const} \textcolor{keyword}{auto}& elem: row)
    std::cout << elem << \textcolor{stringliteral}{" "};
  std::cout << std::endl;
\}
\end{DoxyCode}
}}

{\bfseries {\bfseries
\begin{DoxyCode}
\textcolor{preprocessor}{#include"numpp/structures/matrices/dense"}
\end{DoxyCode}
 }}

\subsection{Function Documentation}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_gaa1377585547eae134c6ce13018e08a6b}\label{group__numpp__structures__matrices__dense_gaa1377585547eae134c6ce13018e08a6b}}
\index{Dense@{Dense}!abs@{abs}}
\index{abs@{abs}!Dense@{Dense}}
\subsubsection{\texorpdfstring{abs()}{abs()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$T, Rows, Columns$>$ std\+::abs (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Standard library overload, matrix element-\/wise abs function $|A|$

\begin{DoxyParams}{Parameters}
{\em matrix} & Matrix with exact same elements, but in absolute value\\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_gaf4c3368b8cb2cdb05c0dd5a4d1790480}\label{group__numpp__structures__matrices__dense_gaf4c3368b8cb2cdb05c0dd5a4d1790480}}
\index{Dense@{Dense}!cos@{cos}}
\index{cos@{cos}!Dense@{Dense}}
\subsubsection{\texorpdfstring{cos()}{cos()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$T, Rows, Columns$>$ std\+::cos (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Standard library overload, matrix element-\/wise sin function $|A|$

\begin{DoxyParams}{Parameters}
{\em matrix} & Matrix with elements passed through cos standard library function\\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga5455e1c6ea8020055f4873c6c07d5810}\label{group__numpp__structures__matrices__dense_ga5455e1c6ea8020055f4873c6c07d5810}}
\index{Dense@{Dense}!exp@{exp}}
\index{exp@{exp}!Dense@{Dense}}
\subsubsection{\texorpdfstring{exp()}{exp()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$T, Rows, Columns$>$ std\+::exp (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Standard library overload, matrix element-\/wise exp function $e^(A)$

\begin{DoxyParams}{Parameters}
{\em matrix} & Matrix whose elements will be exponentiated\\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_gaa9d630e00d9adfc653c428dad39d1b56}\label{group__numpp__structures__matrices__dense_gaa9d630e00d9adfc653c428dad39d1b56}}
\index{Dense@{Dense}!get@{get}}
\index{get@{get}!Dense@{Dense}}
\subsubsection{\texorpdfstring{get()}{get()}\hspace{0.1cm}{\footnotesize\ttfamily [1/4]}}
{\footnotesize\ttfamily template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr T\& numpp\+::matrix\+::get (\begin{DoxyParamCaption}\item[{\hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{n }\end{DoxyParamCaption})}

Overload standard operator get for dense matrix

Elements are taken column-\/wise. {\bfseries Example\+:}
\begin{DoxyCode}
\hyperlink{classnumpp_1_1matrix_1_1dense}{numpp::matrix::dense<int, 2, 2>} foo\{1,2,
                                    3,4\};
std::cout << get<0>(foo) << std::endl; \textcolor{comment}{//Returns 1}
std::cout << get<2>(foo) << std::endl; \textcolor{comment}{//Returns 3, jumps to the next column}
\end{DoxyCode}

\begin{DoxyReturn}{Returns}
Element of matrix
\end{DoxyReturn}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga161ec12506af265f6c407b695b06974c}\label{group__numpp__structures__matrices__dense_ga161ec12506af265f6c407b695b06974c}}
\index{Dense@{Dense}!get@{get}}
\index{get@{get}!Dense@{Dense}}
\subsubsection{\texorpdfstring{get()}{get()}\hspace{0.1cm}{\footnotesize\ttfamily [2/4]}}
{\footnotesize\ttfamily template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr T\& numpp\+::matrix\+::get (\begin{DoxyParamCaption}\item[{\hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&\&}]{n }\end{DoxyParamCaption})}

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga5587c6c4095d1147e35da4860e22df52}\label{group__numpp__structures__matrices__dense_ga5587c6c4095d1147e35da4860e22df52}}
\index{Dense@{Dense}!get@{get}}
\index{get@{get}!Dense@{Dense}}
\subsubsection{\texorpdfstring{get()}{get()}\hspace{0.1cm}{\footnotesize\ttfamily [3/4]}}
{\footnotesize\ttfamily template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr const T\& numpp\+::matrix\+::get (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{n }\end{DoxyParamCaption})}

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga8a016cefdf00f72d041d313318e7a2fc}\label{group__numpp__structures__matrices__dense_ga8a016cefdf00f72d041d313318e7a2fc}}
\index{Dense@{Dense}!get@{get}}
\index{get@{get}!Dense@{Dense}}
\subsubsection{\texorpdfstring{get()}{get()}\hspace{0.1cm}{\footnotesize\ttfamily [4/4]}}
{\footnotesize\ttfamily template$<$std\+::size\+\_\+t Index, typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr const T\&\& numpp\+::matrix\+::get (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&\&}]{n }\end{DoxyParamCaption})}

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.\mbox{\Hypertarget{group__numpp__structures__matrices__dense_gaad33179f3c1ba4df7469b7e3b0da7dbf}\label{group__numpp__structures__matrices__dense_gaad33179f3c1ba4df7469b7e3b0da7dbf}}
\index{Dense@{Dense}!log@{log}}
\index{log@{log}!Dense@{Dense}}
\subsubsection{\texorpdfstring{log()}{log()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$T, Rows, Columns$>$ std\+::log (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Standard library overload, matrix element-\/wise logarithm $ln(A)$

\begin{DoxyParams}{Parameters}
{\em matrix} & Matrix whose elements will be logarithmized\\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_gaeaace68ab41170931eb69e1cdb4fa381}\label{group__numpp__structures__matrices__dense_gaeaace68ab41170931eb69e1cdb4fa381}}
\index{Dense@{Dense}!multiply@{multiply}}
\index{multiply@{multiply}!Dense@{Dense}}
\subsubsection{\texorpdfstring{multiply()}{multiply()}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::multiply (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{first,  }\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&}]{second }\end{DoxyParamCaption})}

Element-\/wise multiplication of two matrices of the same size\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga9f59a9112db4704ed081eaf0c2b738b5}\label{group__numpp__structures__matrices__dense_ga9f59a9112db4704ed081eaf0c2b738b5}}
\index{Dense@{Dense}!operator$\ast$@{operator$\ast$}}
\index{operator$\ast$@{operator$\ast$}!Dense@{Dense}}
\subsubsection{\texorpdfstring{operator$\ast$()}{operator*()}\hspace{0.1cm}{\footnotesize\ttfamily [1/3]}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows\+Columns, std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::operator$\ast$ (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Rows\+Columns $>$ \&}]{first,  }\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows\+Columns, Columns $>$ \&}]{second }\end{DoxyParamCaption})}

Matrix row-\/column multiplication

\begin{DoxyReturn}{Returns}
Matrix with appropriate size after multiplication (dense$<$common\+\_\+type\+\_\+t$<$\+U,\+T$>$, Rows, Columns$>$)
\end{DoxyReturn}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga4ba3829a99216c5210cd95f49b703cf0}\label{group__numpp__structures__matrices__dense_ga4ba3829a99216c5210cd95f49b703cf0}}
\index{Dense@{Dense}!operator$\ast$@{operator$\ast$}}
\index{operator$\ast$@{operator$\ast$}!Dense@{Dense}}
\subsubsection{\texorpdfstring{operator$\ast$()}{operator*()}\hspace{0.1cm}{\footnotesize\ttfamily [2/3]}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::operator$\ast$ (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{matrix,  }\item[{const U}]{scalar }\end{DoxyParamCaption})}

Multiplication of dense matrix and scalar\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga6eabf8b5b95a1aeea6b7dc2e4344619e}\label{group__numpp__structures__matrices__dense_ga6eabf8b5b95a1aeea6b7dc2e4344619e}}
\index{Dense@{Dense}!operator$\ast$@{operator$\ast$}}
\index{operator$\ast$@{operator$\ast$}!Dense@{Dense}}
\subsubsection{\texorpdfstring{operator$\ast$()}{operator*()}\hspace{0.1cm}{\footnotesize\ttfamily [3/3]}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::operator$\ast$ (\begin{DoxyParamCaption}\item[{const U}]{scalar,  }\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Multiplication of dense matrix and scalar\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga9fdd727151e15fa8f6a806b9828d06d4}\label{group__numpp__structures__matrices__dense_ga9fdd727151e15fa8f6a806b9828d06d4}}
\index{Dense@{Dense}!operator+@{operator+}}
\index{operator+@{operator+}!Dense@{Dense}}
\subsubsection{\texorpdfstring{operator+()}{operator+()}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::operator+ (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{first,  }\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&}]{second }\end{DoxyParamCaption})}

Element-\/wise addition of two matrices of the same size\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga1a99075b6985b2ccafb41a6d9ad91824}\label{group__numpp__structures__matrices__dense_ga1a99075b6985b2ccafb41a6d9ad91824}}
\index{Dense@{Dense}!operator-\/@{operator-\/}}
\index{operator-\/@{operator-\/}!Dense@{Dense}}
\subsubsection{\texorpdfstring{operator-\/()}{operator-()}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::operator-\/ (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{first,  }\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&}]{second }\end{DoxyParamCaption})}

Element-\/wise subtraction of two matrices of the same size\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga47bac473f5d6fe8ca8e085f8897d3f81}\label{group__numpp__structures__matrices__dense_ga47bac473f5d6fe8ca8e085f8897d3f81}}
\index{Dense@{Dense}!operator/@{operator/}}
\index{operator/@{operator/}!Dense@{Dense}}
\subsubsection{\texorpdfstring{operator/()}{operator/()}\hspace{0.1cm}{\footnotesize\ttfamily [1/2]}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::operator/ (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{matrix,  }\item[{const U}]{scalar }\end{DoxyParamCaption})}

Element-\/wise division of matrix against scalar\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga1a70f81ac03f3832f97467af1dd782fc}\label{group__numpp__structures__matrices__dense_ga1a70f81ac03f3832f97467af1dd782fc}}
\index{Dense@{Dense}!operator/@{operator/}}
\index{operator/@{operator/}!Dense@{Dense}}
\subsubsection{\texorpdfstring{operator/()}{operator/()}\hspace{0.1cm}{\footnotesize\ttfamily [2/2]}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr auto numpp\+::matrix\+::operator/ (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{first,  }\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ U, Rows, Columns $>$ \&}]{second }\end{DoxyParamCaption})}

Element-\/wise division of two matrices\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga60cc656d6425b919b2876e520854d029}\label{group__numpp__structures__matrices__dense_ga60cc656d6425b919b2876e520854d029}}
\index{Dense@{Dense}!pow@{pow}}
\index{pow@{pow}!Dense@{Dense}}
\subsubsection{\texorpdfstring{pow()}{pow()}}
{\footnotesize\ttfamily template$<$typename T , typename U , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$T, Rows, Columns$>$ std\+::pow (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&}]{matrix,  }\item[{U \&\&}]{exp }\end{DoxyParamCaption})}

Standard library overload, matrix with element-\/wise power $A^exp$

\begin{DoxyParams}{Parameters}
{\em matrix} & Matrix whose elements will be taken to the exp power  power for every element\\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga3cccd3987b35936ecd0368f9dc4d6832}\label{group__numpp__structures__matrices__dense_ga3cccd3987b35936ecd0368f9dc4d6832}}
\index{Dense@{Dense}!sin@{sin}}
\index{sin@{sin}!Dense@{Dense}}
\subsubsection{\texorpdfstring{sin()}{sin()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$T, Rows, Columns$>$ std\+::sin (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Standard library overload, matrix element-\/wise sin function $|A|$

\begin{DoxyParams}{Parameters}
{\em matrix} & Matrix with elements passed through sin standard library function\\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_gac89face89afdd17bfd0c07fda3997db2}\label{group__numpp__structures__matrices__dense_gac89face89afdd17bfd0c07fda3997db2}}
\index{Dense@{Dense}!sqrt@{sqrt}}
\index{sqrt@{sqrt}!Dense@{Dense}}
\subsubsection{\texorpdfstring{sqrt()}{sqrt()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
C\+O\+N\+S\+T\+E\+X\+PR \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$T, Rows, Columns$>$ std\+::sqrt (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{numpp\+::matrix\+::dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Standard library overload, matrix element-\/wise sqrt function $|A|$

\begin{DoxyParams}{Parameters}
{\em matrix} & Matrix with elements passed through sqrt standard library function\\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{group__numpp__structures__matrices__dense_ga07f80d900be174247ad3a3c42e9244fd}\label{group__numpp__structures__matrices__dense_ga07f80d900be174247ad3a3c42e9244fd}}
\index{Dense@{Dense}!transpose@{transpose}}
\index{transpose@{transpose}!Dense@{Dense}}
\subsubsection{\texorpdfstring{transpose()}{transpose()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
constexpr \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$T, Columns, Rows$>$ numpp\+::matrix\+::transpose (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1matrix_1_1dense}{dense}$<$ T, Rows, Columns $>$ \&}]{matrix }\end{DoxyParamCaption})}

Transposes given matrix \begin{DoxyReturn}{Returns}
Transposed dense matrix
\end{DoxyReturn}


\documentclass[12pt]{article}

\usepackage{amsmath}

\title{An Example Document}

\author{John Smith}

\date{}

\begin{document}

\maketitle

\section{The first section}

This is an example of a document formatted using \LaTeX{}.
This is an example of a citation \cite{gG07}.
Now here is an example of an equation:

\begin{align}
i\hbar\frac{\partial}{\partial t}\Psi(r,t) = -\frac{\hbar^2}{2m}\nabla^2\Psi(r,t)+V(r)\Psi(r,t)
\end{align}

\bibliographystyle{amsplain}

\bibliography{BibFile}

\end{document}


\documentclass[gr-notes.tex]{subfiles}

\begin{document}

\setcounter{chapter}{6}

\chapter{Physics in a curved spacetime}

\setcounter{section}{5}

\section{Exercises}

\textbf{1}
If Equation 7.3 were the correct generalization of 7.1 in a curved spacetime, what are the implications? What would happen to the number of particles in a comoving volume of the fluid over time? May we experimentally distinguish between Equations 7.2 and 7.3?

The number of particles would change proportionally to the square of the Ricci scalar, which corresponds to the curvature of the manifold. Whether particles are created ($+$) or destroyed ($-$) would depend on the sign of $q$ in the equation.

We could set up some experiment which tests for a change in the number of particles in a moving fluid, in various gravitational fields, to verify whether the RHS of the equation is non-zero.

\textbf{2}
Compute $g^{\alpha\beta}$ for the line element given by Equation 7.8, to first order in $\phi$.

Based on the line element, we can infer that the metric is
%
\begin{align*}
  (g_{\alpha\beta}) &\underset{(t,x,y,z)}{\to}
  \mqty(\dmat[0]{-(1+2\phi),(1-2\phi),(1-2\phi),(1-2\phi)})
  \\
  (g^{\alpha\beta}) &\underset{(t,x,y,z)}{\to}
  \mqty(\dmat[0]{-(1+2\phi)^{-1},(1-2\phi)^{-1},(1-2\phi)^{-1},(1-2\phi)^{-1}})
  \approx
  \mqty(\dmat[0]{-(1-2\phi),(1+2\phi),(1+2\phi),(1+2\phi)})
\end{align*}

\textbf{3}
Calculate the Christoffel sybmols for the metric given by Equation 7.8, to first order in $\phi$, assuming $\phi = \phi(t,x,y,z)$.

I do the following with the assistance of the free computer algebra system \texttt{Maxima}. I used the exact form of the metric tensor, and then approximated the resulting Christoffel symbols to first order in $\phi$.

\begin{align*}
  \tensor{\Gamma}{^t_{t\alpha}} &=
  \pdv{\phi}{x^\alpha} \frac{1}{1 + 2\phi} \approx
  \pdv{\phi}{x^\alpha} (1 - 2\phi)
  &
  \tensor{\Gamma}{^\alpha_{t\alpha}} &=
 -\pdv{\phi}{t} \frac{1}{1 - 2\phi} \approx
 -\pdv{\phi}{t} (1 + 2\phi)
  \\
  \tensor{\Gamma}{^i_{tt}} &=
  \pdv{\phi}{x^i} \frac{1}{1 - 2\phi} \approx
  \pdv{\phi}{x^i} (1 + 2\phi)
  &
  \tensor{\Gamma}{^t_{ii}} &=
 -\pdv{\phi}{t} \frac{1}{1 + 2\phi} \approx
  \pdv{\phi}{t} (1 - 2\phi)
  \\
  \tensor{\Gamma}{^i_{jj}} =
 -\tensor{\Gamma}{^j_{ij}} =
 -\tensor{\Gamma}{^i_{ii}} &=
  \pdv{\phi}{x^i} \frac{1}{1 - 2\phi} \approx
  \pdv{\phi}{x^i} (1 + 2\phi)
\end{align*}

\textbf{5}

(a) In the case of a perfect fluid, verify that the spatial components of Equation 7.6 reduce to
%
\begin{displaymath}
  \dot{\boldsymbol{v}} +
  (\boldsymbol{v} \cdot \grad) \boldsymbol{v} +
  \grad p / \rho +
  \grad \phi =
  0
\end{displaymath}
%
in the Newtonian limit and in the weak-field regime (the metric given by Equation 7.8).

\begin{align*}
  T^{\mu\nu} &=
  (\rho + p) U^\mu U^\nu + p g^{\mu\nu}
  \\ &\approx
  \rho U^\mu U^\nu + p g^{\mu\nu}
  \\ &\approx
  m U^\mu (n U^\nu) + p g^{\mu\nu}
  \\
  T^{i\nu} &\approx
  m U^i (n U^\nu) + p g^{i\nu}
  \\
  \tensor{T}{^{i\nu}_{;\nu}} &\approx
  m [ U^i (n U^\nu) ]_{;\nu} + [ p g^{i\nu} ]_{;\nu} =
  m n U^\nu \tensor{U}{^i_{;\nu}} + g^{i\nu} p_{;\nu} = 0
  \\ \implies
  0 &=
  U^\nu \tensor{U}{^i_{;\nu}} + g^{i\nu} p_{;\nu} / \rho
  \\ &=
  U^\nu (\tensor{U}{^i_{,\nu}} + U^\lambda \tensor{\Gamma}{^i_{\lambda\nu}}) +
  g^{i\nu} p_{,\nu} / \rho
  \\ &=
  U^0 \tensor{U}{^i_{,0}} +
  U^j \tensor{U}{^i_{,j}} +
  U^\nu U^\lambda \tensor{\Gamma}{^i_{\lambda\nu}} +
  g^{i\nu} p_{,\nu} / \rho
  \\ &=
  \gamma \dv{\tau} (\gamma v^i) +
  \gamma v^j (\gamma v^i)_{,j} +
  U^\nu U^\lambda \tensor{\Gamma}{^i_{\lambda\nu}} +
  g^{ii} p_{,i} / \rho
  \\ &\approx
  \dv{v^i}{\tau} +
  v^j v^i_{,j} +
  (U^0)^2 \tensor{\Gamma}{^i_{00}} +
  (1 - 2\phi) p_{,i} / \rho
  \\ &\approx
  \dv{v^i}{\tau} +
  v^j v^i_{,j} +
  \phi_{,i} +
  p_{,i} / \rho
\end{align*}
%
rewriting this in vector form, we get the original equation.

(b) Now look at the time-component instead of the spatial component.

\begin{align*}
  T^{0\nu} &=
  (\rho + p) U^0 U^\nu + p g^{0\nu} \approx
  m U^0 (n U^\nu) + p g^{0\nu}
  \\
  \tensor{T}{^{0\nu}_{;\nu}} &=
  m [U^0 (n U^\nu)]_{;\nu} + [p g^{0\nu}]_{;\nu} =
  m n U^\nu \tensor{U}{^0_{;\nu}} + g^{00} p_{,\nu} =
  0
  \\ \implies
  0 &=
  U^\nu \tensor{U}{^0_{;\nu}} + g^{00} \dot{p} / \rho
  \\ &=
  U^\nu (\tensor{U}{^0_{,\nu}} + U^\lambda \tensor{\Gamma}{^0_{\lambda\nu}}) +
  g^{00} \dot{p} / \rho
  \\ &=
  U^0 \tensor{U}{^0_{,0}} +
  U^i \tensor{U}{^0_{,i}} +
  U^\nu U^\lambda \tensor{\Gamma}{^0_{\lambda\nu}} +
  g^{00} \dot{p} / \rho
  \\ &\approx
  \frac{1}{2} \dv{v^2}{\tau} +
  \frac{1}{2} v^i \dv{v^2}{x^i} +
  U^\nu U^0 \tensor{\Gamma}{^0_{0\nu}} -
  (1 + 2\phi) \dot{p} / \rho
  \\ &\approx
  \frac{1}{2} \dv{v^2}{\tau} +
  \frac{1}{2} v^i \dv{v^2}{x^i} +
  U^\nu U^0 \tensor{\Gamma}{^0_{0\nu}} -
  \dot{p} / \rho
  \\ &\approx
  \frac{1}{2} \dv{v^2}{\tau} +
  \frac{1}{2} v^i \dv{v^2}{x^i} +
  U^\nu U^0 \phi_{,\nu} -
  \dot{p} / \rho
  \\ &\approx
  \frac{1}{2} \dv{v^2}{\tau} +
  \frac{1}{2} v^i \dv{v^2}{x^i} +
  \dot{\phi} + v^i \phi_{,i} -
  \dot{p} / \rho
\end{align*}

(c) A metric is static if there exist coordinates such that $\vec{e}_0$ is timelike, $g_{i0} = 0$, and $g_{\alpha\beta,0} = 0$. Show from Equation 7.6 that a static fluid (i.e. $U^i = 0$, $p_{,0} = 0$, etc) obeys the relativistic equation of hydrostatic equilibrium (Equation 7.40):
%
\begin{displaymath}
  p_{,i} + (\rho + p) \qty[ \frac{1}{2} \ln(-g_{00}) ]_{,i} = 0.
\end{displaymath}

We start by writing out Equation 7.6 as
%
\begin{align*}
  \tensor{T}{^{\mu\nu}_{;\nu}} &=
  [(\rho + p) U^\mu U^\nu]_{;\nu} + [p g^{\mu\nu}]_{;\nu} =
  0
  \\ &=
  [(\rho + p) U^\mu] \tensor{U}{^\nu_{;\nu}} +
  [(\rho + p) U^\nu] \tensor{U}{^\mu_{;\nu}} +
  U^\nu U^\mu (\rho + p)_{,\nu} +
  g^{\mu\nu} p_{,\nu} =
  0
  \\ &=
  \tensor{T}{^{00}_{;0}} +
  \tensor{T}{^{ij}_{;j}} +
  \tensor{T}{^{0i}_{;i}} +
  \tensor{T}{^{i0}_{;0}} =
  0
  \\
  \tensor{T}{^{00}_{;0}} &=
  [(\rho + p) U^0] \tensor{U}{^0_{;0}} +
  [(\rho + p) U^0] \tensor{U}{^0_{;0}} +
  U^0 U^0 (\rho + p)_{,0} +
  g^{00} p_{,0}
  \\ &=
  2 (\rho + p) U^0 \tensor{U}{^0_{;0}}
  \\ &=
  2 (\rho + p) U^0
  [\tensor{U}{^0_{,0}} + U^\lambda \tensor{\Gamma}{^0_{0\lambda}}]
  \\ &=
  2 (\rho + p)
  [U^0]^2 \tensor{\Gamma}{^0_{00}} =
  0
  \\
  \tensor{T}{^{ij}_{;j}} &=
  [(\rho + p) U^i] \tensor{U}{^j_{;j}} +
  [(\rho + p) U^j] \tensor{U}{^i_{;j}} +
  U^j U^i (\rho + p)_{,j} +
  g^{ij} p_{,j}
  \\ &=
  g^{ij} p_{,j}
  \\
  \tensor{T}{^{0i}_{;i}} &=
  [(\rho + p) U^0] \tensor{U}{^i_{;i}} +
  [(\rho + p) U^i] \tensor{U}{^0_{;i}} +
  U^i U^0 (\rho + p)_{,i} +
  g^{0i} p_{,i}
  \\ &=
  [(\rho + p) U^0] \tensor{U}{^i_{;i}} =
  (\rho + p) U^0
  [\tensor{U}{^i_{,i}} + U^\lambda \tensor{\Gamma}{^i_{i\lambda}}]
  \\ &=
  (\rho + p) [U^0]^2 \tensor{\Gamma}{^i_{i0}}
  \\ &=
  \frac{1}{2} [U^0]^2 (\rho + p)
  g^{i\alpha} (g_{\alpha i,0} + g_{\alpha 0,i} - g_{0i,\alpha}) =
  0
  \\
  \tensor{T}{^{i0}_{;0}} &=
  [(\rho + p) U^i] \tensor{U}{^0_{;0}} +
  [(\rho + p) U^0] \tensor{U}{^i_{;0}} +
  U^0 U^i (\rho + p)_{,0} +
  g^{i0} p_{,0}
  \\ &=
  [(\rho + p) U^0] \tensor{U}{^i_{;0}} =
  (\rho + p) U^0
  [\tensor{U}{^i_{,0}} + U^0 \tensor{\Gamma}{^i_{00}}]
  \\ &=
  \frac{1}{2} (\rho + p) [U^0]^2
  g^{i\alpha} (g_{\alpha0,0} + g_{\alpha0,0} - g_{00,\alpha}) =
 -\frac{1}{2} (\rho + p) [U^0]^2 g^{ij} g_{00,j}
  \\ &=
  \frac{1}{2} (\rho + p) g^{ij} g_{00,j} / g_{00} =
  \frac{1}{2} (\rho + p) g^{ij} \ln(-g_{00})_{,j}
  \\
  \tensor{T}{^{\mu\nu}_{;\nu}} &=
  g^{ij} p_{,j} + \frac{1}{2} (\rho + p) g^{ij} \ln(-g_{00})_{,j} = 0
  \\ &=
  p_{,j} + (\rho + p) \qty[ \frac{1}{2} \ln(-g_{00})]_{,j} = 0
\end{align*}

(d) This suggests that there is a relationship between $g_{00}$ and $\exp(2\phi)$ in the case of a static fluid in a Newtonian potential. Show that Equation 7.8 and Exercise 4 are consistent with this.

In the Newtonian limit, the previous equation is unchanged when replacing $ng_{00}$ with $-\exp(2\phi)$, as $\ln(\exp(2\phi))_{,i} = 2 \phi_{,i}$, and
%
\begin{align*}
  \ln(-g_{00})_{,i} &=
  \ln(1 + 2\phi)_{,i} =
  \frac{(1 + 2\phi)_{,i}}{1 + 2\phi}
  \\ &=
  2 \phi_{,i} (1 + 2\phi)^{-1} \approx
  2 \phi_{,i} (1 - 2\phi) \approx
  2 \phi_{,i}.
\end{align*}
%
I'm not really sure how to relate this to Exercise 4, as it relates $\phi_{,\alpha}$ to four-momentum, while this relates it to pressure and density.

\textbf{7}
Consider the (i) Minkowski, (ii) Schwarzschild, (iii) Kerr, and (iv) Robertson--Walker metrics.

(a) Find the conserved components $p_\alpha$ of a the four-momentum of a particle in free-fall.

For this I will use Equation 7.29:
%
\begin{displaymath}
  m \dv{p_\beta}{\tau} = \frac{1}{2} g_{\nu\alpha,\beta} p^\nu p^\alpha.
\end{displaymath}
%
What this tells us is that if $g_{\alpha\beta}$ is independent of $x^\mu$, then $p_\mu$ is constant along the trajectory.

For (i), the metric is independent of all coordinates $(t,x,y,z)$, and so all $p_\alpha$ are conserved.

For (ii), the metric depends on coordinates $r$ and $\theta$, but not $t$ and $\phi$, so only $p_t$ and $p_\phi$ are conserved.

For (iii) we have the same dependencies as (ii).

For (iv) there is an additional time dependence, and so only $p_\phi$ is conserved.

(b) Use the metric for a flat spacetime in spherical polar coordinates to argue that the Schwarzschild and Robertson--Walker metrics are spherically symmetric.

Our metric in (i) can be expressed in spherical polars as
%
\begin{displaymath}
  \dd{s}^2 =
 -\dd{t}^2 + \dd{r}^2 + r^2 (\dd{\theta}^2 + \sin^2\theta \dd{\phi}^2).
\end{displaymath}
%
The Schwarzschild metric can be obtained from this by multiplying $\dd{t}^2$ by $(1 - 2 M / r)$, and dividing $\dd{r}^2$ by it. This newly introduced term only introduces a new radial dependence (the $r^{-1}$ term), not an angular one, so it retains spherical symmetry.

The Robertson--Walker metric can be obtained by dividing $\dd{r}^2$ by $(1 - kr^2)$, and then multiplying everything \emph{except} $\dd{t}^2$ by $R^2(t)$. Again, the $(1 - kr^2)$ term only introduces a radial dependence in its $r^2$ term, and for a given time $t$, $R^2(t)$ is a constant, so spherical symmetry is retained.

(c) For (i') and (ii)--(iv), a geodesic which at one point has $\theta = \pi/2$ and $p^\theta = 0$ (i.e. tangent to the equatorial plane) conserves these quantities. For (i'), (ii), and (iii),use $\vec{p} \cdot \vec{p} = -m^2$ to find $p^r$ as a function of $m$, other conserved quantities, and known functions of position.

(i')
%
\begin{align*}
  \vec{p} \cdot \vec{p} &=
  g_{\alpha\beta} p^\alpha p^\beta =
  g_{\alpha\alpha} (p^\alpha)^2 =
  g_{tt} (p^t)^2 +
  g_{rr} (p^r)^2 +
  g_{\theta\theta} (\cancelto{0}{p^\theta})^2 +
  g_{\phi\phi} (p^\phi)^2
  \\ &=
  -(p^t)^2 + (p^r)^2 + r^2 \cancelto{1}{\sin^2(\theta)} (p^\phi)^2 =
  -m^2
  \\ \implies
  (p^r)^2 &=
  (p^t)^2 - r^2 (p^\phi)^2 - m^2 =
  g^{tt} (p_t)^2 - r^2 g^{\phi\phi} (p_\phi)^2 - m^2 =
  -(p^t)^2 - (p^\phi)^2 - m^2
  \\ \implies
  p^r &=
  \pm\sqrt{-[(p^t)^2 + (p^\phi)^2 + m^2]}
\end{align*}
%
(ii)
%
\begin{align*}
  \vec{p} \cdot \vec{p} &=
  g_{tt} (p^t)^2 +
  g_{rr} (p^r)^2 +
  g_{\phi\phi} (p^\phi)^2
  \\ &=
 -(1 - 2M/r) (p^t)^2 +
  (1 - 2M/r)^{-1} (p^r)^2 +
  r^2 \cancelto{1}{\sin^2\theta} (p^\phi)^2 = -m^2
  \\ \implies
  (p^r)^2 &=
  (1 - 2M/r) [ (1 - 2M/r) (p^t)^2 - r^2 (p^\phi)^2 - m^2 ]
  \\ &=
 -(1 - 2M/r) [ (1 - 2M/r) (p_t)^2 + (p_\phi)^2 + m^2 ]
\end{align*}
%
(iii)
%
This metric gets a bit messy, so I will keep things more abstract. First, I will simplify the metric, utilizing the fact that $\theta = \pi/2$.
%
\begin{gather*}
  \dd{s}^2 =
 -\frac{\Delta - a^2}{r^2} \dd{t}^2 -
  2 \frac{2 M a}{r} \dd{t} \dd\phi +
  \frac{(r^2 + a^2)^2 - a^2 \Delta}{r^2} \dd\phi^2 +
  \frac{r^2}{\Delta} \dd{r}^2 +
  r^2 \dd\theta^2
  \\
  g_{tt} = -\frac{\Delta - a^2}{r^2};
  \quad
  g_{rr} = \frac{r^2}{\Delta};
  \quad
  g_{\theta\theta} = r^2;
  \quad
  g_{\phi\phi} = \frac{(r^2 + a^2)^2 - a^2 \Delta}{r^2};
  \quad
  g_{t\phi} = -\frac{2 M a}{r},
  \\
  \lambda \equiv
  a^6 - 2 (D - r^2) a^4 + (r^4 - 4 M^2 r^2 - 2 D r^2 + D^2) a^2 - D r^4
  \\
  g^{tt} = r^2 (a^4 - (D - 2 r^2) a^2 + r^4) / \lambda;
  \quad
  g^{rr} = \frac{D}{r^2};
  \quad
  g^{\theta\theta} = \frac{1}{r^2};
  \quad
  g^{\phi\phi} = r^2 (a^2 - D) / \lambda;
  \quad
  g^{t\phi} = 2 a M r^3 / \lambda,
  \\
  \vec{p} \cdot \vec{p} =
  g_{tt} (p^t)^2 +
  g_{rr} (p^r)^2 +
  g_{\phi\phi} (p^\phi)^2 +
  2 g_{t\phi} (p^t p^\phi) =
 -m^2
  \\
  p^r =
  \pm\sqrt{
   -g^{rr}
    [g_{tt} (p^t)^2 +
     g_{\phi\phi} (p^\phi)^2 +
     2 g_{t\phi} (p^t p^\phi) +
     m^2]
  }
  \\
  p^t =
  g^{t\alpha} p_\alpha =
  g^{\phi\phi} p_t + g^{t\phi} p_\phi
  \\
  p^\phi =
  g^{\phi\alpha} p_\alpha =
  g^{\phi\phi} p_\phi + g^{t\phi} p_t
\end{gather*}

(d)

When $k = 0$, the line element and metric become
%
\begin{gather*}
  \dd{s}^2 =
 -\dd{t}^2 +
  R^2(t) [ \dd{r}^2 + r^2 (\dd\theta^2 + \sin^2\theta \dd\phi^2) ]
  \\
  g_{tt} = -1;
  \quad
  g_{rr} = R^2(t);
  \quad
  g_{\theta\theta} = R^2(t) r^2;
  \quad
  g_{\phi\phi} = R^2(t) r^2 \sin^2\theta.
\end{gather*}
%
Equation 7.29 with $\beta = r$ then becomes
%
\begin{displaymath}
  m \dv{p_r}{\tau} =
  \frac{1}{2} g_{\nu\alpha,r} p^\nu p^\alpha =
  \frac{1}{2} [ g_{tt,r} (p^t)^2 + g_{rr,r} (p^r)^2 ].
\end{displaymath}
%
Since $g_{tt,r} = g_{rr,r} = 0$, the RHS becomes zero, and so
%
\begin{displaymath}
  m \dv{p_r}{\tau} =
  0 \implies
  \text{$p_r$ is conserved}.
\end{displaymath}

\textbf{8}
For a coordinate system where $g_{\alpha\beta,\mu} = 0$:

(a) Show that $\tensor{T}{^\nu_{\mu;\nu}} = 0$ becomes
%
\begin{displaymath}
  \frac{1}{\sqrt{-g}} (\sqrt{-g} \tensor{T}{^\nu_\mu})_\nu = 0.
\end{displaymath}

For this, I will make mathematicians cry, and go from the \emph{solution} backwards to the starting point. So I expand the final expression, first using the Leibniz rule:
%
\begin{displaymath}
  \tensor{T}{^\nu_{\mu,\nu}} +
  \frac{(\sqrt{-g})_\nu}{\sqrt{-g}} \tensor{T}{^\nu_\mu} =
  0,
\end{displaymath}
%
and then using Equation 6.40:
%
\begin{displaymath}
  \tensor{T}{^\nu_{\mu,\nu}} +
  \tensor{\Gamma}{^\alpha_{\alpha\nu}} =
  0.
\end{displaymath}
%
Just pretend I did that backwards. Next I expand $\tensor{T}{^\nu_{\mu;\nu}}$, to show that the above expression makes it zero.
%
\begin{align*}
  \tensor{T}{^\nu_{\mu;\nu}} &=
  \tensor{T}{^\nu_{\mu,\nu}} +
  \tensor{T}{^\alpha_\mu} \tensor{\Gamma}{^\nu_{\alpha\nu}} -
  \tensor{T}{^\nu_\alpha} \tensor{\Gamma}{^\alpha_{\mu\nu}}
  \\ &=
  \tensor{T}{^\nu_{\mu,\nu}} +
  \tensor{T}{^\nu_\mu} \tensor{\Gamma}{^\alpha_{\nu\alpha}} -
  \tensor{T}{^\nu_\alpha} \tensor{\Gamma}{^\alpha_{\mu\nu}}.
\end{align*}
%
Note that the positive terms are just the expression from before, which we showed was zero, so we're left with
%
\begin{displaymath}
  \tensor{T}{^\nu_{\mu;\nu}} =
  \tensor{T}{^\nu_\alpha} \tensor{\Gamma}{^\alpha_{\mu\nu}}.
\end{displaymath}
%
Now we expand this
%
\begin{align*}
  \tensor{T}{^\nu_{\mu;\nu}} &=
  -\frac{1}{2} \tensor{T}{^\nu_\alpha} g^{\alpha\beta}
  (g_{\beta\mu,\nu} + \cancel{g_{\beta\nu,\mu}} - g_{\mu\nu,\beta})
  \\ &=
  -\frac{1}{2} \tensor{T}{^{\nu\beta}}
  (g_{\beta\mu,\nu} - g_{\mu\nu,\beta}) =
  -\frac{1}{2} \tensor{T}{^{(\nu\beta)}}
  A_{[\nu\beta]\mu} =
  0.
\end{align*}

(b) Suppose $T^{\alpha\beta}$ is zero except in a bounded region of the space-like hypersurface $x^0 =$ constant. Show that Equation 7.41 implies that
%
\begin{displaymath}
  \int_{x^0 = \mathrm{const}} \tensor{T}{^\nu_\mu} \sqrt{-g} n_\nu \dd[3]{x}
\end{displaymath}
%
does not depend on $x^0$, so long as $n_\nu$ is the unit normal to the hypersurface.

Using Equation 7.41 and the differential in Equation 6.18, we take the integral
%
\begin{displaymath}
  \int {
    \frac{1}{\sqrt{-g}} (\sqrt{-g} \tensor{T}{^\nu_\mu})_\nu \sqrt{-g}
  } \dd[4]{x} =
  \int {
    (\sqrt{-g} \tensor{T}{^\nu_\mu})_{,\nu} \dd[4]{x}
  } \dd[4]{x}.
\end{displaymath}
%
Now we use Equation 6.44:
%
\begin{align*}
  \int {
    (\sqrt{-g} \tensor{T}{^\nu_\mu})_{,\nu} \dd[4]{x}
  } \dd[4]{x} &=
  \oint {
    \sqrt{-g} n_\nu \tensor{T}{^\nu_\mu}
  } \dd[3]{S}
  \\ &=
  \int_{x^0 = \mathrm{const}} \sqrt{-g} n_\nu \tensor{T}{^\nu_\mu} \dd[3]{x}
\end{align*}

(c) Now consider flat Minkowski space with a global inertial frame in spherical polar coordinates. Show that, from part (b), we have
%
\begin{displaymath}
  J =
  \int_{t=\mathrm{const}} {
    \tensor{T}{^0_\phi} r^2 \sin\theta
  } \dd{r} \dd\theta \dd\phi,
\end{displaymath}
%
which is independent of $t$. This is the system's total angular momentum.

Since we are in flat Minkowski space, the unit-normal one form has components $\tilde{n} \to (1, 0, 0, 0)$, so only the $\tensor{T}{^0_\mu}$ term is retained. We also have $x^0 \to t$, so we can write the expression from (b) as
%
\begin{displaymath}
  \int_{t = \mathrm{const}} \sqrt{-g} \tensor{T}{^0_\mu} \dd[3]{x}.
\end{displaymath}
%
We also know that $\sqrt{-g} \dd[3]{x}$ in spherical polars is $r^2 \sin\theta \dd{r} \dd\theta \dd\phi$, so we can write this as
%
\begin{displaymath}
  \int_{t = \mathrm{const}} {
    \tensor{T}{^0_\mu} r^2 \sin\theta
  } \dd{r} \dd\theta \dd\phi.
\end{displaymath}
%
Taking the $\phi$ component of $\tensor{T}{^0_\mu}$, we get something which we call $J$:
%
\begin{displaymath}
  J =
  \int_{t = \mathrm{const}} {
    \tensor{T}{^0_\phi} r^2 \sin\theta
  } \dd{r} \dd\theta \dd\phi.
\end{displaymath}

(d) Now express the previous integral in terms of the components of $T^{\alpha\beta}$ on the Cartesian basis, ultimately arriving at
%
\begin{displaymath}
  J =
  \int {
    (x T^{y0} - y T^{x0})
  } \dd{x} \dd{y} \dd{z}
\end{displaymath}

\begin{align*}
  J &=
  \int_{t = \mathrm{const}} {
    \tensor{T}{^0_\phi} r^2 \sin\theta
  } \dd{r} \dd\theta \dd\phi
  \\ &=
  \int_{t = \mathrm{const}} {
    \tensor{\Lambda}{^\alpha_\phi} \tensor{T}{^0_\alpha} r^2 \sin\theta
  } \dd[3]{x}
  \\ &=
  \int_{t = \mathrm{const}} (
    \tensor{\Lambda}{^x_\phi} \tensor{T}{^0_x} +
    \tensor{\Lambda}{^y_\phi} \tensor{T}{^0_y} +
    \tensor{\Lambda}{^z_\phi} \tensor{T}{^0_z}
  ) \dd[3]{x}
  \\ &=
  \int_{t = \mathrm{const}} (
    (-r \sin\theta \sin\phi) \tensor{T}{^0_x} +
    ( r \sin\theta \cos\phi) \tensor{T}{^0_y} +
    (0) \tensor{T}{^0_z}
  ) \dd[3]{x}
  \\ &=
  \int_{t = \mathrm{const}} (
    x \tensor{T}{^0_y} -
    y \tensor{T}{^0_x}
  ) \dd[3]{x}
  \\ &=
  \int_{t = \mathrm{const}} (
    \eta_{yy} x \tensor{T}{^{0y}} -
    \eta_{xx} y \tensor{T}{^{0x}}
  ) \dd[3]{x}
  \\ &=
  \int_{t = \mathrm{const}} (
    x \tensor{T}{^{0y}} -
    y \tensor{T}{^{0x}}
  ) \dd[3]{x}
\end{align*}

\textbf{10}

(a) Show that if the vector field $\xi^\alpha$ satisfies Killing's equation,
%
\begin{displaymath}
  \grad_\alpha \xi_\beta + \grad_\beta \xi_\alpha = 0,
\end{displaymath}
%
then $p^\alpha \xi_\alpha$ is constant along a geodesic.

If $p^\alpha \xi_\alpha$ is constant along a geodesic, then $p^\alpha \xi_{\alpha;\beta} = 0$, so we simply have to show that this follows from Killing's equation.

Killing's equation can be rewritten as
%
\begin{displaymath}
  \xi_{\beta;\alpha} + \xi_{\alpha;\beta} = 0 \implies
  \xi_{\beta;\alpha} = -\xi_{\alpha;\beta}.
\end{displaymath}
%
Now we combine this with the geodesic equation,
%
\begin{displaymath}
  p^\alpha \xi_{\beta;\alpha} = -p^\alpha \xi_{\alpha;\beta} = 0.
\end{displaymath}
%
And there we have it!

(b) Find ten Killing fields for Minkowski spacetime.

Since the basis vectors in Minkowski spacetime are all constant, $\grad_\beta \vec{e}_\alpha = 0$, and so we get four from $\vec{e}_t$, $\vec{e}_x$, $\vec{e}_y$, $\vec{e}_z$. According to part (c), we get a Killing field from any \emph{constant} linear combination of these four, and so from that we may create an infinity of Killing fields. Schutz's solutions manual also lists expressions such as $x \vec{e}_t - t \vec{e}_x$ as Killing fields, which are linear combinations, but the coefficients are non-constant. I give an attempted derivation below, although at the very last step it turns out not to work, and I pretend it does anyway. I claim that the general form of Schutz's expressions is: $x^\alpha \vec{e}_\beta - x^\beta \vec{e}_\alpha$.

\begin{align*}
  \grad_\alpha (x^\alpha \vec{e}_\beta) -
  \grad_\alpha (x^\beta \vec{e}_\alpha) +
  \grad_\beta (x^\alpha \vec{e}_\beta) -
  \grad_\beta (x^\beta \vec{e}_\alpha)
  &=
  \tensor{x}{^\alpha_{;\alpha}} \vec{e}_\beta -
  \tensor{x}{^\beta_{;\alpha}} \vec{e}_\alpha +
  \tensor{x}{^\alpha_{;\beta}} \vec{e}_\beta -
  \tensor{x}{^\beta_{;\beta}} \vec{e}_\alpha
  \\ &=
  \vec{e}_\beta -
  \vec{e}_\alpha -
  \tensor{x}{^\beta_{,\alpha}} \vec{e}_\alpha +
  \tensor{x}{^\alpha_{,\beta}} \vec{e}_\beta
  \\ &=
  \vec{e}_\beta -
  \vec{e}_\alpha -
  \tensor{\Lambda}{^\beta_\alpha} \vec{e}_\alpha +
  \tensor{\Lambda}{^\alpha_\beta} \vec{e}_\beta
  \\ &
  \text{(magnets at work here)}
  \\ &=
  \vec{e}_\beta -
  \vec{e}_\alpha -
  \vec{e}_\beta +
  \vec{e}_\alpha =
  0
\end{align*}

(c) Prove that any \emph{constant} linear combination of two Killing fields $\vec\xi$ and $\vec\eta$ is itself a Killing field.

\begin{align*}
  &
  \grad_\mu \xi_\nu + \grad_\nu \xi_\mu = 0
  \\
  &
  \grad_\mu \eta_\nu + \grad_\nu \eta_\mu = 0
  \\ &
  \grad_\mu (\alpha \xi_\nu + \beta \eta_\nu) +
  \grad_\nu (\alpha \xi_\mu + \beta \eta_\mu)
  \\ =&
  \alpha \grad_\mu \xi_\nu + \beta \grad_\mu \eta_\nu +
  \alpha \grad_\nu \xi_\mu + \beta \grad_\nu \eta_\mu
  \\ =&
  \alpha (\grad_\mu \xi_\nu + \grad_\nu \xi_\mu) +
  \beta (\grad_\mu \eta_\nu + \grad_\nu \eta_\mu) =
  0
\end{align*}

(d)
Show that the Lorentz transforms of the fields in (b) are also Killing fields.

Applying a Lorentz transform $\tensor{\Lambda}{^\mu_\nu}$ we get the expression $\tensor{\Lambda}{^\mu_\nu} \qty(x^\alpha \vec{e}_\beta - x^\beta \vec{e}_\alpha)$.
%
\begin{align*}
  &
  \grad_\alpha
  [
    \tensor{\Lambda}{^\mu_\nu}
    (x^\alpha \vec{e}_\beta - x^\beta \vec{e}_\alpha)
  ] +
  \grad_\beta
  [
    \tensor{\Lambda}{^\mu_\nu}
    (x^\beta \vec{e}_\alpha - x^\alpha \vec{e}_\beta)
  ]
  \\ =&
  \tensor{\Lambda}{^\mu_{\nu;\alpha}}
  [
    (x^\alpha \vec{e}_\beta - x^\beta \vec{e}_\alpha) +
    (x^\beta \vec{e}_\alpha - x^\alpha \vec{e}_\beta)
  ]
  \\ =&
  \tensor{\Lambda}{^\mu_{\nu;\alpha}}
  [
    x^\alpha \vec{e}_\beta - x^\alpha \vec{e}_\beta +
    x^\beta \vec{e}_\alpha - x^\beta \vec{e}_\alpha
  ] = 0
\end{align*}

(e) Use the results in Exercise 7(a) to find Killing vectors for the non-Minkowski metrics listed in (ii)--(iv).

(ii) Since the conserved quantities are $p_t$ and $p_\phi$, then the Killing fields are any constant linear combinations or Lorentz transforms of $\vec{e}_t$, $\vec{e}_\phi$, and $\phi \vec{e}_t - t \vec{e}_\phi$.

(iii) Same as (ii).

(iv) Only $p_\phi$ is conserved, so any constant multiple of $\vec{e}_\phi$ is a Killing field.

\end{document}