\title{Legitimate States and Behavior}
%\author{}
\date{}

\begin{document}

\tableofcontents

\section{Defining the Invariant}

Let's define a predicate for the system where all colors in the ring are distinct.
\begin{code}
predicate I := (forall i <- Nat % N : c[i-1]!=c[i]);
\end{code}

Since we will use $I$ as an invariant, it must be defined with shadow or direct variables (not puppet variables).

\section{Convergence and Behavior}

Stabilization can be defined as both convergence and closure.
That is, a system should eventually reach $I$ and remain within $I$.
This is generally too relaxed to be useful, but it is supported by writing the following in a \ilfile{.prot} file:
\begin{code}
(future & closed) (I);
\end{code}

We often want to specify how the protocol behaves within the invariant.
The simplest case is that of silent protocols.
Here we say the protocol should reach the invariant $I$ and no actions should execute within $I$.
This is written as:
\begin{code}
(future & silent) (I);
\end{code}

When there is shadow protocol defined (using \ilcode{shadow action:} statements in process definitions), we can enforce that it is executed within $I$.
Puppet variables are allowed to be changed in any way, but shadow (and direct) variables must eventually change.
That is, some transitions in the protocol may not change any shadow variables, which will appear as a self-loop in the shadow protocol.
\begin{code}
(future & shadow) (I);
\end{code}
If no shadow protocol is defined, this statement allows any finite or infinite executions within the invariant provided that the shadow variables are not changed.

Allowing shadow self-loops within $I$ is undesirable since they delay operation of the shadow protocol.
These can be forbidden by forcing all transitions in $I$ to correspond with transitions in the shadow protocol.
Write this as:
\begin{code}
(future & active shadow) (I);
\end{code}
Note that the shadow protocol must not have deadlocks.

\section{Eventual Closure}

Sometimes it is okay to find a protocol that stabilizes to some invariant $I'$ which is a subset of the original invariant $I$.
This is the method of adaptive programs as described in \href{http://dx.doi.org/10.1109/32.92911}{Adaptive Programming} by Gouda and Herman.
The three invariant styles above can be stated with this notion of eventual closure:
\begin{code}
(future & future silent) (I);
(future & future shadow) (I);
(future & future active shadow) (I);
\end{code}

\textbf{Note:} Always use this notation or the next section's notation when using pure \ilcode{shadow} variables (not \ilcode{direct} variables).
Shadow variables are assigned completely based on puppet (and direct) variables, so any nontrivial protocol will have transitions that leave $I$.
Therefore $I'$ will need to be a proper subset of $I$.

\section{Modding out Puppet Variables}

Sometimes we want to enforce that each state in $I$ is kept within $I'$ for at least some values of puppet variables.
That is, for every valuation of shadow (or direct) variables that satisfies $I$, a state exists in $I'$ with the same valuation (but some arbitrary valuation of puppet variables).
In other words, we want $I$ to equal $I'$, ignoring differences caused by puppet variables.

Semantics follow directly from the previous section.
To synthesize a protocol which is silent in some $I'$, we would write \ilcode{(future & silent) (I_prime);} if we knew $I'$.
It can be difficult to determine $I'$ manually, so we prefer to specify $I$ and use a certain notation to say that $I=I'$ \textit{modulo} the puppet variables.
This is written as:
\begin{code}
((future & silent) % puppet) (I);
\end{code}

Likewise, if we want to enforce execution of the shadow protocol within $I'$ (i.e., \ilcode{(future & shadow) (I_prime);}), we write:
\begin{code}
((future & shadow) % puppet) (I);
\end{code}
This is the general constraint we used in \href{http://dx.doi.org/10.1007/978-3-319-11764-5_18}{Synthesizing Self-stabilization through Superposition and Backtracking}.

Finally, if we want to force all actions within $I'$ to correspond with actions in the shadow protocol (i.e., \ilcode{(future & active shadow) (I_prime);}), we write:
\begin{code}
((future & active shadow) % puppet) (I);
\end{code}

\section{Eventual Behavior}

In some cases, forcing silence or an active shadow protocol within the entire invariant $I'$ is too strict.
Rather, we are often content to enforce these constraints on the protocol's eventual behavior.
This is done by an additional statement in the specification \ilfile{.prot} file.
That is, the statements in this section are optional and are given in addition to lines such as \ilcode{(future & shadow) (I);} or \ilcode{((future & shadow) % puppet) (I);}.

When the shadow protocol is silent, we often want to enforce a silent protocol overall in order to minimize network traffic.
This is expressed by adding the following line:
\begin{code}
future silent;
\end{code}
We use this in \url{\examplespec/OrientRing.prot} example where the invariant is defined as \ilcode{(future & shadow) (I);}.
In this case, we desire a silent protocol, but the two alternative ways to define the invariant have deficiencies:
(1) \ilcode{(future & silent) (I);} is too strict, and
(2) \ilcode{((future & silent) % puppet) (I);} does not force $I'=I$, which disables some search optimizations.

When the shadow protocol is live, we often want the synthesized protocol to execute its actions exactly (i.e., eventually, every transition of the system corresponds to a shadow action).
This desire is for practicality - we want the service to respond quickly if no faults are occurring.
Write this as:
\begin{code}
future active shadow;
\end{code}
We could use this in \url{\examplespec/TokenRingSuperpos.prot} where the invariant is defined as \ilcode{(future & shadow) (I);}.
Though it is not used in the example itself, we could add \ilcode{future active shadow;} if we want every transition within the invariant to pass a token.
We would do this over simply defining the invariant do be active, since the alternative ways to define the invariant have deficiencies:
(1) \ilcode{(future & active shadow) (I);} is too strict, and
(2) \ilcode{((future & active shadow) % puppet) (I);} does not force $I'=I$, which disables some search optimizations.

\end{document}


\documentclass[10pt,conference,compsocconf]{IEEEtran}

\usepackage{hyperref}
\usepackage{graphicx}	% For figure environment
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{float}
\usepackage{url}
\newcommand{\beginsupplement}{%
	\setcounter{table}{0}
	\renewcommand{\thetable}{S\arabic{table}}%
	\setcounter{figure}{0}
	\renewcommand{\thefigure}{S\arabic{figure}}%
}

\begin{document}
\title{Extreme Wind Analysis}

\author{
	Matthias Minder, Yves Rychener
}

\maketitle

\begin{abstract}
Modeling extreme conditions has many applications in Finance, Insurance, Environment and others. In this article we report the results of our analysis on the extreme weather conditions leading to extreme thunderstorms in central Kansas in the United States using various approaches. As expected, we consistently discover a seasonality, showing that thunderstorms are much more extreme during summer months. Moreover, during all months except December, there is not enough evidence to support a time-dependence. Interestingly, in the month of December extreme thunderstorms seem to significantly decrease in severeness over the course of time. Finally, we provide estimated return levels for every month, which could be valuable for risk assessment in insurance.
\end{abstract}

\section*{Introduction}
Modeling extreme weather events is of interest for a variety of applications, such as risk assessment for insurance companies or conception of preventive measures. In particular, questions about how often a particular event will occur, how severe events can get, and whether there are seasonal or year-dependent trends are of interest. Within the scope of this report, we will address these questions for extreme thunderstorms on a 1° longitude and 1° latitude grid cell with south-west coordinates 38° latitude and -100° longitude, situated in central Kansas. The measured quantities are the Connective Available Potential Energy ($CAPE$) and the Storm Relative Helicity ($SRH$), which have to be simultaneously high for severe thunderstorms to occur. Three-hourly time series of these events are taken into account from January 1st 1979 at 00:00 to December 31st 2015, 21:00.
\par
In particular, we will study the structure variable denoted $PROD$ given by $PROD = \sqrt{CAPE} \times SRH$. It captures concurrently high values of $SRH$ and $CAPE$, and is thus apt for modeling the risk of thunderstorms. Every month will be treated separately in order to capture seasonal differences. To model extreme values, a generalized extreme value distribution will be fitted to the monthly maxima of $PROD$ using maximum likelihood estimation as well as Bayesian approaches. Moreover, the generalized extreme value distribution will be fitted to the $r$-largest order statistic for every month to determine whether that improves the fit. Subsequently, we will assess dependence of $PROD$ upon time and the NINO 3.4 index, an established indicator of the El-Niño Southern Oscillation ($ENSO$).
\par
Following this, $CAPE$ and $SRH$ are considered separately. We will study whether they are asymptotically dependent, before fitting bivariate models to the joint extremes of $CAPE$ and $SRH$.
Finally, 50- and 100-year return levels of $PROD$ are calculated based on fitting a point process model to $PROD$ with maximum likelihood estimation, based on the Bayesian fit, and based on simulated values of $CAPE$ and $SRH$ from the bivariate model fitted before.

\section*{Preliminary Analysis}
\begin{figure}
	\centering
	\includegraphics[width=0.35\textwidth]{../plots/full_time_series.pdf}
	\includegraphics[width=0.35\textwidth]{../plots/monthly_max_series.pdf}
	\caption{Three-hourly values (top) and monthly maxima (bottom) of $PROD$ values for the entire analyzed period.}
	\label{fig:timeseries}
\end{figure}
Plotting the full time series and the monthly maxima as shown in Figure \ref{fig:timeseries} clearly shows the seasonality of the data, with high values of $PROD$ occurring mainly during summer. This clearly shows the necessity of separate treatment of months. Moreover, there seems to be some upward trend following time, with more extreme values of $PROD$ in recent years.

\section*{Fitting Generalized Extreme Value Distribution to PROD}
In order to understand the behavior of the monthly maxima, we fitted a generalized extreme value (GEV) distribution to $PROD$ for each month separately with three different approaches.
\begin{figure}
	\centering
	\textbf{January}\\
	\includegraphics[width=0.35\textwidth]{../plots/monthly_mle_diag/01_monthly_mle_diag.pdf}\\
	\textbf{December}\\
	\includegraphics[width=0.35\textwidth]{../plots/monthly_mle_diag/12_monthly_mle_diag.pdf}
	\caption{Diagnostic plots for fitting GEV to the data using maximum likelihood estimation for January (top) and December (bottom). Whereas in January the model fits the data, as shown by the fact that the observed values are within the confidence range for probability plot, this is not the case for December, indicating a poor fit.}
	\label{fig:mle_diag}
\end{figure}
\par
First, we fitted the values using maximum likelihood estimation (MLE). Fitting was done using the evd package in R, using the Nelder-Mead optimization method and standard parameters (as specified in the evd-help files). The quality of the fit was assessed using diagnostic plots, as shown for January and December in Figure \ref{fig:mle_diag}. The model performed well with the exception of September and December: In September optimization didn't succeed, whereas in December the observed values lie outside of the given confidence intervals, as shown in Figure \ref{fig:mle_diag}. For both of these months, no standard error could be calculated due to singularity of the observed Fisher information matrix. Since we expect some continuity over the course of the year, the problem wasn't further investigated as inferences for the missing months can be made from their adjacent months.
\par
Then, we fitted the values using the Metropolis-Hastings algorithm using the \texttt{evdbayes} package in R \cite{evdbayes}. Since we don't know an underlying dependence structure between the parameters, we naively assumed independence by using a tri-variate normal distribution with mean zero and a diagonal covariance matrix as prior. The prior variances in the diagonal were chosen as 100'000 for the location and scale parameter, and as 100 for the shape parameter in order to cover the entire parameter space.
\par
Here, we will give an intuitive explanation of the Metropolis-Hastings algorithm; for a more detailed and mathematically rigorous explanation, please refer to slides 82-86 of the course slides. This algorithm creates a Markov chain with stationary distribution $\pi(x)$, where $\pi(x)$ is also the desired distribution of the parameters of our model. The transition probability from $x$ to $y$ is $p(x,y)=\alpha(x,y) q(x,y)$, where $\alpha(x,y)$ is the acceptance rate, and $q(x,y)$ is the proposition density. We can select the proposition density $q(x,y)$ ourselves, usually a normal distribution is chosen, the acceptance rate can be shown to be $\alpha(x,y)=min(\frac{\pi(y) q(y,x)}{\pi(x) q(x,y)},1)$.
\par
We can imagine the sampling as follows: An agent is navigating the Markov chain. At every iteration, it will sample a proposed step to take from the distribution $q(x,y)$. Then, with probability $\alpha(x,y)$, it is allowed to take said step and move to a new state. With probability $1-\alpha(x,y)$, the step is rejected and we stay at the current state. We can estimate the (unknown) stationary distribution of the chain by navigating $n$ iterations and keeping track of the empirical state distribution. As $n \to \infty$ (or in practice for big $n$), we converge to the true stationary distribution. The proposal standard deviation dictates how big the proposal steps are. If the agent wants to take steps that are too big, he gets rejected all the time and cannot explore the chain. If the proposal steps are too small, he cannot fully explore the chain since $n$ has to be finite in order to finish our calculation. In practice, we have to remove some "burn in", since we may start very far away from the stationary distribution. Also, thinning is applied, since each state is dependent on the preceding state, resulting in high autocorrelation.
\par
The proposal standard deviations were fine-tuned to obtain acceptance rates between 0.2 and 0.4. In order to avoid having to fine-tune every month separately, we implemented the following very simple optimization algorithm: If the acceptance rates for a given parameter were too high, the proposal standard deviation for said parameter were multiplied with 1.5. In the opposite case for low acceptance rates, the proposal standard deviation was divided by 2. The Metropolis-Hastings algorithm was run with 30'000 iterations. The chain was thinned with a factor 300 in order to avoid dependence between steps of the Markov chain. The thinning was validated with autocorrelation plots (not shown). The final parameter was determined to be the median of the posterior distribution, in order to be robust to outliers and be more adapted to skewed distributions.
\par
\begin{figure}
	\centering
	\textbf{May}\\
	\includegraphics[width=0.35\textwidth]{../plots/r_larg_diag_may.pdf}\\
	\textbf{July}\\
	\includegraphics[width=0.35\textwidth]{../plots/r_larg_diag_july.pdf}
	\caption{Diagnostic plots for fitting r-largest-order statistic for January (top) and December (bottom). Whereas in may the model fits the data very well, as shown by the fact that the observed values are within the confidence range for return level plot, this is not the case for July, indicating a poor fit. Also the probability plot indicates a better fit in May.}
	\label{fig:r_diag}
\end{figure}
We then investigated how taking into account the $r$-largest values for every month affects the fit. For fitting the $r$-largest order statistic, we have to find the best $r$ first. This was done by comparing the different parameter standard deviations and MLE deviances: When taking into account $r$ largest values, the standard deviation for all parameters is expected to be reduced by a factor $\sqrt{r}$ with respect to the model using only maxima. If it is reduced by less, this suggests that the additional order statistics don't bring important information and thus don't improve the fit. Similarly, the deviance is expected to be reduced when using more data. However, if this reduction of deviance is small, this again suggests that the additional order statistics don't improve the data. Using these paradigms, we found a reasonable choice to be $r=2$. This choice was confirmed using the diagnostic plots (Figure \ref{fig:r_diag}), which indicated a good fit for all months with exception of July. In Figure \ref{fig:r_diag}, we show the diagnostic plots for May to exemplify a good fit and July to show it's poor fit.
\par
We then compare the estimates for the location, shape and scale parameter obtained by these three methods. As we observe in Figure \ref{fig:params}, all three parameters obtained with maximum likelihood estimation of maxima as well as the $r$-largest order statistic correspond well. This is expected, since the two methods rely both on maximum likelihood estimation of the GEV distribution, where the likelihood is slightly different to account for the $r$-largest order statistics instead of solely the maximum. However, the results obtained using Bayesian imputation seem very different. The results were validated using different priors, tolerances for acceptance ratios and initial values and were determined to be stable. Such a difference is described for the Weibull distribution (a special case of the GEV with negative shape parameter) by Smith and Naylor, where the Bayesian approach is determined to be more stable \cite{Smith1987}. They attribute the difference to the fact that maximum likelihood theory relies on an asymptotically quadratic log likelihood, whereas Bayesian techniques rely on integration and not on asymptotics, and are thus probably better suited for unusually shaped log likelihoods.

\par
\begin{figure}
	\centering
	\includegraphics[width=0.35\textwidth]{../plots/evolution_eta.pdf}\\
	\includegraphics[width=0.35\textwidth]{../plots/evolution_tao.pdf}\\
	\includegraphics[width=0.35\textwidth]{../plots/evolution_xi.pdf}\\
	\caption{Location, scale and shape parameter estimates of GEV distribution, when fitted to monthly extremes of PROD values for every month separately, using maximum likelihood estimation, Bayesian fitting and the $r$-largest order statistics (with $r=2$).}
	\label{fig:params}
\end{figure}

The parameter evolution throughout the year is somewhat similar between Bayesian and maximum likelihood parameter estimation: Values of $PROD$ seem to be higher during summer months, in accordance to the observation that heavy thunderstorms tend to occur more often during this time. Whereas maximum likelihood estimation attributes this difference to both higher location and scale parameters in summer, Bayesian estimation attributes it solely to a higher scale parameter. Moreover, the shape parameter is estimated to be positive during the winter months from December to February by both methods. This would correspond to absence of an upper bound to values of $PROD$. Meanwhile, estimates for the remaining months differ: Bayesian estimation predicts a negative shape parameter and thus existence of an upper bound to $PROD$ during that time, whereas maximum likelihood estimation seems to favor a shape parameter of zero with no such upper bound. It is thus not possible from this analysis to consistently predict an upper bound on $PROD$ values.
%When considering the evolution of the three parameters as estimated with maximum likelihood and Bayesian fitting over the course of the year, the following can be observed: Both location and shape parameters are higher during summer than during winter months. According to this result, $PROD$ values are more variable and more extreme during this period, leading to more intense thunderstorms. Moreover, the shape parameter is non-negative for all months except July. This suggests that during these months, there exists no upper bound to $PROD$ values. In July however, the shape parameter is negative, in fact by more than two standard errors (not shown). This significantly indicates a negative shape parameter and an associated upper bound for $PROD$ values. However, we argue that since we expect some smoothness of weather behavior throughout the year, there is no reason for one month to admit for an upper bound when all others don't. This result is likely a relic of the small amount of data and thus the variability of the fit.

\section*{Dependence of PROD on Time and ENSO}
A dependence test of $PROD$ on a factor $x$ can be done by likelihood ratio test. Within the scope of this analysis, dependence on time and ENSO as determined by the NINO 3.4 index is assessed. Before fitting the linear trend, we center and renormalise the influencing factor with respect to its mean and standard deviation as recommended in the \texttt{fgev} help files. We tested for linear dependence to account for gradual regime changes, and for a step function dependence centered at the factor mean to allow for rapid changes. More formally, the linear dependence is modeled
\begin{align*}
	\eta(x_{norm}) = \eta_0 + \eta_1*x_{norm}
\end{align*}
while the step change is modeled as
\begin{align*}
	\eta(x_{norm}) = \begin{cases} \eta_0+\eta_1 & \textrm{if } x_{norm}>0\\ \eta_0 & \textrm{otherwise} \end{cases}
\end{align*}
The test was formulated such that the model with constant $\eta$ is the null hypothesis, and the model with factor-dependent $\eta$ is the alternative hypothesis. We employ the Bonferroni multiple testing method to take into account the multiple tests at 95\% significance level arising from the different months tested.
\par
Figure \ref{fig:dependance_test} displays the different ratios and the 95\% significance level (red) for linear dependence. We observe that independence with respect to ENSO is rejected in October, while independence with respect to time is rejected in December. For all other months, the null hypothesis cannot be rejected for a significance level of 95\%. Moreover, Figure \ref{fig:dependence_test_step} shows the likelihood ratio and 95\% significance level (red) for step dependence. Here, independence with respect to time is only rejected in December, while the null hypothesis is retained in all other months, and when testing for independence with respect to ENSO.
\par
It is interesting that the month of December is consistently determined to be time dependent, whether that dependence has a linear or step-function shape, while all other months are determined to be time independent. Moreover, contrary to expectation (because of global warming), the detected linear trend is negative. This suggests that thunderstorms have been getting less severe in December in recent years at the particular location of our measured data. However, this conclusion is based on very little data, and only applies to a single location. More thorough analysis should be done before drawing conclusions from this results.
Dependence on ENSO is determined to be of linear nature in October, whereas a step function doesn't sufficiently capture this change. Moreover, since the slope parameter is positive, this suggests that El Niño oscillations positively affect the thunderstorm activity in October.
\par
We will not use a time dependent model for estimation of the return levels in December, since the severity is decreasing, and therefore neglecting it will not result in an underestimation of the return level.
ENSO dependence will also not be taken into account, since we have no way to predict the covariate (ENSO).

\begin{figure}
	\centering
	\includegraphics[width=0.35\textwidth]{../plots/enso_dependance.pdf}\\
	\includegraphics[width=0.35\textwidth]{../plots/time_dependance.pdf}
	\caption{Plots for likelihood ratios and 95\% significance levels for linear dependence}
	\label{fig:dependance_test}
\end{figure}

\begin{figure}
	\centering
	\includegraphics[width=0.35\textwidth]{../plots/enso_dependance_step.pdf}\\
	\includegraphics[width=0.35\textwidth]{../plots/time_dependance_step.pdf}
	\caption{Plots for likelihood ratios and 95\% significance levels for step dependence}
	\label{fig:dependence_test_step}
\end{figure}
\section*{Clustering of Extremes}
The general theory for the GEV is under the assumption that the samples are independent. If dependence is present, we can estimate the clustering using the extremal index $\theta$. There are many interpretations of the extremal index, we will only give 2 here. An intuitive interpretation is that $\theta^{-1}$ is the mean limiting size of the clusters of threshold exceedances. For a more mathematical interpretation, let $\{X_i\}$ be a stationary process and let  $\{X_i^*\}$ be independent variables with the same marginal distribution. If the maxima of the $X_i$ have a limiting distribution $H(z)$ and the maxima of $X_i^*$ have a limiting distribution $H^*(z)$, then it can be shown that $H(z)=H^*(z)^\theta$. Since $\eta=\eta^*-\tau^*\frac{1-\theta^\xi}{\xi}\leq\eta^*$, the maxima of the independent variables have bigger extremes than the maxima of the dependent processes.
\par
Figure \ref{fig:extremal_index} shows the extremal indexes for every month. Since they are smaller than one, some clustering does occur. This would affect the analysis of $r$-largest order statistics as well as peak-over-threshold analysis. However, models using monthly maxima aren't affected since they rely on only one value per month, making clustering irrelevant. Moreover, we see that the clusters are bigger in summer, with average cluster sizes of 4, in winter the average cluster sizes are more in the region of 2. This indicates that the necessary conditions for extreme thunderstorms are given for a longer time during summer, possibly also leading to longer-during thunderstorms than in winter.

\begin{figure}
	\centering
	\includegraphics[width=0.35\textwidth]{../plots/extermal_index.pdf}
	\caption{Extremal index estimation using evd function exi}
	\label{fig:extremal_index}
\end{figure}

\section*{Approach to Analysing Annual Maxima for all Months Together}
In our analysis, we have clearly seen that there is seasonality in the data. If we would have to fit a distribution to a dataset without splitting the months, the best approach in our opinion would be to account for this seasonality by including a seasonal parameter (sinusoidal) in $\eta$, such that the location parameter would be estimated by $\eta = \eta_0 + \eta_1*x$, where $x$ is a seasonality trend. For example we could take $x=cos(\frac{2\pi m}{12}-\alpha)$, where $m$ is the month index and $\alpha$ is an appropriate shift. The problem would be that while we do incorporate seasonality in the location parameter, we don't in the scale and shape parameter. The obvious strength of this approach would be that we could make inference about the annual maxima and their return levels. Also, we would have 12 times as many data points, which would be a substantial improvement from the only 37 samples we have now (for monthly maxima).
\par
We believe that it would be possible however, to estimate annual maxima and their return levels from our analysis above. For this, we would propose sampling extremes for each month, and then estimate return levels for the annual maxima. This approach is similar to what we incorporate for the return level calculation with the bivariate fit.

\section*{Dependence of CAPE and SRH}
Asymptotic dependence (or independence) of bivariate maxima of two random variables can be estimated using $\chi$ and $\bar{\chi}$ plots as provided by the \texttt{chiplot} function of the \texttt{evd} package \cite{evd}. The $\chi$ plot estimates for two random variables, $X \sim F_X$ and $Y \sim F_Y$, the probability
\begin{align*}
	P\{F_X (X) > u | F_Y (Y) > u\}
\end{align*}
for a given probability threshold $u$. The asymptotic behavior is observed as the upper support point of the distributions are attained, as $u \to 1$. If the maxima are independent, the quantity $\lim_{u \to 1} \chi(u) = 0$. Whereas $\chi(u)$ can measure the strength of the dependence, the rate at which $\chi(u) \to 0$ as $u \to 1$ is measured by the $\bar{\chi}$ plot. Generally we can say that for asymptotic independence $\lim_{u \to 1} \bar{\chi}(u) \to 0$, and for asymptotic dependence $\lim_{u \to 1} \bar{\chi}(u) \to 1$.
%The value of interest is $\chi = \lim_{u \to 1} \chi(u)$. For independence, $\chi \to 0$, since as $u \to 1$, $P\{F_X(x)>u | F_Y(y)>u\} \to \chi$. $\chi$ can distinguish the strength of dependence, but not the rate at which $\chi(u) \to 0$ as $u \to 1$. For this we can use the $\bar{\chi}$ plot. Generally we can say that for asymptotic independence $\lim_{u \to 1} \bar{\chi}(u) \to 0$, and for asymptotic dependence $\lim_{u \to 1} \bar{\chi}(u) \to 1$. (Source Slides 239-242 of the lecture notes)
\par
Our chi plots for all months look very similar. They suggest asymptotic independence between $CAPE$ and $SRH$ since $\lim_{u \to 1} \chi(u) \to 0$ and $\lim_{u \to 1} \bar{\chi}(u) \to 0$. Figure \ref{fig:cape_srh_chi} shows two representative examples of $\chi$ and $\bar{\chi}$ plots, for May and November.

\begin{figure}
	\centering
	\textbf{May}\\
	\includegraphics[width=0.35\textwidth]{../plots/May_chi.pdf}\\
	\textbf{November}\\
	\includegraphics[width=0.35\textwidth]{../plots/November_chi.pdf}
	\caption{Representative examples for chi plots for $CAPE$ and $SRH$, both suggesting asymptotic independence since they approach 0 as the quantile $u \to 1$.}
	\label{fig:cape_srh_chi}
\end{figure}

\section*{Bivariate Fitting of CAPE and SRH}
Whereas until now only the single structure variable $PROD$ was considered, in this section its two components $CAPE$ and $SRH$ are taken separately. A bivarate extreme value distribution is  fitted to the data with the \texttt{fbvevd} function of the \texttt{evd} package \cite{evd}, using six different parametric link functions. The tested link functions were logistic (log), asymmetric logistic (alog), negative logistic (neglog), bilogistic (bilog), Coles-Tawn (ct) and negative bilogistic models (negbilog), and thus comprised symmetric and asymmetric models. The quality of the fit using different link functions were compared using the Akaike Information Criterion (AIC), as shown in Table \ref{table:cape_srh_AIC}.
\par
We observe that the negative logistic link function is the best or among the best fits for all months. This suggests that the introduction of asymmetry between $CAPE$ and $SRH$ doesn't improve the fit. In order to treat all months consistently, fits using this link function for all months were used for subsequent analysis.
\begin{table}[]
\begin{tabular}{lllllll}
Month     & log       & alog      & neglog    & bilog     & ct        & negbilog  \\
January   & 920.4  & 921.3  & 920.1  & 920.3  & 921.0  & 920.3  \\
February  & 993.3  & 997.1  & 993.5  & 995.3  & 996.2  & 994.8  \\
March     & 1070.1 & 1074.2 & 1069.5 & 1072.2 & 1074.1 & 1071.6 \\
April     & 1064.8 & 1068.7 & 1064.6 & 1066.1 & 1066.2 & 1066.3 \\
May       & 1066.5 & 1070.4 & 1066.5 & 1068.3 & 1071.0 & 1068.2 \\
June      & 1043.3 & 1047.0 & 1043.4 & 1040.7 & 1043.1 & 1045.5 \\
July      & 1047.0 & 1044.9 & 1046.7 & 1046.2 & 1048.4 & 1046.5 \\
August    & 1029.2 & 1033.0 & 1029.4 & 1031.1 & 1031.3 & 1031.2 \\
September & 1056.0 & 1059.6 & 1055.7 & 1058.1 & 1059.9 & 1057.3 \\
October   & 1038.0 & 1042.0 & 1037.6 & 1037.6 & 1039.3 & 1038.5 \\
November  & 1012.4 & 1016.4 & 1012.7 & 1014.5 & 1015.1 & 1014.1 \\
December  & 892.7  & 896.7  & 892.5  & 894.9  & 895.5  & 894.3
\end{tabular}
\caption{AIC comparison of different link function models}
\label{table:cape_srh_AIC}
\end{table}
Note that for this fit, we extracted for each month the maximal $SRH$ value and the maximal $CAPE$ value and fitted the distribution to this data pair. However, the monthly maximum of these two independent variables don't necessarily correspond to the same event. We have therefore to be careful when drawing conclusions, since the "observations" we fit the models to often don't actually exist.
\par
Before, we estimated the dependence between $CAPE$ and $SRH$. We can also these results with the fits we just made. For this we will use the dependence parameter $r$ from the negative logistic model. This positive parameter tends to infinity for dependence, and to zero for independence. In Figure \ref{fig:cape_srh_dependance_logistic} we plot the dependence parameters for every month with crude estimates of 95\% confidence bands using the standard error of the parameter. Since all of the dependence parameters are close to zero, independence cannot be ruled out.

\begin{figure}
	\centering
	\includegraphics[width=0.35\textwidth]{../plots/monthly_dependence.pdf}
	\caption{Monthly dependence parameter $r$ with 95\% confidence intervals, compared to independence ($r=0$)}
	\label{fig:cape_srh_dependance_logistic}
\end{figure}

\section*{Calculation of Return Levels}
The return levels of extreme events is a quantity of interest for risk assessment. Here, we estimate the return levels using the different estimated fits obtained above. Notably, we compare 50- and 100 year return levels of $PROD$ using the location $\hat{\nu}$, scale $\hat{\tau}$ and shape $\hat{\xi}$ estimates obtained above for every month using Bayesian fitting (BAY) and maximum likelihood estimation (MLE). The estimated location $\hat{\nu}$, scale $\hat{\tau}$ and shape $\hat{\xi}$ parameters are converted into return levels $L$ for the return period $p$ using the formula
\begin{align*}
	L = \hat{\nu} + \hat{\tau}  \frac{\{-\log(1-p)\}^{-\hat{\xi}}}{\hat{\xi}}.
\end{align*}
\par
We also obtain the return levels using a Poisson process approach (POI). To this effect, we use the \texttt{fpot} function of the \texttt{evd} package and a threshold set to the 95\% quantile of the monthly observed data to fit a poisson process using maximum likelihood estimation. The estimated parameters are converted to return levels as described above. Whereas the fit failed in February, it performed well in all other months as assessed by the built-in diagnostic plots (not shown). % TODO: WAS MACHT r=1
\par
Additionally, we compute return levels based on the bivariate fit as follows (BIV): Using the function \texttt{rbvevd} from the \texttt{evd} package, we simulate 500'000 observations of $SRH$ and $CAPE$ using the fitted distribution obtained above with the negative logarithmic link function. We then calculate the resulting $PROD$ value of the simulated observation pairs. From this, we obtain the $n$-year return level as the $1-1/n$ quantile.
\par
The results in Figure \ref{fig:return_lvl} that the values obtained using the Poisson process approach generally correspond well with the Bayesian and MLE results. All show a seasonal trend for both the 50-year and 100-year return levels, with values in spring and the lowest during late fall and winter. The Bayesian results seem to be more smooth throughout the year, which is probably more realistic than high fluctuations between months. The fact that the Bayesian and MLE estimated return levels correspond so well is a surprise considering that the estimated parameters are very different, as seen above.
\par
Return levels estimated with the bivariate fit are generally higher than the others. This is likely due to the problematic discussed above, that simultaneous monthly maxima of $CAPE$ and $SRH$ are simulated. Since the maxima of these two values don't necessarily occur simultaneously, as illustrated by their asymptotic independence, we simulate values of $PROD$ that overestimate the actual values. Hence, the return levels obtained this way likely overestimate the ground truth. Similar seasonality is observed as in the case of the other results.
\par
%While the different models yield consistent seasonality results in general, a discrepancy is observed in January and February for the 100 year levels which are estimated as being the highest by BIV. In contrast, the values in January are among the lowest for both the BAY and POI, whereas February is also low for BAY while it is the highest for POI. Since the Bayesian model has been determined as stable above, its corresponding return values can most likely be best trusted. The Poisson model fit failed in February as indicated above, which explains its discrepancy with respect to the Bayesian model. An explanation for the exceptionally high BIV return values in these two months would be if both high $SRH$ and $CAPE$ values could be observed, but never simultaneously. Grouping the extreme values into a single observation would lead to a particularly high overestimate of the return level, which may be what we observe here.

\begin{figure}
	\centering
	\includegraphics[width=0.35\textwidth]{../plots/50yr_return.pdf}
	\includegraphics[width=0.35\textwidth]{../plots/100yr_return.pdf}
	\caption{50- and 100 year return levels of PROD, as assessed with Bayesian estimation (BAY) of GEV parameters, poisson-process fitting (POI) to peak-over-threshold values, and simulating from a bivariate GEV distribution fitted to SRH and CAPE.}
	\label{fig:return_lvl}
\end{figure}

\section*{Impact by Using Variable Transformations}
We argue (without testing this explicitly), that using a $log(\cdot)$ transformation on $CAPE$, $SRH$ and $PROD$ would not change our analysis much. If $CAPE$ and $SRH$ arise from a joint distribution $F$, then $log(CAPE)$ and $log(SRH)$ arise from a distribution $F'$. The \textit{Extremal Types Theorem} (Seen on slide 31 of the course) shows that if a limiting extremal distribution exists, it must be the GEV. Since the $log(\cdot)$ operation maps values $x>1$ to $log(x)<x$, the upper tails will be lighter and the distribution will exist. The dependence analysis would yield different results: Since if the shape parameter has linear dependence in log space, it has exponential dependence in linear space. To do the same analysis, we would have to use a transformed trend $x_{new}= log(x)$.

\section*{Conclusion}
We have analysed the thunderstorm risk using several methods from the toolbox of extremal analysis. The key insights are that, in accordance with common knowledge, the thunderstorm risk is greater in summer than in winter. Also, we cannot conclude that the shape parameter $\xi$ is negative, suggesting that there is no upper limit in the strength of thunderstorms for the region analysed in this report.
\par
We have also compared different fitting methods, and seen their strengths and weaknesses. We saw that if we are aware of the weakness of the method we apply, we can better understand the fit, as the possible errors can easily be spotted.
\par
A clear deficit of the analysis performed in this report is the lack of data: When treating every month differently and taking monthly maxima, we relied on only 37 data points for model fitting. One way to better model the thunderstorm behavior would be using spatial extremes, by taking into account data measured at other locations. This would yield more data, but could also reveal interesting behavior of extreme thunderstorm formation, possibly giving valuable physical insight.

%%% Bibliography
\bibliographystyle{IEEEtran}
\bibliography{literature-project}

% TODO:
% Explain why discrepancy
% Schribe das r-largest eue schlecht isch
% Parameter vergliiche vode verschidnige fitting methode
% Poisson process approach
% Bibliographie!!!

\end{document}


\section{Towards a Reproducible Thesis}\label{sec:reproducibility}

% \subsection{Motivations}\label{sec:motivations}
In some respects, the practice of writing software has diverged from the motivations of an academic researcher.
The latter seeks to generate new knowledge and may write a set of example scripts/programs to demonstrate some novel idea or method.
By contrast, the motivations of a software engineer are related to resiliency.
Not only must they ensure the code works as expected given a myriad of ways users may interact with it, but it is necessary to write the code in a manner compatible with maintaining it into the future.
Much of the work of writing ``good software'' is concerned with writing appropriate documentation to express the intended usage and logic underlying architectural decisions.
Without proper context and an understandable architecture, new ideas that are implemented in programs are unlikely to be adopted.
There are many ways to write a functioning program to demonstrate a proof-of-concept, but creating something that is \emph{user-friendly}, and scales to different computational environments/resources, requires an entirely different approach.

Decisions made early in the software design cycle have lasting impacts on future features and functionality.
Rigor is added to libraries through the writing of \emph{unit tests}, and eventually \emph{functional tests}, which validate individual components and entire workflows, respectively.
The practice of \emph{continuous integration} ensures that the download and installation process is predictable and reproducible by running the requisite steps (and tests) in an ephemeral environment as an independent verification that programs execute as expected.
Code that only runs on the one's computer is impractical, since any thorough review of the results requires validation by an independent third party.
Having continuous integration (and deployment for packaging the software), tests, and documentation, allows a repository of code to be functionally and practically accessible to the larger research community.

This thesis is concerned not only with a demonstration of novel mathematical content\---showcasing new ways to make inferences from noisy data in a novel Data-Consistent framework\---it also serves to set a precedent for guaranteeing that the results presented are \textbf{fully reproducible}.
In mathematics, reproducibility is ensured through the use of proofs, which motivate the original work presented here.
However, as the title of this thesis suggests, much of the work involves computational implementation of the novel research into Data Consistent Inversion, studying the impact of using computers to perform the task of making conclusions based on data.
Mathematics is implemented on computers through software.
We are therefore concerned with verifying and validating the expected functionality of that software, which aligns with our training as mathematicians; we care deeply about making sure things are rigorous.

In short, we want to make sure that theory aligns with practice, and that both live up to high standards of intellectual scrutiny.
Every computational result, illustrative figure, table, plot, etc. presented in this thesis is associated with the scripts that generate them, and are included in the publicly-available GitHub repository.
With a minimal set of instructions, everything (including this document itself), can be reproduced.
The specific tools and frameworks through which the reproduction of these results can be accomplished change over time.
The GitHub repository \citep{github} for this dissertation provides a number of pathways for generating the results, including ones that do not require any installation of software on local or remote resources.

\FloatBarrier


\section{Part 5.a Nearest Grid Point Method}

The file of the functions used for this exercise is:

\lstinputlisting{part_five.py}

While I ran out of time to finish this part, here is the methodology I was attempting to make.
I did generate the grid, as well as the random points, and started on the Nearest Grid Point method. The idea was to
go to thebox of 8 points surrounding the mass that is being added, calculate the distance to each of the grid points, and
add all the mass to the closest of the 8 points. While not the most efficient, it would have resulted in the mass being
distributed properly.

\section{Part 5.c Cloud In Cell Method}

For the Cloud In Cell Method, while again, I ran out of time to implement it, to do so I would have done as follows.
I would have gotten the closest 8 points making up the box around the mass, in the same way as for the Nearest Grid Point method.
Once having those points, the next step is calculating how much of the particle is the closest to each grid point, and assigning that
portion of the particle's mass to the grid point it is closest to.


\section{Fundamentals}

\subsection{Document Structure}
\input{sections/fundamentals/Document_structure}

\subsection{Basic Formatting}

\subsection{Whitespace and Pages}
\input{sections/fundamentals/Whitespace}

\subsection{Headers, Footers and Page-numbers}

\subsection{The Titlepage}

\subsection{Contents, Bibliography and Appendices}

\subsection{Math Mode}

One of \LaTeX{}'s most powerful and recognizable features is its math mode. It's purpose is fairly simple typesetting of equations and formulae that still look professional There are two slightly different types of math mode. First one is inline, which will display equation as a part of the text and looks like this: $x_{1,2} = \frac{-b\pm \sqrt{b^2-4ac}}{2a}$, while the second one is display mode and will show the formula much bigger and isolated, looking like this: $$x_{1,2} = \frac{-b\pm \sqrt{b^2-4ac}}{2a}$$ % FIX

\subsubsection{Math Environments}


\documentclass[main.tex]{subfiles}
\begin{document}

\section{The Dirac Equation}

\marginpar{Saturday\\ 2020-3-28, \\ compiled \\ \today}

The Klein Gordon equation, which we discussed in the previous lectures, has two main issues:
\begin{enumerate}
  \item It is a second order equation, since we started from the relativistic dispersion relation \(E^2 = M^2 + \abs{\vec{p}}^2\), so it admits a negative as well as a positive energy solution: \(E = \pm \omega_{p}\).
  \item The charge associated with its 4-current density \(J^{\mu }\) is not positive definite:
  %
  \begin{align}
  Q = \int \dd[3]{x} J^{0}(\vec{x}, t)
  \,
  \end{align}
  %
  can be negative.
\end{enumerate}

In order to clarify the problem with these, we discussed the Klein Paradox, in which there is a violation of unitarity for a scattering process: the reflection probability was \(>1\) while the transmission probability was negative.

Dirac, in 1928, tried a different approach.

\subsection{Historical derivation of the Dirac equation}

We want to build an equation in the form
%
\begin{align}
i \pdv{}{t} \psi  = H_D \psi
\,,
\end{align}
%
for some Dirac Hamiltonian \(H_D\), which we require to be first-order in the space derivatives and the mass, so that our equation can be covariant: this in general will be written as
%
\begin{align}
H_D = -i \vec{\alpha} \cdot \vec{\nabla} + \beta M = \vec{\alpha} \cdot \qty(-i \vec{\nabla}) + \beta M
\,,
\end{align}
%
for some yet to be determined 4 coefficients \(\vec{\alpha}\) and \(\beta \).

Why are we introducing the \(i\)? This formulation is equivalent to saying that the energy \(E\) is given by \(\vec{\alpha} \cdot \vec{p} + \beta M\), since \(\vec{p} = - i \vec{\nabla}\).

We are assuming the coefficients to be constant, we shall see that this hypothesis works out. Also, as we shall these cannot be numbers, but instead they are matrices: for now, all this means is that we need to be careful when manipulating them, since in general they will not commute.

In order to determine \(\vec{\alpha }\) and \(\beta \) we impose the conditions:
\begin{enumerate}
  \item the Dirac Hamiltonian \(H_D\) is hermitian, since it needs to describe the physical property of energy, therefore it is an observable;
  \item if \(\psi \) solves the Dirac equation, then it also solves the KG equation.
\end{enumerate}

Actually, KG solutions also Dirac solutions in general.

The first condition can be written as \(H = H ^\dag\), but to find out what it means for the coefficients \(\vec{\alpha }\) and \(\beta \) we need to know what \(\vec{\nabla} ^\dag\): since we know that momentum \(\vec{p} = -i \vec{\nabla}\) is self adjoint, we must have \(\vec{p} ^\dag = (-i) ^\dag \vec{\nabla} ^\dag = i \vec{\nabla} ^\dag \overset{!}{=} -i \vec{\nabla} = \vec{p} \),
which means that \(\vec{\nabla} ^\dag = - \vec{\nabla}\).
So, we get
%
\begin{subequations}
\begin{align}
H ^\dag &= (-i) ^\dag \vec{\alpha} ^\dag \cdot \vec{\nabla} ^\dag + \beta ^\dag M ^\dag  \\
&= -i \alpha^{*} \cdot \vec{\nabla} + \beta^{*} M
\,,
\end{align}
\end{subequations}
%
since \(M\) is real.\footnote{In the professor's notes this is done explicitly by integrating by parts: this method can be adapted to look like that, since one can use integration by parts to show that for any wavefunctions \(\phi \) and \(\psi \) we have \(\braket{\phi }{\nabla \psi } + \braket{\nabla \phi}{\psi } = 0\). Then, the only difference between the approaches is whether we only integrate by parts to get the adjoint of \(\nabla\) or the whole of \(H_D\). }
Therefore, the coefficients must satisfy \(\vec{a}^{*} = \vec{\alpha}\) and \(\beta^{*} = \beta \) themselves.

The other condition, consistency with the KG equation, means that when we square the Dirac time derivative operator
%
\begin{align}
\pdv{}{t} = -i H_D
\,
\end{align}
%
we should get the KG square time- derivative operator
%
\begin{align}
\pdv[2]{}{t} = \nabla^2 + M^2
\,.
\end{align}

So, we find
%
\begin{subequations}
\begin{align}
\nabla^2 + M^2 &\overset{!}{=} (-i H_D)^2 = - H_D^2  \\
&= -\qty(-i \alpha_{i}  \nabla_{i} + \beta M) \qty(-i \alpha_{j} \nabla_{j} + \beta M)  \\
&= \alpha_{i} \alpha_{j} \nabla_{i} \nabla_{j} + i \qty(\alpha_{i} \beta  + M \beta \alpha_{i}) \nabla_{i} + \beta^2 M^2 \\
&= \frac{1}{2} \qty{\alpha_{i}, \alpha_{j}} \nabla_{i} \nabla_{j}
+ iM \qty{\alpha_{i}, \beta } \nabla_{i} + \beta^2M^2
\,,
\end{align}
\end{subequations}
%

where we introduced the anticommutator bracket notation:
%
\begin{align}
\qty{A, B} = AB + BA
\qquad \text{while} \qquad
\qty[A, B] = AB - BA
\,.
\end{align}

So, in order for the equations to be equivalent we need to impose
%
\begin{align}
\frac{1}{2}\qty{\alpha_{i}, \alpha_{j}} = \delta_{ij}
\qquad \qquad
\qty{\alpha_{i}, \beta } = 0
\qquad \qquad
\beta^2 = 1
\,.
\end{align}

This means \(\alpha_{i}\) and \(\beta \) cannot be real or complex numbers: for complex numbers \(x, y\) we have \(\qty{x, y} = 2 xy \),  since for them multiplication is commutative.

Specifically, they must be matrices in an \(N\)-dimensional vector space, called a spinorial space.
So, \(\alpha_{i}\) and \(\beta \) are \(N \times N\) matrices, while the wavefunction \(\psi \) is an \(N\) dimensional vector (spinor). \(N\) is yet to be determined.

They must be Hermitian matrices, since they satisfy \(\alpha_{i} ^\dag = \alpha_{i}\) and \(\beta ^\dag = \beta \).

We must have \(\alpha_{i}^2 = \frac{1}{2} \qty{\alpha_{i}, \alpha_{i}} = \mathbb{1}\), where \(\mathbb{1}\) is the \(N\) dimensional identity matrix. Also, \(\beta^2 = \mathbb{1}\).
If we write \(\alpha_{i}\) and \(\beta \) in diagonal form, which we can do since they are Hermitian, we get their real eigenvalues on the diagonal. If we square them we get the identity, therefore they must all be \(\pm 1\).

Now, let us show that these are traceless: call \(c_{\mu }\) one of the four \(\qty(\beta ,\alpha_{i})\). Then, we know that \(\qty{c_{\mu }, c_{\nu }} = 2 \delta_{\mu \nu }\).
So, we do the following manipulation: take \(c_{\mu }\) and \(c_{\nu }\), with \(\nu \neq \mu \):
%
\begin{subequations}
\begin{align}
\Tr(c_{\mu }) &= \Tr(c_{\mu } c_{\nu } c_{\nu })  \marginnote{\(c_{\nu }^2 = \mathbb{1}\)}\\
&= \Tr(-c_{\nu } c_{\mu } c_{\nu }) \marginnote{\(\qty{c_{\mu }, c_{\nu }} = 0\), so \(c_{\mu } c_{\nu } = - c_{\nu } c_{\mu }\)}  \\
&= \Tr(-c_{\mu } c_{\nu } c_{\nu })  \marginnote{Cyclic property of the trace, and linearity of the trace}[.7cm]\\
&= - \Tr(c_{\mu })
\,,
\end{align}
\end{subequations}
%
so \(\Tr(c_{\mu }) = - \Tr(c_{\mu }) \implies \Tr(c_{\mu }) = 0\).
Since the trace is the sum of the eigenvalues, which are \(\pm 1\), the dimension must be even.

So, our simplest guess will be \(N=2\): a basis for Hermitian complex matrices is \(\qty{\mathbb{1}, \sigma_{i}}\) where \(\sigma_{i}\) are the Pauli matrices.
However, \(\mathbb{1}\) is not traceless: so our \(c_{\mu }\) can only be written as \(c_{\mu } = \vec{c} \cdot \vec{\sigma}\).

Now, our \(c_{\mu }\) must be linearly independent over \(\mathbb{C}\): if they were not, say because \(c_{\mu } = z c_{\nu }\), with \(\mu \neq \nu \) and \(z \in \mathbb{C}\), then the anticommutation would read
%
\begin{align}
\qty{c_{\mu }, c_{\nu }} = \qty{z c_{\nu }, c_{\nu }} = z \mathbb{1}  \neq 0
\,,
\end{align}
%
a contradiction.
We only have three linearly independent Pauli matrices \(\sigma_{i}\) to express four \(c_{\mu }\), so this cannot work.

Do however note that if \(M=0\) then we do not need the \(\beta \) matrix since the term multiplying it goes to zero, so the only matrices we need are the three \(\alpha_{i}\): in the massless case, then, we can use the Pauli matrices, setting \(\sigma_{i} = \alpha_{i}\) satisfies all our requirements, since \(\qty{\sigma_{i}, \sigma_{j}} = 2 \delta_{ij}\).

The next possible dimensionality is \(N=4\), and we can use the following matrices:
%
\begin{subequations}
\begin{align}
\alpha_{i} = \left[\begin{array}{cc}
0 & \sigma_{i} \\
\sigma_{i} & 0
\end{array}\right]
\qquad \text{and} \qquad
\beta = \left[\begin{array}{cc}
\mathbb{1} & 0 \\
0 & -\mathbb{1}
\end{array}\right]
\,.
\end{align}
\end{subequations}

These are self adjoint since the Pauli matrices are, manifestly traceless, and they satisfy the anticommutation relations.

\begin{proof}
We expand the relation \(\qty{\alpha_{i}, \alpha_{j}}\): if we write \(\alpha_{i} \alpha_{j}\) we get
%
\begin{subequations}
\begin{align}
\alpha_{i} \alpha_{j} =
\left[\begin{array}{cc}
0 & \sigma_{i} \\
\sigma_{i} & 0
\end{array}\right]
\left[\begin{array}{cc}
0 & \sigma_{j} \\
\sigma_{j} & 0
\end{array}\right]
= \left[\begin{array}{cc}
\sigma_{i} \sigma_{j} & 0 \\
0 & \sigma_{i} \sigma_{j}
\end{array}\right]
\,,
\end{align}
\end{subequations}
%
therefore
%
\begin{subequations}
\begin{align}
\qty{\alpha_{i}, \alpha_{j}} = \left[\begin{array}{cc}
\qty{\sigma_{i}, \sigma_{j}} & 0 \\
0 & \qty{\sigma_{i}, \sigma_{j}}
\end{array}\right]
= \qty{\sigma_{i}, \sigma_{j}} \mathbb{1}_{4}
\,,
\end{align}
\end{subequations}
%
but we know that \(\qty{\sigma_{i}, \sigma_{j}} = 2 \delta_{ij}\), so we have verified the anticommutation relations between the \(\alpha_{i}\).

To see that \(\beta^2 = \mathbb{1}_{4}\) is immediate since it is already diagonal, so we only need to show \(\qty{\alpha_{i}, \beta } = 0\). We have
%
\begin{subequations}
\begin{align}
\alpha_{i} \beta =
\left[\begin{array}{cc}
0 & \sigma_{i} \\
\sigma_{i} & 0
\end{array}\right]
\left[\begin{array}{cc}
\mathbb{1} & 0 \\
0 & -\mathbb{1}
\end{array}\right]
&=
\left[\begin{array}{cc}
0 & -\sigma_{i} \\
\sigma_{i} & 0
\end{array}\right] \\
\beta \alpha_{i} =
\left[\begin{array}{cc}
\mathbb{1} & 0 \\
0 & -\mathbb{1}
\end{array}\right]
\left[\begin{array}{cc}
0 & \sigma_{i} \\
\sigma_{i} & 0
\end{array}\right]
&=
\left[\begin{array}{cc}
0 & \sigma_{i} \\
-\sigma_{i} & 0
\end{array}\right]
\,,
\end{align}
\end{subequations}
%
so the sum \(\alpha_{i} \beta + \beta \alpha_{i}\) is zero, which proves our statement.
\end{proof}

\subsubsection{The \(\gamma \) matrices}

It is then conventional to define the matrices
%
\begin{subequations}
\begin{align}
\gamma^{0} = \beta = \left[\begin{array}{cc}
\mathbb{1} & 0 \\
0 & -\mathbb{1}
\end{array}\right]
\qquad \text{and} \qquad
\gamma^{i} = \beta \alpha_{i} = \left[\begin{array}{cc}
0 & \sigma_{i} \\
-\sigma_{i} & 0
\end{array}\right]
\,,
\end{align}
\end{subequations}
%
which obey the following properties:
\begin{enumerate}
  \item \(\gamma^{0} = (\gamma^{0}) ^\dag\), while \(\gamma^{i} = - (\gamma^{i} ) ^\dag\);
  \item \(\qty{\gamma^{\mu }, \gamma^{\nu }} = 2 \eta^{\mu \nu }\), specifically \((\gamma^{0})^2 = \mathbb{1}_{4}\) and \((\gamma^{i})^2 = - \mathbb{1}_{4}\).
\end{enumerate}

We can then interpret this collection of matrices as a 4-vector.
We can rewrite the Dirac equation using them: we multiply it by \(\beta \) to get
%
\begin{subequations} \label{eq:dirac-equation-from-ansatz-to-gamma}
\begin{align}
i \partial_0 \psi &= \qty(-i \alpha_{i} \partial_{i}+ \beta M ) \psi  \\
i \beta \partial_0 \psi &= \qty(-i \beta \alpha_{i} \partial_{i} + \beta^2 M) \psi  \\
i \gamma^{0} \partial_0 \psi &= \qty(- \gamma^{i}\partial_{i} + \beta^2 M) \psi  \\
\qty(i \gamma^{\mu } \partial_{\mu } - M ) \psi &= 0
\,.
\end{align}
\end{subequations}

This looks simple, but recall that \(\gamma^{\mu }\) are \(4 \times 4\) matrices and \(\psi \) is a 4D spinor: if we write this explicitly using the spinor indices, for which we use the Hebrew letters \(\aleph\) nd \(\beth\) (aleph and beth\footnote{Since this notation will only be used here, it does not matter if it is a little inconvenient. I did not use greek or latin letters since they both already have meaning in the conventional notation.}), we get
%
\begin{align}
\qty(i \gamma^{\mu }_{\aleph \beth} - M \delta_{\aleph \beth}) \psi_{\beth} = 0
\,,
\end{align}
%
which is a set of 4 equations, indexed by the free index \(\aleph\).
Since the \(\gamma \) matrices are not diagonal, the components \(\psi_{\beth}\) are mixed in the equation.

If we introduce the slashed notation \(\slashed{p} \overset{\text{def}}{=} \gamma^{\mu }p_{\mu }\).

With this notation, the Dirac equation reads
%
\boxalign{
\begin{align}
\qty(i \slashed{\partial} -M) \psi = 0
\,.
\end{align}}

\subsubsection{Representations of \(\gamma \)-matrices}

The way we defined the \(\gamma \) matrices was arbitrary, and in fact there are other possible equivalent definitions which are also physically useful.

In general, for any unitary matrix \(C\) we can move to the new representation
%
\begin{align}
\widetilde{\gamma}^{\mu } =C^{-1} \gamma^{\mu } C
\,.
\end{align}

How do we prove that the physical results are the same?
The Dirac equation is in the form \(A \psi =0\), and if we show that for an equation in this form \(C^{-1} A C\) is as good as \(A\) then we are done: in \(A = i \slashed{\partial} - M \mathbb{1}\) the \(M \mathbb{1}\) term is unaffected since it commutes with the matrix, the derivative is unaffected since the \(C\) matrix is assumed to be constant.
But then, if we want to use \( \widetilde{A} = C^{-1}A C\), we will find solutions to \(C^{-1} A C C^{-1} \psi = \widetilde{A} \widetilde{\psi}\), where \(\widetilde{\psi} = C^{-1} \psi \): we will see later that the physical observables corresponding to spinors are related to their contractions, and indeed if we take the square modulus after applying a unitary transformation it is unchanged.

The Dirac representation we gave before is usually used when dealing with the nonrelativistic limit, while the one we now show is called the relativistic, or Weyl, or chiral, representation.
We use the matrix which is known in quantum information as the Hadamard gate:
%
\begin{subequations}
\begin{align}
C = \frac{1}{\sqrt{2}} \left[\begin{array}{cc}
1 & 1 \\
-1 & 1
\end{array}\right]
\,
\end{align}
\end{subequations}
%
we can move to the representation
%
\begin{subequations}
\begin{align}
\gamma^{\mu } = \qty(\left[\begin{array}{cc}
0 & \mathbb{1} \\
\mathbb{1} & 0
\end{array}\right], \left[\begin{array}{cc}
0 & \sigma_{i} \\
- \sigma_{i} & 0
\end{array}\right])
\,.
\end{align}
\end{subequations}
%
\begin{proof}
We multiply, writing \(1\) for \(\mathbb{1}\) and \(0\) for the 0 matrix for simplicity: for \(\gamma^{0}\) we get
%
\begin{subequations}
\begin{align}
C^{-1} \gamma^{0} C &= \frac{1}{2} \left[\begin{array}{cc}
1 & -1 \\
1 & 1
\end{array}\right]
\left[\begin{array}{cc}
1 & 0 \\
0 & -1
\end{array}\right]
\left[\begin{array}{cc}
1 & 1 \\
-1 & 1
\end{array}\right]  \\
&= \frac{1}{2} \left[\begin{array}{cc}
1 & -1 \\
1 & 1
\end{array}\right]
\left[\begin{array}{cc}
1 & 1 \\
1 & -1
\end{array}\right]  \\
&= \frac{1}{2} \left[\begin{array}{cc}
0 & 2 \\
2 & 0
\end{array}\right] = \left[\begin{array}{cc}
0 & 1 \\
1 & 0
\end{array}\right]
\,,
\end{align}
\end{subequations}
%
while for \(\gamma^{i}\) we have
%
\begin{subequations}
\begin{align}
C^{-1} \gamma^{i} C &= \frac{1}{2} \left[\begin{array}{cc}
1 & 1 \\
-1 & 1
\end{array}\right]
\left[\begin{array}{cc}
0 & \sigma_{i} \\
- \sigma_{i} & 0
\end{array}\right]
\left[\begin{array}{cc}
1 & -1 \\
1 & 1
\end{array}\right]  \\
&= \frac{1}{2}
\left[\begin{array}{cc}
1 & 1 \\
-1 & 1
\end{array}\right]
\left[\begin{array}{cc}
\sigma_i  & \sigma_i  \\
- \sigma_i  & \sigma_i
\end{array}\right]  \\
&= \left[\begin{array}{cc}
0 & \sigma_i  \\
-\sigma_i  & 0
\end{array}\right]
\,.
\end{align}
\end{subequations}
\end{proof}

The Dirac equation is consistent with the Klein Gordon equation: we can multiply it by the conjugate of the Dirac operator, \(-(i \slashed{\partial}+M)\), to get
%
\begin{subequations}
\begin{align}
- \qty(i \slashed{\partial}+M) \qty(i \slashed{\partial}-M) \psi  &= 0\\
\qty( \gamma^{\mu } \gamma^{\nu } \partial_{\mu } \partial_{\nu } + M^2  ) &= 0   \\
\qty(\square + M^2) \psi &=0
\,,
\end{align}
\end{subequations}
%
which is equivalent to the Klein-Gordon equation since when we compute \(\gamma^{ \mu }  \gamma^{\nu } \partial_{\mu } \partial_{\nu }\) we only have the symmetric part, since the partial derivatives commute, and \(\frac{1}{2} \qty{\gamma^{\mu }, \gamma^{\nu }} = \eta^{\mu \nu }\).

The Klein-Gordon equation is then diagonal in the spinorial space: by this manipulation we have shown that the KG operator is proportional to the identity.

\end{document}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright (c) 2003-2018 by The University of Queensland
% http://www.uq.edu.au
%
% Primary Business: Queensland, Australia
% Licensed under the Apache License, version 2.0
% http://www.apache.org/licenses/LICENSE-2.0
%
% Development until 2012 by Earth Systems Science Computational Center (ESSCC)
% Development 2012-2013 by School of Earth Sciences
% Development from 2014 by Centre for Geoscience Computing (GeoComp)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{The \pycad Module}\label{PYCAD CHAP}

\section{Introduction}

\pycad provides a simple way to build a mesh for your finite element
simulation. You begin by building what we call a \class{Design} using
primitive geometric objects, and then go on to build a mesh from this.
The final step of generating the mesh from a \class{Design} uses freely
available mesh generation software, such as \gmshextern.

A \class{Design} is built by defining points, which are used to specify
the corners of geometric objects and the vertices of curves. Using
points you construct more interesting objects such as lines,
rectangles, and arcs. By adding many of these objects into a \class{Design},
you can build meshes for arbitrarily complex 2-D and 3-D structures.

\section{The Unit Square}
The simplest geometry is the unit square. First we generate the corner points
\begin{python}
  from esys.pycad import *
  p0=Point(0.,0.,0.)
  p1=Point(1.,0.,0.)
  p2=Point(1.,1.,0.)
  p3=Point(0.,1.,0.)
\end{python}
which are then linked to define the edges of the square
\begin{python}
  l01=Line(p0,p1)
  l12=Line(p1,p2)
  l23=Line(p2,p3)
  l30=Line(p3,p0)
\end{python}
The lines are put together to form a loop
\begin{python}
  c=CurveLoop(l01,l12,l23,l30)
\end{python}
The orientation of the line defining the \class{CurveLoop} is important.
It is assumed that the surrounded area is to the left when moving along the
lines from their starting points towards the end points.
Moreover, the line needs to form a closed loop.
We now use the \class{CurveLoop} to define a surface
\begin{python}
  s=PlaneSurface(c)
\end{python}
Note that there is a difference between the \class{CurveLoop}, which defines
the boundary of the surface, and the actual surface \class{PlaneSurface}.
This difference becomes clearer in the next example with a hole.
Now we are ready to define the geometry which is described by an instance of
the \class{Design} class:
\begin{python}
  d=Design(dim=2,element_size=0.05)
\end{python}
Here we use the two-dimensional domain with a local element size in the finite
element mesh of $0.05$.
We then add the surface \code{s} to the geometry
\begin{python}
  d.addItems(s)
\end{python}
This will automatically import all items used to construct \code{s} into the
\class{Design} \code{d}.
Now we are ready to construct a \finley FEM mesh and then write it to the file
\file{quad.fly}:
\begin{python}
  from esys.finley import MakeDomain
  dom=MakeDomain(d)
  dom.write("quad.fly")
\end{python}
In some cases it is useful to access the script used to generate the geometry.
You can specify a specific name for the script file. In our case we use
\begin{python}
  d.setScriptFileName("quad.geo")
\end{python}
It is also useful to check error messages generated during the mesh generation
process. \gmshextern writes messages to the file \file{.gmsh-errors} in your
home directory.
Putting everything together we get the script
\begin{python}
  from esys.pycad import *
  from esys.pycad.gmsh import Design
  from esys.finley import MakeDomain
  p0=Point(0.,0.,0.)
  p1=Point(1.,0.,0.)
  p2=Point(1.,1.,0.)
  p3=Point(0.,1.,0.)
  l01=Line(p0,p1)
  l12=Line(p1,p2)
  l23=Line(p2,p3)
  l30=Line(p3,p0)
  c=CurveLoop(l01,l12,l23,l30)
  s=PlaneSurface(c)
  d=Design(dim=2,element_size=0.05)
  d.setScriptFileName("quad.geo")
  d.addItems(s)
  pl1=PropertySet("sides",l01,l23)
  pl2=PropertySet("top_and_bottom",l12,l30)
  d.addItems(pl1, pl2)
  dom=MakeDomain(d)
  dom.write("quad.fly")
\end{python}
This example is included with the software in \file{quad.py} in the
\ExampleDirectory.

There are three extra statements which we have not discussed yet.
By default the mesh used to subdivide the boundary is not written into the
mesh file mainly to reduce the size of the data file.
One needs to explicitly add the lines to the \Design which should be present
in the mesh data. Here we additionally labeled the lines on the top and the
bottom with the name ``top_and_bottom`` and the lines on the left and right
hand side with the name ``sides`` using \class{PropertySet} objects.
The labeling is convenient when using tagging\index{tagging}, see \Chap{ESCRIPT CHAP}.

\begin{figure}
\centerline{\includegraphics{quad}}
\caption{Quadrilateral with mesh of triangles}
\label{fig:PYCAD 0}
\end{figure}

If you have \gmshextern installed you can run the example and view the
geometry and mesh with:
\begin{verbatim}
run-escript quad.py
gmsh quad.geo
gmsh quad.msh
\end{verbatim}
See Figure~\ref{fig:PYCAD 0} for a result.

In most cases it is best practice to generate the mesh and solve the
mathematical model in two separate scripts. In our example you can read the
\finley mesh into your simulation code\footnote{\gmshextern files can be
directly read using \function{ReadGmsh}, see \Chap{chap:finley}} using
\begin{python}
  from finley import ReadMesh
  mesh=ReadMesh("quad.fly")
\end{python}
Note that the underlying mesh generation software will not accept all
the geometries you can create.  For example, \pycad will happily allow
you to create a 2-D \class{Design} that is a closed loop with some
additional points or lines lying outside of the enclosed area, but
\gmshextern will fail to create a mesh for it.

\section{Holes}
The example included below shows how to use \pycad to create a 2-D mesh
in the shape of a trapezoid with a cut-out area as in Figure~\ref{fig:PYCAD 1}.

\begin{python}
  from esys.pycad import *
  from esys.pycad.gmsh import Design
  from esys.finley import MakeDomain

  # A trapezoid
  p0=Point(0.0, 0.0, 0.0)
  p1=Point(1.0, 0.0, 0.0)
  p2=Point(1.0, 0.5, 0.0)
  p3=Point(0.0, 1.0, 0.0)
  l01=Line(p0, p1)
  l12=Line(p1, p2)
  l23=Line(p2, p3)
  l30=Line(p3, p0)
  c=CurveLoop(l01, l12, l23, l30)

  # A small triangular cutout
  x0=Point(0.1, 0.1, 0.0)
  x1=Point(0.5, 0.1, 0.0)
  x2=Point(0.5, 0.2, 0.0)
  x01=Line(x0, x1)
  x12=Line(x1, x2)
  x20=Line(x2, x0)
  cutout=CurveLoop(x01, x12, x20)

  # Create the surface with cutout
  s=PlaneSurface(c, holes=[cutout])

  # Create a Design which can make the mesh
  d=Design(dim=2, element_size=0.05)

  # Add the trapezoid with cutout
  d.addItems(s)

  # Create the geometry, mesh and Escript domain
  d.setScriptFileName("trapezoid.geo")
  d.setMeshFileName("trapezoid.msh")
  domain=MakeDomain(d)
  # write mesh to a finley file:
  domain.write("trapezoid.fly")
\end{python}
This example is included with the software in \file{trapezoid.py} in the
\ExampleDirectory.

\begin{figure}
\centerline{\includegraphics{trapezoid}}
\caption{Trapezoid with triangular hole}
\label{fig:PYCAD 1}
\end{figure}

A \code{CurveLoop} is used to connect several lines into a single curve.
It is used in the example above to create the trapezoidal outline for the grid
and also for the triangular cutout area.
You can define any number of lines when creating a \class{CurveLoop}, but
the end of one line must be identical to the start of the next.

\section{A 3D example}

In this section we discuss the definition of 3D geometries. As an example
consider the unit cube as shown in Figure~\ref{fig:PYCAD 2}.
First we generate the vertices of the cube:
\begin{python}
  from esys.pycad import *
  p0=Point(0.,0.,0.)
  p1=Point(1.,0.,0.)
  p2=Point(0.,1.,0.)
  p3=Point(1.,1.,0.)
  p4=Point(0.,0.,1.)
  p5=Point(1.,0.,1.)
  p6=Point(0.,1.,1.)
  p7=Point(1.,1.,1.)
\end{python}

We connect the points to form the bottom and top surfaces of the cube:
\begin{python}
  l01=Line(p0,p1)
  l13=Line(p1,p3)
  l32=Line(p3,p2)
  l20=Line(p2,p0)
  bottom=PlaneSurface(-CurveLoop(l01,l13,l32,l20))
\end{python}

\begin{figure}
\centerline{\includegraphics{brick}}
\caption{Three dimensional block}
\label{fig:PYCAD 2}
\end{figure}

Similar to the definition of a \code{CurvedLoop} the orientation of the
surfaces in a \code{SurfaceLoop} is relevant.
In fact, the surface normal direction defined by the right-hand rule needs to
point outwards as indicated by the surface normals in Figure~\ref{fig:PYCAD 2}.
As the \code{bottom} face is directed upwards it is inserted with the minus
sign into the \code{SurfaceLoop} in order to adjust the orientation of the
surface. Similarly we set
\begin{python}
  l45=Line(p4,p5)
  l57=Line(p5,p7)
  l76=Line(p7,p6)
  l64=Line(p6,p4)
  top=PlaneSurface(CurveLoop(l45,l57,l76,l64))
\end{python}
To form the front face we introduce the two additional lines connecting the
left and right front points of the \code{top} and \code{bottom} face:
\begin{python}
  l15=Line(p1,p5)
  l40=Line(p4,p0)
\end{python}
To form the front face we encounter a problem, the line \code{l45} used
to define the \code{top} face is pointing the wrong direction.
In \pycad you can reverse the direction of an object by changing its sign.
So we write \code{-l45} to indicate that the direction is to be reversed.
With this notation we can write
\begin{python}
  front=PlaneSurface(CurveLoop(l01,l15,-l45,l40))
\end{python}
Keep in mind that if you use \code{Line(p4,p5)} instead of \code{-l45} both
objects are treated as different although connecting the same points with a
straight line in the same direction. The resulting geometry would include an
opening along the \code{p4}--\code{p5} connection.
This will lead to an inconsistent mesh and may result in a failure of the
volumetric mesh generator. Similarly we can define the other sides of the cube:
\begin{python}
  l37=Line(p3,p7)
  l62=Line(p6,p2)
  back=PlaneSurface(CurveLoop(l32,-l62,-l76,-l37))
  left=PlaneSurface(CurveLoop(-l40,-l64,l62,l20))
  right=PlaneSurface(CurveLoop(-l15,l13,l37,-l57))
\end{python}
We can now put the six surfaces together to form a \class{SurfaceLoop}
defining the boundary of the volume of the cube:
\begin{python}
  sl=SurfaceLoop(top,bottom,front,back,left,right)
  v=Volume(sl)
\end{python}
As in the 2D case, the \class{Design} class is used to define the geometry:
\begin{python}
  from esys.pycad.gmsh import Design
  from esys.finley import MakeDomain

  des=Design(dim=3, element_size = 0.1, keep_files=True)
  des.setScriptFileName("brick.geo")
  des.addItems(v, top, bottom, back, front, left, right)

  dom=MakeDomain(des)
  dom.write("brick.fly")
\end{python}
Note that the \finley mesh file \file{brick.fly} will contain the
triangles used to define the surfaces as they are added to the \class{Design}.
The example script of the cube is included with the software in
\file{brick.py} in the \ExampleDirectory.

\section{Alternative File Formats}
\pycad supports other file formats including I-DEAS universal file, VRML,
Nastran and STL. The following example shows how to generate the STL file
\file{brick.stl}:
\begin{python}
  from esys.pycad.gmsh import Design

  des=Design(dim=3, element_size = 0.1, keep_files=True)
  des.addItems(v, top, bottom, back, front, left , right)

  des.setFileFormat(des.STL)
  des.setMeshFileName("brick.stl")
  des.generate()
\end{python}
The example script of the cube is included with the software in
\file{brick_stl.py} in the \ExampleDirectory.

\section{Element Sizes}
The element size used globally is defined by the \code{element_size} argument
of the \class{Design}. The mesh generator will try to use this mesh size
everywhere in the geometry. In some cases it can be desirable to use a finer
mesh locally. A local refinement can be defined at each \class{Point}:
\begin{python}
  p0=Point(0., 0., 0., local_scale=0.01)
\end{python}
Here the mesh generator will create a mesh with an element size which is by
the factor \code{0.01} times smaller than the global mesh size
\code{element_size=0.3}, see Figure~\ref{fig:PYCAD 5}.
The point where a refinement is defined must be a point on a curve used to
define the geometry.

\begin{figure}
\centerline{\includegraphics{refine}}
\caption{Local refinement at the origin by \var{local_scale=0.01}
with \var{element_size=0.3} and number of elements on the top set to 10}
\label{fig:PYCAD 5}
\end{figure}

Alternatively, one can define a mesh size along a curve by defining the number
of elements to be used to subdivide the curve. For instance, to use $20$
elements on line \code{l23}:
\begin{python}
  l23=Line(p2, p3)
  l23.setElementDistribution(20)
\end{python}
Setting the number of elements on a curve overwrites the global mesh size
\code{element_size}. The result is shown in Figure~\ref{fig:PYCAD 5}.

\section{\pycad Classes}
%\declaremodule{extension}{esys.pycad}
%\modulesynopsis{Python geometry description and meshing interface}

\subsection{Primitives}
Some of the most commonly-used objects in \pycad are listed here.
For a more complete list see the full API documentation.

\begin{classdesc}{Point}{x=0.,y=0.,z=0.\optional{,local_scale=1.}}
creates a point at the given coordinates with local characteristic length \var{local_scale}
\end{classdesc}

\begin{classdesc}{CurveLoop}{list}
creates a closed curve from a \code{list} of
\class{Line}, \class{Arc}, \class{Spline}, \class{BSpline},
\class{BezierSpline} objects.
\end{classdesc}

\begin{classdesc}{SurfaceLoop}{list}
creates a loop of \class{PlaneSurface} or \class{RuledSurface}, which defines
the shell of a volume.
\end{classdesc}

\subsubsection{Lines}
\begin{classdesc}{Line}{point1, point2}
creates a line between two points.
\end{classdesc}

\begin{methoddesc}[Line]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on the line. If set, it overwrites the local
length setting which would be applied.
The progression factor \var{progression} defines the change of element size
between neighboured elements. If \var{createBump} is set progression is
applied towards the centre of the line.
\end{methoddesc}

\begin{methoddesc}[Line]{resetElementDistribution}{}
removes a previously set element distribution from the line.
\end{methoddesc}
\begin{methoddesc}[Line]{getElementDistribution}{}
returns the element distribution as a tuple of number of elements, progression
factor and bump flag. If no element distribution is set None is returned.
\end{methoddesc}

\subsubsection{Splines}
\begin{classdesc}{Spline}{point0, point1, ...}
A spline curve defined by a list of points \var{point0}, \var{point1}, \ldots
\end{classdesc}

\begin{methoddesc}[Spline]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on the spline. If set, it overwrites the local
length setting which would be applied.
The progression factor \var{progression} defines the change of element size
between neighboured elements. If \var{createBump} is set progression is
applied towards the centre of the spline.
\end{methoddesc}

\begin{methoddesc}[Spline]{resetElementDistribution}{}
removes a previously set element distribution from the spline.
\end{methoddesc}

\begin{methoddesc}[Spline]{getElementDistribution}{}
returns the element distribution as a tuple of number of elements, progression
factor and bump flag. If no element distribution is set None is returned.
\end{methoddesc}

\subsubsection{BSplines}
\begin{classdesc}{BSpline}{point0, point1, ...}
A B-spline curve defined by a list of points \var{point0}, \var{point1}, \ldots
\end{classdesc}

\begin{methoddesc}[BSpline]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on the curve. If set, it overwrites the local
length setting which would be applied.
The progression factor \var{progression} defines the change of element size
between neighboured elements. If \var{createBump} is set progression is
applied towards the centre of the curve.
\end{methoddesc}

\begin{methoddesc}[BSpline]{resetElementDistribution}{}
removes a previously set element distribution from the curve.
\end{methoddesc}

\begin{methoddesc}[BSpline]{getElementDistribution}{}
returns the element distribution as a tuple of number of elements, progression
factor and bump flag. If no element distribution is set None is returned.
\end{methoddesc}

\subsubsection{Bezier Curves}
\begin{classdesc}{BezierCurve}{point0, point1, ...}
A Bezier spline curve defined by a list of points \var{point0}, \var{point1}, \ldots
\end{classdesc}

\begin{methoddesc}[BezierCurve]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on the curve. If set, it overwrites the local
length setting which would be applied.
The progression factor \var{progression} defines the change of element size
between neighboured elements. If \var{createBump} is set progression is
applied towards the centre of the curve.
\end{methoddesc}

\begin{methoddesc}[BezierCurve]{resetElementDistribution}{}
removes a previously set element distribution from the curve.
\end{methoddesc}

\begin{methoddesc}[BezierCurve]{getElementDistribution}{}
returns the element distribution as a tuple of number of elements, progression
factor and bump flag. If no element distribution is set None is returned.
\end{methoddesc}

\subsubsection{Arcs}
\begin{classdesc}{Arc}{centre_point, start_point, end_point}
creates an arc by specifying a centre for a circle and start and end points.
An arc may subtend an angle of at most $\pi$ radians.
\end{classdesc}

\begin{methoddesc}[Arc]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on the arc. If set, it overwrites the local
length setting which would be applied.
The progression factor \var{progression} defines the change of element size
between neighboured elements. If \var{createBump} is set progression is
applied towards the centre of the arc.
\end{methoddesc}

\begin{methoddesc}[Arc]{resetElementDistribution}{}
removes a previously set element distribution from the arc.
\end{methoddesc}

\begin{methoddesc}[Arc]{getElementDistribution}{}
returns the element distribution as a tuple of number of elements, progression
factor and bump flag. If no element distribution is set None is returned.
\end{methoddesc}

\subsubsection{Plane surfaces}
\begin{classdesc}{PlaneSurface}{loop, \optional{holes=[list]}}
creates a plane surface from a \class{CurveLoop}, which may have one or more
holes described by a \var{list} of \class{CurveLoop} objects.
\end{classdesc}

\begin{methoddesc}[PlaneSurface]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on all lines.
\end{methoddesc}

\begin{methoddesc}[PlaneSurface]{setRecombination}{\optional{max_deviation=45 * \var{DEG} }}
the mesh generator will try to recombine triangular elements into
quadrilateral elements. \var{max_deviation} (in radians) defines the
maximum deviation of any angle in the quadrilaterals from the right angle.
Set \var{max_deviation}=\var{None} to remove recombination.
\end{methoddesc}

\begin{methoddesc}[PlaneSurface]{setTransfiniteMeshing}{\optional{orientation="Left"}}
applies 2D transfinite meshing to the surface.
\var{orientation} defines the orientation of triangles. Allowed values
are \var{``Left''}, \var{``Right''} and \var{``Alternate''}.
The boundary of the surface must be defined by three or four lines and an
element distribution must be defined on all faces where opposite
faces use the same element distribution. No holes must be present.
\end{methoddesc}

\subsubsection{Ruled Surfaces}
\begin{classdesc}{RuledSurface}{list}
creates a surface that can be interpolated using transfinite interpolation.
\var{list} gives a list of three or four lines defining the boundary of the
surface.
\end{classdesc}

\begin{methoddesc}[RuledSurface]{setRecombination}{\optional{max_deviation=45 * \var{DEG} }}
the mesh generator will try to recombine triangular elements into
quadrilateral elements. \var{max_deviation} (in radians) defines the
maximum deviation of any angle in the quadrilaterals from the right angle.
Set \var{max_deviation}=\var{None} to remove recombination.
\end{methoddesc}

\begin{methoddesc}[RuledSurface]{setTransfiniteMeshing}{\optional{orientation="Left"}}
applies 2D transfinite meshing to the surface.
\var{orientation} defines the orientation of triangles. Allowed values
are \var{``Left''}, \var{``Right''} and \var{``Alternate''}.
The boundary of the surface must be defined by three or four lines and an
element distribution must be defined on all faces where opposite
faces use the same element distribution. No holes must be present.
\end{methoddesc}

\begin{methoddesc}[RuledSurface]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on all lines.
\end{methoddesc}

\subsubsection{Volumes}
\begin{classdesc}{Volume}{loop, \optional{holes=[list]}}
creates a volume given a \class{SurfaceLoop}, which may have one or more holes
define by the list of \class{SurfaceLoop}.
\end{classdesc}

\begin{methoddesc}[Volume]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}}
defines the number of elements on all lines.
\end{methoddesc}

\begin{methoddesc}[Volume]{setRecombination}{\optional{max_deviation=45 * \var{DEG} }}
the mesh generator will try to recombine triangular elements into
quadrilateral elements. These meshes are then used to generate the volume mesh
if possible.
Together with transfinite meshing one can construct rectangular meshes.
\var{max_deviation} (in radians) defines the maximum deviation of any angle in
the quadrilaterals from the right angle.
Set \var{max_deviation}=\var{None} to remove recombination.
\end{methoddesc}

\begin{methoddesc}[Volume]{setTransfiniteMeshing}{\optional{orientation="Left"}}
applies transfinite meshing to the volume and all surfaces (if
\var{orientation} is not equal to \var{None}).
\var{orientation} defines the orientation of triangles. Allowed values
are \var{``Left''}, \var{``Right''} and \var{``Alternate''}.
The boundary of the surface must be defined by three or four lines and an
element distribution must be defined on all faces where opposite
faces use the same element distribution.
If \var{orientation} is equal to \var{None} transfinite meshing is not
switched on for the surfaces but needs to be set by the user.
No holes must be present.
\textbf{Warning: The functionality of transfinite meshing without
recombination is not entirely clear in \gmshextern.
So please apply this method with care.}
\end{methoddesc}

%============================================================================
\subsection{Transformations}

Sometimes it is convenient to create an object and then make copies at
different orientations or in different sizes. This can be achieved by
applying transformations which are used to move geometrical objects in the
3-dimensional space and to resize them.

\begin{classdesc}{Translation}{\optional{b=[0,0,0]}}
defines a translation $x \to x+b$. \var{b} can be any object that can be
converted into a \numpy object of shape $(3,)$.
\end{classdesc}

\begin{classdesc}{Rotation}{\optional{axis=[1,1,1], \optional{ point = [0,0,0], \optional{angle=0*RAD} } } }
defines a rotation by \var{angle} around axis through point \var{point} and direction \var{axis}.
\var{axis} and \var{point} can be any object that can be converted into a
\numpy object of shape $(3,)$.
\var{axis} does not have to be normalised but must have positive length.
The right-hand rule~\cite{RIGHTHANDRULE} applies.
\end{classdesc}

\begin{classdesc}{Dilation}{\optional{factor=1., \optional{centre=[0,0,0]}}}
defines a dilation by the expansion/contraction \var{factor} with
\var{centre} as the dilation centre.
\var{centre} can be any object that can be converted into a \numpy object of
shape $(3,)$.
\end{classdesc}

\begin{classdesc}{Reflection}{\optional{normal=[1,1,1], \optional{offset=0}}}
defines a reflection on a plane defined in normal form $n^t x = d$
where $n$ is the surface normal \var{normal} and $d$ is the plane \var{offset}.
\var{normal} can be any object that can be converted into a \numpy object of
shape $(3,)$.
\var{normal} does not have to be normalised but must have positive length.
\end{classdesc}

\begin{datadesc}{DEG}
a constant to convert from degrees to an internal angle representation in
radians. For instance use \code{90*DEG} for $90$ degrees.
\end{datadesc}

\subsection{Properties}
If you are building a larger geometry you may find it convenient to
create it in smaller pieces and then assemble them.
Property Sets make this easy, and they allow you to name the smaller
pieces for convenience.

Property Sets are used to bundle a set of geometrical objects in a
group. The group is identified by a name. Typically a Property Set
is used to mark subregions which share the same material properties or
to mark portions of the boundary. For efficiency, the \Design class
assigns an integer to each of its Property Sets, a so-called tag\index{tag}.
The appropriate tag is attached to the elements at generation time.

See the file \code{pycad/examples/quad.py} for an example using a {\it PropertySet}.

\begin{classdesc}{PropertySet}{name,*items}
defines a group geometrical objects which can be accessed through a \var{name}
The objects in the tuple \var{items} mast all be \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD objects.
\end{classdesc}

\begin{methoddesc}[PropertySet]{getManifoldClass}{}
returns the manifold class \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD
expected from the items in the property set.
\end{methoddesc}

\begin{methoddesc}[PropertySet]{getDim}{}
returns the spatial dimension of the items in the property set.
\end{methoddesc}

\begin{methoddesc}[PropertySet]{getName}{}
returns the name of the set
\end{methoddesc}

\begin{methoddesc}[PropertySet]{setName}{name}
sets the name. This name should be unique within a \Design.
\end{methoddesc}

\begin{methoddesc}[PropertySet]{addItem}{*items}
adds a tuple of items. They need to be objects of class \ManifoldOneD,
\ManifoldTwoD or \ManifoldThreeD.
\end{methoddesc}

\begin{methoddesc}[PropertySet]{getItems}{}
returns the list of items
\end{methoddesc}

\begin{methoddesc}[PropertySet]{clearItems}{}
clears the list of items
\end{methoddesc}

\begin{methoddesc}[PropertySet]{getTag}{}
returns the tag used for this property set
\end{methoddesc}

\section{Interface to the mesh generation software}
%\declaremodule{extension}{esys.pycad.gmsh}
%\modulesynopsis{Python geometry description and meshing interface}

The class and methods described here provide an interface to the mesh
generation software, which is currently \gmshextern. This interface could be
adopted to \emph{triangle} or another mesh generation package if this is
deemed to be desirable in the future.

\begin{classdesc}{Design}{
\optional{dim=3, \optional{element_size=1., \optional{order=1, \optional{keep_files=False}}}}}
describes the geometry defined by primitives to be meshed.
\var{dim} specifies the spatial dimension, while \var{element_size} defines
the global element size which is multiplied by the local scale to set the
element size at each \Point.
The argument \var{order} defines the element order to be used.
If \var{keep_files} is set to \True temporary files are kept, otherwise they
are removed when the instance of the class is deleted.
\end{classdesc}

\begin{memberdesc}[Design]{GMSH}
gmsh file format~\cite{GMSH}
\end{memberdesc}

\begin{memberdesc}[Design]{IDEAS}
I-DEAS universal file format~\cite{IDEAS}
\end{memberdesc}

\begin{memberdesc}[Design]{VRML}
VRML file format, \cite{VRML}
\end{memberdesc}

\begin{memberdesc}[Design]{STL}
STL file format~\cite{STL}
\end{memberdesc}

\begin{memberdesc}[Design]{NASTRAN}
NASTRAN bulk data format~\cite{NASTRAN}
\end{memberdesc}

\begin{memberdesc}[Design]{MEDIT}
Medit file format~\cite{MEDIT}
\end{memberdesc}

\begin{memberdesc}[Design]{CGNS}
CGNS file format~\cite{CGNS}
\end{memberdesc}

\begin{memberdesc}[Design]{PLOT3D}
Plot3D file format~\cite{PLOT3D}
\end{memberdesc}

\begin{memberdesc}[Design]{DIFFPACK}
Diffpack 3D file format~\cite{DIFFPACK}
\end{memberdesc}

\begin{memberdesc}[Design]{DELAUNAY}
the Delaunay triangulator, see \gmshextern and \cite{TETGEN}
\end{memberdesc}

\begin{memberdesc}[Design]{MESHADAPT}
the gmsh triangulator, see \gmshextern
\end{memberdesc}

\begin{memberdesc}[Design]{FRONTAL}
the NETGEN~\cite{NETGEN} triangulator
\end{memberdesc}

\begin{methoddesc}[Design]{generate}{}
generates the mesh file. The data are written to the file \var{Design.getMeshFileName}.
\end{methoddesc}

\begin{methoddesc}[Design]{setDim}{\optional{dim=3}}
sets the spatial dimension which needs to be $1$, $2$ or $3$.
\end{methoddesc}

\begin{methoddesc}[Design]{getDim}{}
returns the spatial dimension.
\end{methoddesc}

\begin{methoddesc}[Design]{setElementOrder}{\optional{order=1}}
sets the element order which needs to be $1$ or $2$.
\end{methoddesc}

\begin{methoddesc}[Design]{getElementOrder}{}
returns the element order.
\end{methoddesc}

\begin{methoddesc}[Design]{setElementSize}{\optional{element_size=1}}
sets the global element size. The local element size at a point is defined as
the global element size multiplied by the local scale.
The element size must be positive.
\end{methoddesc}

\begin{methoddesc}[Design]{getElementSize}{}
returns the global element size.
\end{methoddesc}

\begin{methoddesc}[Design]{setKeepFilesOn}{}
work files are kept at the end of the generation.
\end{methoddesc}

\begin{methoddesc}[Design]{setKeepFilesOff}{}
work files are deleted at the end of the generation.
\end{methoddesc}

\begin{methoddesc}[Design]{keepFiles}{}
returns \True if work files are kept, \False otherwise.
\end{methoddesc}

\begin{methoddesc}[Design]{setScriptFileName}{\optional{name=None}}
sets the file name for the gmsh input script.
If no name is given a name with extension "geo" is generated.
\end{methoddesc}

\begin{methoddesc}[Design]{getScriptFileName}{}
returns the name of the file for the gmsh script.
\end{methoddesc}

\begin{methoddesc}[Design]{setMeshFileName}{\optional{name=None}}
sets the name for the mesh file. If no name is given a name is generated.
The format is set by \\\var{Design.setFileFormat}.
\end{methoddesc}

\begin{methoddesc}[Design]{getMeshFileName}{}
returns the name of the mesh file.
\end{methoddesc}

\begin{methoddesc}[Design]{addItems}{*items}
adds the tuple of \var{items}. An item can be any primitive or a
\class{PropertySet}.
\warning{If a \PropertySet is added which includes an object that is not
part of a \PropertySet, it may not be considered in the meshing.}
\end{methoddesc}

\begin{methoddesc}[Design]{getItems}{}
returns a list of the items.
\end{methoddesc}

\begin{methoddesc}[Design]{clearItems}{}
resets the items in this design.
\end{methoddesc}

\begin{methoddesc}[Design]{getMeshHandler}{}
returns a handle to the mesh.
Calling this method generates the mesh from the geometry and returns a
mechanism to access the mesh data. In the current implementation this
method returns a file name for a file containing the mesh data.
\end{methoddesc}

\begin{methoddesc}[Design]{getScriptString}{}
returns the gmsh script to generate the mesh as a string.
\end{methoddesc}

\begin{methoddesc}[Design]{getCommandString}{}
returns the gmsh command used to generate the mesh as a string.
\end{methoddesc}

\begin{methoddesc}[Design]{setOptions}{
\optional{algorithm=None
\optional{, optimize_quality=\True
\optional{, smoothing=1
\optional{, curvature_based_element_size=\False
\optional{, algorithm2D=None
\optional{, algorithm3D=None
\optional{, generate_hexahedra=False
\optional{, random_factor=None}}}}}}}}}
sets options for the mesh generator.
Both \var{algorithm} and \var{algorithm2D} set the 2D meshing algorithm to be
used. If both parameters are given, they must be equal.
The algorithm needs to be \var{Design.DELAUNAY}, \var{Design.FRONTAL},
or \var{Design.MESHADAPT}. By default \var{Design.MESHADAPT} is used.
\var{algorithm3D} sets the 3D  meshing algorithm to be used.
The algorithm needs to be \var{Design.DELAUNAY} or \var{Design.FRONTAL}.
By default \var{Design.FRONTAL} is used.
\var{optimize_quality}=\True invokes an optimization of the mesh quality.
\var{smoothing} sets the number of smoothing steps to be applied to the mesh.
\var{curvature_based_element_size}=\True switches on curvature based
definition of element size.
\var{generate_hexahedra}=\True switches on the usage of quadrilateral or
hexahedral elements.
\var{random_factor} a positive amount used in the 2D meshing algorithm.
\end{methoddesc}

\begin{methoddesc}[Design]{getTagMap}{}
returns a \class{TagMap} to map the \class{PropertySet} names to tag numbers
generated by gmsh.
\end{methoddesc}

\begin{methoddesc}[Design]{setFileFormat}{\optional{format=\var{Design.GMSH}}}
sets the file format. \var{format} must be one of the values:\\
\var{Design.GMSH}\\
\var{Design.IDEAS}\\
\var{Design.VRML}\\
\var{Design.STL}\\
\var{Design.NASTRAN}\\
\var{Design.MEDIT}\\
\var{Design.CGNS}\\
\var{Design.PLOT3D}\\
\var{Design.DIFFPACK}.
\end{methoddesc}

\begin{methoddesc}[Design]{getFileFormat}{}
returns the file format.
\end{methoddesc}