diff --git a/contrib/MeshOptimizer/doc/figures/log_barrier/Makefile b/contrib/MeshOptimizer/doc/figures/log_barrier/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..515b395b758c31a9217084cc9dee261af5af32da
--- /dev/null
+++ b/contrib/MeshOptimizer/doc/figures/log_barrier/Makefile
@@ -0,0 +1,4 @@
+%.pdf : %.tex
+	pdflatex --shell-escape $<
+clean :
+	${RM} *.gnuplot *.table *.aux *.log
diff --git a/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier.pdf b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c288af6d3912406372e1b4b08b7b3a1242a97956
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier.pdf differ
diff --git a/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier.tex b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier.tex
new file mode 100644
index 0000000000000000000000000000000000000000..5cfc6648449fd91403df055935edc5fdca6d78fa
--- /dev/null
+++ b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier.tex
@@ -0,0 +1,16 @@
+\documentclass{standalone}
+\usepackage{tikz}
+\begin{document}
+\begin{tikzpicture}[yscale = 0.25, xscale = 2]
+  \draw[thick, ->] (0,0) -- (3.2,0) node[right] {$m$};
+  \draw[thick, ->] (0,0) -- (0,17) node[left] {$F_{\epsilon,\omega}$};
+%  \node at (2, 12) {$F_{\epsilon,\omega}(m) = (m - \omega)^2 + \log\Big(\frac{m - \epsilon} {\omega - \epsilon}\Big)^2$};
+  \foreach \y in {0, 5, 10, 15}
+    \draw[thick, shift={(0, \y)}] node[left] {$\y$}(-1pt, 0pt) -- (0pt,0pt) ;
+  \foreach \x in {0, 1, 2, 3}
+    \draw[thick, shift={(\x, 0)}] node[below] {$\x$}(0pt, -8pt) -- (0pt,0pt) ;
+  \clip(-1,-2) rectangle(3.5, 17);
+  \draw[very thick, dashed](0.2, 0) node[below]{$\epsilon$}-- (0.2, 20);
+  \draw[thick, domain = 0.2:3, samples=300] plot[id=opti] function{(log((x - 0.2)/ 0.8))**2 + (x - 1)**2}; 
+\end{tikzpicture}
+\end{document}
diff --git a/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier_max.pdf b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier_max.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..7140741c42bbaaef76123ad848e7c5e37ff683c4
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier_max.pdf differ
diff --git a/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier_max.tex b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier_max.tex
new file mode 100644
index 0000000000000000000000000000000000000000..5aa30df92682a4b798d03dd599b657e0f8603ca9
--- /dev/null
+++ b/contrib/MeshOptimizer/doc/figures/log_barrier/log_barrier_max.tex
@@ -0,0 +1,17 @@
+\documentclass{standalone}
+% Paper size: 3.58in,2.03in
+\usepackage{tikz}
+\begin{document}
+\begin{tikzpicture}[yscale = 0.25, xscale = 2]
+  \draw[thick, ->] (0,0) -- (3.2,0) node[right] {$m$};
+  \draw[thick, ->] (0,0) -- (0,17) node[left] {$F_{\epsilon,\omega}$};
+%  \node at (1.4, 12) {$F_{\epsilon,\omega}(m) = (m - \omega)^2 + \log\Big(\frac{m - \epsilon} {\omega - \epsilon}\Big)^2$};
+  \foreach \y in {0, 5, 10, 15}
+    \draw[thick, shift={(0, \y)}] node[left] {$\y$}(-1pt, 0pt) -- (0pt,0pt) ;
+  \foreach \x in {0, 1, 2, 3}
+    \draw[thick, shift={(\x, 0)}] node[below] {$\x$}(0pt, -8pt) -- (0pt,0pt) ;
+  \clip(-1,-2) rectangle(3.5, 17);
+  \draw[very thick, dashed](2.75, 0) node[below]{$\epsilon$}-- (2.75, 20);
+  \draw[thick, domain = 0:2.75, samples=300] plot[id=opti] function{(log((x - 2.75)/ -1.75))**2 + (x - 1)**2}; 
+\end{tikzpicture}
+\end{document}
diff --git a/contrib/MeshOptimizer/doc/figures/opti_process/Makefile b/contrib/MeshOptimizer/doc/figures/opti_process/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c57c1e8936c15d6bd5ec0909071b4d0e32f3838e
--- /dev/null
+++ b/contrib/MeshOptimizer/doc/figures/opti_process/Makefile
@@ -0,0 +1,4 @@
+opti_process.pdf : opti_process.tex
+	pdflatex --shell-escape $<
+clean :
+	${RM} *.gnuplot *.table *.aux *.log
diff --git a/contrib/MeshOptimizer/doc/figures/opti_process/opti2.dat b/contrib/MeshOptimizer/doc/figures/opti_process/opti2.dat
new file mode 100644
index 0000000000000000000000000000000000000000..c0093752ee823a55cc7f0941a0bd22a5d45dfeed
--- /dev/null
+++ b/contrib/MeshOptimizer/doc/figures/opti_process/opti2.dat
@@ -0,0 +1,71 @@
+-2.64148E+00 0  
+-2.43013E+00 1  
+-1.70784E+00 2  
+-1.48840E+00 3  
+-1.24431E+00 4  
+-1.22296E+00 5  
+-1.46493E+00 6  
+-1.37456E+00 7  
+-1.06042E+00 8  
+-1.08719E+00 9  
+-7.98080E-01 10 
+-6.91630E-01 11 
+-5.29097E-01 12 
+-7.59110E-01 13 
+-7.96486E-01 14 
+-5.83650E-01 15 
+-5.67035E-01 16 
+-5.54370E-01 17 
+-5.58354E-01 18 
+-4.42153E-01 19 
+-5.31631E-01 20 
+-3.67621E-01 21 
+-2.35836E-01 22 
+-3.03352E-01 23 
+-1.23011E-01 24 
+-3.10858E-01 25 
+-2.79462E-01 26 
+-3.07822E-01 27 
+-3.90367E-01 28 
+-2.83299E-01 29 
+-3.25716E-01 30 
+-2.32968E-01 31 
+-6.45337E-02 32 
+-7.54033E-02 33 
+ 1.03627E-01 34 
+ 1.10993E-01 35 
+ 1.57424E-01 36 
+ 1.12755E-01 37 
+ 1.15172E-01 38 
+ 1.96417E-01 39 
+ 1.59601E-01 40 
+ 2.11292E-01 41 
+ 1.83952E-01 42 
+ 2.25986E-01 43 
+ 2.67051E-01 44 
+ 1.72728E-01 45 
+ 2.87346E-01 46 
+ 2.34241E-01 47 
+ 2.50449E-01 48 
+ 1.53213E-01 49 
+ 2.73509E-01 50 
+ 2.20303E-01 51 
+ 1.71445E-01 52 
+ 2.94302E-01 53 
+ 2.40149E-01 54 
+ 1.62477E-01 55 
+ 2.70177E-01 56 
+ 1.97067E-01 57 
+ 1.49844E-01 58 
+ 3.15566E-01 59 
+ 2.14724E-01 60 
+ 2.78222E-01 61 
+ 3.41295E-01 62 
+ 3.99265E-01 63 
+ 4.07313E-01 64 
+ 4.55684E-01 65 
+ 4.37392E-01 66 
+ 4.56385E-01 67 
+ 4.88812E-01 68 
+ 4.47293E-01 69 
+ 5.02562E-01 70 
diff --git a/contrib/MeshOptimizer/doc/figures/opti_process/opti_process.pdf b/contrib/MeshOptimizer/doc/figures/opti_process/opti_process.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..6d99b6df1571b44bb9886a1c66a20baca3ef48c4
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/opti_process/opti_process.pdf differ
diff --git a/contrib/MeshOptimizer/doc/figures/opti_process/opti_process.tex b/contrib/MeshOptimizer/doc/figures/opti_process/opti_process.tex
new file mode 100644
index 0000000000000000000000000000000000000000..b6a59c1672c946aa8c628984e8dae9bd6877ea2e
--- /dev/null
+++ b/contrib/MeshOptimizer/doc/figures/opti_process/opti_process.tex
@@ -0,0 +1,40 @@
+\documentclass{standalone}
+\usepackage{tikz}
+\begin{document}
+\begin{tikzpicture}[yscale = 0.06, xscale = 1.8, thick]
+  %\node at (-1.4, 40) {\Large $\displaystyle J^{\min} = \min_{e,j} \frac{J_{ej}}{J_e^0}$};
+  \draw[dashed, green!70!black](0.5, 0) node[below]{$\bar{\epsilon}$}-- (0.5, 75);
+  \begin{scope}[black]
+    \draw(-3,0) -- (2,0) node[right] {};
+    \foreach \x in {-2, -1, 0, 1, 2}
+      \draw[shift={(\x, 0)}] node[below] {$\x$}(0pt, -20pt) -- (0pt,0pt) ;
+  \end{scope}
+  \begin{scope}[red, yscale = 3]
+    \draw[dashed](-2.9, 0) node[below]{$\epsilon_0$}-- (-2.9, 25) ;
+    \draw[dashed](-0.358, 0) node[below]{$\epsilon_1$}-- (-0.358, 25);
+    \draw[dashed](0.193, 0) node[below]{$\epsilon_2$}-- (0.193, 25);
+    \begin{scope}
+      \clip(-3.5, 0) rectangle(2.4, 25);
+      \draw[domain = -3:2, samples=500] plot[id=opti1] function{(log((x + 2.9)/ 3.9))**2 + (x - 1)**2}; 
+      \draw[domain = -3:2, samples=500] plot[id=opti2] function{(log((x + 0.358)/ 1.358))**2 + (x - 1)**2}; 
+      \draw[domain = -3:2, samples=500] plot[id=opti3] function{(log((x - 0.193)/ 0.807))**2 + (x - 1)**2}; 
+    \end{scope}
+    \node at (-2.50, 25) {$f_{\epsilon_0,\omega}$};
+    \node at (-0.10, 25) {$f_{\epsilon_1,\omega}$};
+    \node at (0.45, 25) {$f_{\epsilon_2,\omega}$};
+    \foreach \y in {0, 5, 10, 15, 20}
+      \draw[shift={(2, \y)}] node[right] {$\y$}(0pt, 0pt) -- (1pt,0pt) ;
+    \draw[->] (2,0) -- (2,25) node[right] {$f_{\epsilon,\omega}$};
+  \end{scope}
+  \begin{scope}[blue]
+    \draw plot file {opti2.dat} node[right]{$m$};
+    \node at (-2.641, 0) {$\bullet$};
+    \node at (-0.3257, 30) {$\bullet$};
+    \node at (0.214, 60) {$\bullet$};
+    \node at (0.5025, 70) {$\bullet$};
+    \draw[->] (-3,0) -- (-3,75) node[left] {Iterations};
+    \foreach \y in {0, 30, 60}
+      \draw[shift={(-3, \y)}] node[left] {$\y$}(-1pt, 0pt) -- (0pt,0pt) ;
+  \end{scope}
+\end{tikzpicture}
+\end{document}
diff --git a/contrib/MeshOptimizer/doc/figures/patches/patch_def.png b/contrib/MeshOptimizer/doc/figures/patches/patch_def.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab24babdab6855bb239548774d52fed6524230b4
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/patches/patch_def.png differ
diff --git a/contrib/MeshOptimizer/doc/figures/patches/patch_tangled.png b/contrib/MeshOptimizer/doc/figures/patches/patch_tangled.png
new file mode 100644
index 0000000000000000000000000000000000000000..343bb769d027944518dd4ef6bd39a948731629e1
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/patches/patch_tangled.png differ
diff --git a/contrib/MeshOptimizer/doc/figures/patches/patch_untangled.png b/contrib/MeshOptimizer/doc/figures/patches/patch_untangled.png
new file mode 100644
index 0000000000000000000000000000000000000000..f9cc54230a49433bbe07167003a590aed3cea56d
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/patches/patch_untangled.png differ
diff --git a/contrib/MeshOptimizer/doc/figures/patches/patchdef.xcf b/contrib/MeshOptimizer/doc/figures/patches/patchdef.xcf
new file mode 100644
index 0000000000000000000000000000000000000000..6a507128e9285fe7f381827c1f92f7b2b69b90ea
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/patches/patchdef.xcf differ
diff --git a/contrib/MeshOptimizer/doc/figures/untangling/linear.pdf b/contrib/MeshOptimizer/doc/figures/untangling/linear.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..54300e6d637db86121d4c3c32773fe20b14f63b6
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/untangling/linear.pdf differ
diff --git a/contrib/MeshOptimizer/doc/figures/untangling/p2.pdf b/contrib/MeshOptimizer/doc/figures/untangling/p2.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..bc47412ff8e1d3e10d5b8a476efe571c887eb2b7
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/untangling/p2.pdf differ
diff --git a/contrib/MeshOptimizer/doc/figures/untangling/p2_bad.pdf b/contrib/MeshOptimizer/doc/figures/untangling/p2_bad.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..895b9f35e94be9591fd88528082a7508dd102f8e
Binary files /dev/null and b/contrib/MeshOptimizer/doc/figures/untangling/p2_bad.pdf differ
diff --git a/contrib/MeshOptimizer/doc/mesh_optimization.tex b/contrib/MeshOptimizer/doc/mesh_optimization.tex
new file mode 100644
index 0000000000000000000000000000000000000000..729a80486158fbfc39bdfa8cbfc6c4abadbcc382
--- /dev/null
+++ b/contrib/MeshOptimizer/doc/mesh_optimization.tex
@@ -0,0 +1,833 @@
+%
+% Template for IDIHOM technical reports
+%
+%  to be processed with pdflatex
+%
+% based on initial design by K. Hillewaert
+
+\documentclass[12pt,a4paper,a4wide]{article}
+
+% ------------------------------------------------------------------------------
+% packages
+% ------------------------------------------------------------------------------
+
+% inclusion of non ps-graphics
+\usepackage{graphicx,psfrag}
+\usepackage{subfig}
+\usepackage{epstopdf}
+\usepackage{amsfonts,amsmath,amssymb,amscd}
+% typesetting headers and footers 
+\usepackage{fancyhdr}
+%\usepackage{lastpage}
+
+% fancy links
+\usepackage{color}
+\usepackage[citecolor=blue,linkcolor=blue,colorlinks=true]{hyperref}
+
+\usepackage{parskip}
+%\usepackage{alltt}
+\usepackage{verbatim}
+\usepackage[latin1]{inputenc}
+\usepackage{float}
+\usepackage{url}
+%\usepackage[francais]{babel}
+%\def\baselinestretch{2}
+
+%\floatstyle{ruled}
+%\newfloat{algorithm}{tbp}{loa}
+%\floatname{algorithm}{Algorithm}
+
+\graphicspath{{figures/}}
+
+\renewcommand{\vec}[1]{\ensuremath{\text{\boldmath $#1$\unboldmath}}}
+\newcommand{\mvx}{\vec{x}}
+
+% ------------------------------------------------------------------------------
+% modify here the properties of the document
+% ------------------------------------------------------------------------------
+
+%\newcommand{\reference}{D4.1-30b}
+%\newcommand{\shorttitle}{Curvilinear Mesh Generation Capability in Gmsh}
+%\newcommand{\theauthor}{T. Toulorge, J.F. Remacle}
+ 
+\title{Mesh Optimization in Gmsh}
+\author{Thomas Toulorge}
+\date{November 2014}
+
+% ------------------------------------------------------------------------------
+% page title and table of contents
+% ------------------------------------------------------------------------------
+
+\begin{document}
+
+% ------------------------------------------------------------------------------
+% define headers and footers
+% ------------------------------------------------------------------------------
+
+%\pagestyle{fancy}
+
+% header from left to right
+%\lhead{\includegraphics[width=0.1\textwidth]{figures/idihom_105px}}
+%\chead{}
+%\rhead{\small{\textit{\reference~-~\shorttitle}}}
+%\renewcommand{\headrulewidth}{0.4pt}
+
+% footer from left to right
+%\renewcommand{\footrulewidth}{0.4pt}
+%\lfoot{\nouppercase{\leftmark}}
+%\cfoot{}
+%\rfoot{\thepage/\pageref{LastPage}}
+%\newcommand{\chaptermark}[1]{\markboth{#1}{}}
+
+% ------------------------------------------------------------------------------
+% main text 
+% ------------------------------------------------------------------------------
+
+%\newpage
+\maketitle
+
+
+\section{Introduction}
+
+The quality of the meshes generated by Gmsh in a first step is
+sometimes not satisfying. The mesh optimization tool aims to
+improve the meshes with respect to a given set of quality measures
+without performing any topological operation. The tool is designed
+to improve locally bad (or even invalid) meshes by using an
+optimization algorithm that moves the mesh vertices.
+
+
+\section{Method}
+
+
+\subsection{Problem Definition}\label{sec:problem-def}
+
+In order to improve the mesh, an optimization problem is defined:
+\[
+\min_{\mvx_i} F(\mvx_i)
+\]
+where the variables $\mvx_i$ are the vertex positions, and the objective
+function $F$ takes into account the quality measures of interest. The
+position of a vertex in the interior of the computational domain
+is normally expressed in terms of its spatial coordinates ($x$, $y$ and
+$z$). Vertices classified on a boundary are allowed to move along the
+corresponding geometric entity, in case a CAD model is available:
+the variables associated to such a vertex are then its parametric
+coordinates, as provided by the CAD modeler. Thus, vertices
+classified on model edges will have as only degree of freedom the
+parametric coordinate $u$, while vertices classified on model faces
+will have two degrees of freedom $u$ and $v$. Vertices classified on
+a model vertex will not be allowed to move.
+
+The objective function $F$ is the function of all variables $\mvx_i$
+to be minimized by moving the nodes. It is the sum of several
+\emph{contributions}:
+\[
+F(\mvx_i) = \sum_{j} F_j(\mvx_i),
+\]
+where each contribution $F_j(\mvx_i)$ is actually a function of
+a \emph{measure} $m_j(\mvx_i)$:
+\[
+F_j(\mvx_i) = f_j[m_j(\mvx_i)].
+\]
+A measure is usually a quantity of interest
+characterizing the quality or the validity of the mesh (for
+instance the scaled Jacobian in high-order meshes). Nevertheless,
+a contribution proportional to the square of the node displacement
+is often included in the objective function, so that the mesh
+remains as similar as possible to the original one, while complying
+with other quality constraints.
+
+
+\subsection{Moving Barriers}
+
+Most often, the mesh optimizer is used to change the mesh so that a
+quality or a validity measure lies within a given range of values.
+For this purpose, a \emph{log barrier} is used:
+\[
+f_{\epsilon,\omega}(m) = (m - \omega)^2 +
+\log\left(\frac{m-\epsilon}{\omega-\epsilon}\right)^2,
+\]
+where $\omega$ is the optimal value of the measure $m$, and $\epsilon$
+is a value for which the function blows up (cf.
+figure~\ref{fig:barrier}). Thus, setting $\epsilon<\omega$ ensures that
+the measure $m$ will never drop below the value of $\epsilon$ during the
+optimization procedure. Likewise, setting $\epsilon>\omega$ ensures that
+$m$ will never exceed $\epsilon$.
+
+\begin{figure}
+%\begin{center}
+\centering
+\includegraphics[width=0.45\textwidth]{log_barrier/log_barrier}
+\includegraphics[width=0.45\textwidth]{log_barrier/log_barrier_max}
+%\end{center}
+\caption{Barrier function for $\omega=1$ and
+$\epsilon<\omega$ (left) or $\epsilon>\omega$
+(right)\label{fig:barrier}} 
+\end{figure}
+
+In order for the measure $m$ to remain in the domain of definition of
+the barrier function $f_{\epsilon,\omega}$, the value of $\epsilon$ must
+be lower than the minimum of $m$ in the domain or subdomain of interest.
+Thus, a constraint forcing the measure $m$ to increase to reach a target
+minimum value $\bar{\epsilon}$ is introduced through a \emph{moving
+barrier}: a sequence of optimization problems is solved. A conjugate
+gradient optimization algorithm is applied to each problem, so that $m$
+progressively increases. Each run is stopped after a fixed number of
+iterations, when stagnation in $m$ is detected, or when the target
+criterion $m\geq\bar{\epsilon}$ is reached. Between two runs, $\epsilon$
+is reset to a value just below the current minimum value of $m$, so that
+the variables remain in the domain of realizability.
+Fig.~\ref{fig:opti_process} illustrates this process. The same method
+is applied for a maximum constrain.
+
+
+\subsection{Passes}
+
+It is difficult to handle several moving barriers at the same
+time. This is why the optimization procedure can be
+used in successive \emph{passes}, between which the objective function
+changes. For instance, a moving barrier can be used in a first pass to
+bring $m$ to a threshold $m_{\min}$. In a second pass, the objective
+function is composed of a fixed barrier set to $m_{\min}$, plus a moving
+barrier that forces $m$ to drop below a value $m_{\max}$. This technique
+can also prove useful when one wants to impose a constraint on a crucial
+measure $m_1$ in a first pass, and then improve another less important
+one $m_2$ in a second pass. 
+
+\begin{figure}
+%\begin{center}
+\centering
+\includegraphics[width=0.95\textwidth]{opti_process/opti_process}
+%\end{center}
+\caption{Optimization process: three successive series of
+(maximum) 30 conjugate gradient iterations\label{fig:opti_process}} 
+\end{figure}
+
+
+\subsection{Strategy and Mesh Patches}\label{sec:strategy}
+
+A common use case for the mesh optimization tool is when only a few
+small portions of the mesh do not comply with the required quality
+criteria. Involving the whole mesh in the optimization process is then
+unnecessary, or even prohibitively costly. Therefore, the tool makes it
+possible to select \emph{patches} of the mesh (or ``blobs'') in which
+the optimization is performed, while the rest of the domain is left
+untouched.
+
+The first step in the definition of patches consists in identifying
+the mesh elements that do not satisfy the user-defined criteria. A
+primary patch containing a user-defined number $N$ of layers of elements
+surrounding each ``bad'' element is then built. A geometrical criterion
+can also be added: among the elements forming the $N$ layers around the
+bad element, only those located within a user-defined distance are
+retained. This additional criterion is particularly useful when dealing
+with anisotropic meshes, as the boundary layer mesh illustrated in
+Fig.~\ref{fig:patches}.
+%The optimal values for the number of layers $N$
+%and the distance factor are case-dependant: they should involve the lowest
+%number of elements while still leaving the optimization procedure enough
+%freedom to reach a node configuration that complies with the target mesh
+%quality. In complex cases, a unique value of these parameters for the whole
+%mesh may lead to patches that are too large at some locations, but too small
+%at others. It is then beneficial to use the untangling procedure in an
+%adaptive loop where the patch size is progressively increased in case
+%the optimization procedure fails to reach the quality criteria.
+
+A potential problem with the patches created as described above is
+that they may overlap. Let us consider the case of a subdomain built
+around an bad element, that contains another bad element close to its
+boundary: this patch may not provide the necessary degrees of freedom
+to fix the second bad element, thus the optimization procedure can
+fail to reach the mesh quality target in this patch.
+In order to avoid such problems, the user can choose between two
+strategies:
+\begin{description}
+\item[Disjoint patches] Overlapping patches are detected and
+merged. This strategy ensures that each invalid element in a patch
+has enough surrounding elements for the untangling procedure to
+be successful, provided the primary patches are large enough, but
+it may lead to large patches, which can be computationally expensive.
+\item[``One-by-one'' strategy] The untangling procedure is applied
+sequentially to each patch, with the objective of fixing only
+the invalid element around which it is built, while allowing other
+invalid elements in the same patch to remain broken. This strategy
+lets the untangling procedure work on small-size patches.
+\end{description}
+
+\begin{figure}
+\begin{center}
+\begin{tabular}{ccc}
+\includegraphics[width=0.33\textwidth]{patches/patch_tangled}&
+\includegraphics[width=0.33\textwidth]{patches/patch_def}&
+\includegraphics[width=0.33\textwidth]{patches/patch_untangled}
+\end{tabular}
+\end{center}
+\caption{Detail of a boundary-layer mesh on a curved geometry:
+tangled quadratic mesh (left), patch definition with $N=5$ layers
+in red and geometrical criterion represented by a green circle
+(center), untangled mesh (right).
+\label{fig:patches}}
+\end{figure}
+
+
+\section{Implementation}
+
+
+\subsection{General organization}\label{sec:gen-org}
+
+The code of the optimization tool itself is divided into three main
+parts:
+
+\begin{itemize}
+\item The class \texttt{Patch} handles the information needed from
+and provided to the mesh patch, such as the node coordinates and the
+value of the quality measures and their gradients. It allows to work
+indifferently with physical and parametric node coordinates, and to
+avoid modifying the actual mesh data in Gmsh until the optimization
+has completed successfully.
+\item The class \texttt{MeshOpt} is in charge of setting up and
+running the optimization procedure in a given patch. The computation
+of the objective function, as well as the assessment of the success
+or the failure of the optimization procedure, are handled by classes
+that represent each contribution. These classes derived from
+\texttt{ObjContrib} are called from \texttt{MeshOpt} through the
+class \texttt{ObjectiveFunction}.
+\item The function \texttt{meshOptimizer} and the related functions
+perform the patch selection and execute the overall optimization
+process.
+\end{itemize}
+
+In order to tailor the mesh optimization tool to a new application, it
+is necessary to carry out the following developments:
+\begin{itemize}
+\item Implement the main function setting the input parameters (see
+Section~\ref{sec:input-param}) and calling the function
+\texttt{meshOptimizer}.
+\item Implement the class derived from \texttt{MeshOptPatchDef}
+that drives the patch selection process (see
+Section~\ref{sec:patch-selec}).
+\item Implement the classes derived from \texttt{ObjContrib} that
+compute the different contributions to the objective function and
+check the corresponding criteria (see Section~\ref{sec:obj-func}).
+\item Implement the appropriate measure(s) in the class
+\texttt{Patch}.
+\end{itemize}
+
+These steps are detailed in the following sections.
+
+\subsection{Input Parameters}\label{sec:input-param}
+
+The input parameters that control the optimization process are
+provided to \texttt{meshOptimizer} through the structure
+\texttt{MeshOptParameters}:
+
+\begin{verbatim}
+struct MeshOptParameters {
+  int dim ;
+  bool onlyVisible ;
+  bool fixBndNodes;
+  bool useGeomForPatches, useGeomForOpt;
+  MeshOptPatchDef *patchDef;
+  std::vector<MeshOptPass> pass;
+  int optDisplay;
+  int verbose;
+  int success;
+  double CPU;
+};
+\end{verbatim}
+
+This structure carries the following information:
+\begin{itemize}
+\item The fields \texttt{dim} and \texttt{onlyVisible} specify the
+geometric entities (2D or 3D, all of them or only the visible ones)
+in which the mesh will be optimized.
+\item The field \texttt{fixBndNodes} determines whether the nodes
+located on the boundaries (i.e. the nodes classified on model
+entities of dimension \texttt{dim-1}) should be fixed or allowed to
+move along their respective model entity.
+\item The fields \texttt{useGeomForPatches} and \texttt{useGeomForOpt}
+determine whether the geometrical information (i.e. on which model
+entity each element is classified) should be passed respectively:
+\begin{itemize}
+\item to \texttt{patchDef} (see Section~\ref{sec:patch-selec}), in
+order to take it into account in the selection of mesh patches,
+\item to the classes \texttt{MeshOpt} and \texttt{Patch}, in order
+to take it into account in the evaluation of quality measures.   
+\end{itemize}
+If both fields are set to \texttt{false}, the geometrical information
+is not computed, which may result in an improved performance.
+\item The field \texttt{patchDef} is a pointer on an instance of a
+class derived from \texttt{MeshOptPatchDef}, that implements the
+methods needed to select the mesh patches (see
+Section~\ref{sec:patch-selec}).
+\item The vector \texttt{pass} contains instances of the structure
+\texttt{MeshOptPass}, which determines the optimization procedure
+for each pass, as described hereafter.
+\item The fields \texttt{optDisplay} and \texttt{verbose} control
+the output (respectively the iteration interval at which the progress
+of the Conjugate Gradient procedure is printed to screen and the
+overall level of verbosity).
+\item The fields \texttt{success} and \texttt{CPU} indicate whether
+the overall procedure has been successful (i.e. whether the target
+values for the quality measures have been reached) and how much CPU
+time it used.
+\end{itemize}
+
+The structure \texttt{MeshOptPass}, that specifies the optimization
+procedure for each pass, is as follows:
+
+\begin{verbatim}
+struct MeshOptPass {
+  std::vector<ObjContrib*> contrib;
+  int optIterMax;
+  int barrierIterMax;
+};
+\end{verbatim}
+
+where:
+
+\begin{itemize}
+\item The vector \texttt{contrib} contains pointers on instances
+of classes derived from \texttt{ObjContrib}, each instance
+describing a contribution to the objective function (see
+Section~\ref{sec:obj-func}).
+\item The field \texttt{optIterMax} gives the maximum number of
+Conjugate Gradient iterations to be performed for a given objective
+function (i.e. before a potential log barrier is moved).
+\item The field \texttt{barrierIterMax} determines the maximum
+number of times the objective function is changed, i.e. the number
+of times a potential log barrier is moved.
+\end{itemize}
+
+
+\subsection{Patch Selection}\label{sec:patch-selec}
+
+The patch selection process is controlled by an application-specific
+class that is derived from \texttt{MeshOptPatchDef}:
+
+\begin{verbatim}
+class MeshOptPatchDef {
+public:
+  enum { STRAT_CONNECTED, STRAT_ONEBYONE };
+  int strategy;
+  int minLayers, maxLayers;
+  union {
+    struct {
+      int maxAdaptPatch;
+      int maxLayersAdaptFact;
+      double distanceAdaptFact;
+    };
+    bool weakMerge;
+  };
+  virtual ~MeshOptPatchDef() {}
+  virtual double elBadness(MElement *el,
+                           GEntity* gEnt) const = 0;
+  virtual double maxDistance(MElement *el) const = 0;
+  virtual int inPatch(const SPoint3 &badBary,
+                      double limDist,
+                      MElement *el,
+                      GEntity* gEnt) const = 0;
+protected:
+  bool testElInDist(const SPoint3 &P, double limDist,
+                    MElement *el) const;
+};
+\end{verbatim}
+
+The fields of this class contain information about the strategy
+and the number of layers in the patch:
+
+\begin{itemize}
+\item The field \texttt{strategy} specifies the overall strategy
+with (\texttt{STRAT\_CONNECTED} for merging overlapping patches
+or \texttt{STRAT\_ONEBYONE} for a sequential treatment, see
+Section~\ref{sec:strategy}).
+\item The fields \texttt{minLayers} and \texttt{maxLayers} give
+respectively the minimum and maximum amount of layers of elements
+surrounding the bad element to be included in the patch.
+\item Depending on the strategy chosen, additional information
+must be provided:
+\begin{itemize}
+\item If the strategy is \texttt{STRAT\_CONNECTED}, the field
+\texttt{weakMerge} specifies whether two patches are merged if
+they overlap (value \texttt{false}), or only if a bad element
+of one patch is included in the other one (value \texttt{true}).
+\item If the strategy is \texttt{STRAT\_ONEBYONE}, an adaptive
+process loop is used: the patch size is progressively increased
+in case the optimization procedure fails. The maximum number of
+adaptations is then controlled by the field \texttt{maxAdaptPatch}.
+The growth factor in maximum number of layers and in the maximum
+distance criterion at each adaptation is specified by the fields
+\texttt{maxLayersAdaptFact} and \texttt{distanceAdaptFact}
+respectively.
+\end{itemize}
+\end{itemize}
+
+Application-specific control of the patch selection is achieved
+through the pure virtual methods \texttt{elBadness},
+\texttt{maxDistance} and \texttt{inPatch}, that have to be
+implemented in a derived class:
+\begin{itemize}
+\item \texttt{elBadness} determines the ``badness'' of an element:
+it returns a negative value for a bad element and a positive value
+for a good element. The return value is a floating point instead of
+a boolean because the tool always deals with the patches in
+decreasing order of badness in the \texttt{STRAT\_ONEBYONE} strategy.
+\item \texttt{maxDistance} returns the value the maximum distance
+criterion for a given bad element. This value matters only if the
+criterion is used in the method \texttt{inPatch}.
+\item \texttt{inPatch} determines whether a given element should be
+included in a patch. It returns an integer value:
+\begin{itemize}
+\item $-1$ means that the element should not be included in the patch,
+\item $0$ means that the element should be included in the patch only if
+it belongs to a layer below \texttt{minLayers},
+\item $1$ means that the element should be included in the patch if
+it belongs to a layer below \texttt{maxLayers}.
+\end{itemize}
+This system makes the patch selection very flexible. For instance, it is
+possible to exclude unconditionally certain type of elements, or to take
+into account certain criteria only in layers between \texttt{minLayers}
+and \texttt{maxLayers}. Moreover, the protected method
+\texttt{testElInDist} can be called from \texttt{inPatch} for an
+efficient test of the distance criterion, if desired.
+\end{itemize}
+
+
+
+\subsection{Objective Function}\label{sec:obj-func}
+
+As explained in Section~\ref{sec:problem-def}, the objective
+function is defined as a sum of contributions, each
+contribution being a function of a single measure. In practice,
+it is important to follow the progress of the measure to determine
+whether the optimization procedure is successful. To this end, the
+extrema (minimum and maximum) of the measure over the patch under
+consideration are evaluated during the computation of the contribution.
+Three criteria are associated to each contribution:
+\begin{itemize}
+\item A success criterion tests whether the minimum (or maximum)
+of the measure is greater (respectively lower) than the target value,
+\item A failure criterion tests whether the minimum (or maximum)
+of the measure is lower (respectively greater) than a critical value
+(for instance the value 0 for the scaled Jacobian in high-order meshes,
+below which the mesh is invalid),
+\item A stagnation criterion tests whether the minimum (or maximum)
+of the measure stagnates compared to the start of the conjugate
+gradient algorithm.
+\end{itemize}
+Thus, a mesh that does not fulfill the failure criterion anywhere can
+be considered as acceptable, even if the target has not been reached
+in some patches. The stagnation criterion avoids wasting
+computation time in problematic cases by stopping an optimization
+procedure that does not improve the measure.
+
+As mentioned in Section~\ref{sec:gen-org}, the contributions
+are defined by specifying in \texttt{MeshOptPass} a vector of
+pointers on instances of classes derived from \texttt{ObjContrib}.
+The class \texttt{ObjContrib} is as follows:
+
+\begin{verbatim}
+class ObjContrib
+{
+public:
+  ObjContrib(std::string mesName, std::string name);
+  virtual ~ObjContrib() {}
+  virtual ObjContrib *copy() const = 0;
+  const double getMin() { return _min; }
+  const double getMax() { return _max; }
+  const std::string &getName() const { return _name; }
+  const std::string &getMeasureName() const {
+    return _measureName;
+  }
+  virtual void initialize(Patch *mesh) = 0;
+  virtual bool fail() = 0;
+  virtual bool addContrib(double &Obj,
+                          alglib::real_1d_array &gradObj) = 0;
+  virtual void updateParameters() = 0;
+  virtual bool targetReached() = 0;
+  virtual bool stagnated() = 0;
+  virtual void updateMinMax() = 0;
+  void updateResults();
+
+protected:
+  static const double BIGVAL;
+  ObjContrib *_parent;
+  std::string _measureName, _name;
+  double _min, _max;
+};
+\end{verbatim}
+
+A class defining a contribution should derive from \texttt{ObjContrib}.
+One instance should be defined through the constructor in the function
+calling the optimization tool, and passed through \texttt{MeshOptPass}.
+Then, a new copy of this ``parent'' instance is used for each patch.
+\texttt{ObjContrib} stores the pointer to the parent instance
+(\texttt{\_parent}), the name of the contribution and the corresponding
+measure (\texttt{\_name}, \texttt{\_measureName}) for output purposes, and
+the extrema of the measure (\texttt{\_min}, \texttt{\_max}) for the
+evaluation of target criteria. The method \texttt{updateResults} updates
+the extrema of the measure in the parent instance for reporting purposes.
+A derivative class should implement the following methods:
+
+\begin{itemize}
+\item The constructor \texttt{ObjContrib} may be needed if fixed
+user-defined parameters shall be provided to the contribution (for
+instance, a weight factor in the objective function).
+\item The method \texttt{copy} returns a new copy of the instance.
+\item The method \texttt{initialize} is in charge of initializing
+the contribution for each patch, i.e. setting up the fields and
+calling the initialization methods of the measure in the class
+\texttt{Patch}.
+\item The method \texttt{fail} returns whether the measure fails
+to fulfill a critical criterion. The whole process is considered
+as failed if this method returns \texttt{true} for at least one
+of the patches at the end of the optimization procedure.
+\item The method \texttt{addContrib} computes the contribution
+and its gradients and evaluates the extrema of the measure at
+the same time.
+\item The method \texttt{updateParameters} recalculates the
+parameters of the contribution (e.g. the blow-up value $\epsilon$
+for a log barrier). It is called before each run of the
+conjugate gradient algorithm.
+\item The method \texttt{targetReached} checks whether the target
+value has been reached for the corresponding measure. The
+optimization procedure for a patch is considered successful
+and stops when this method returns \texttt{true} for all the
+contributions.
+\item The method \texttt{stagnated} checks whether the corresponding
+measure stagnates compared to its value at the beginning of the
+conjugate gradient run. In case it returns \texttt{true} for at least
+one contribution, the run is stopped.
+\item The method \texttt{updateMinMax} recomputes the extrema of
+the corresponding measure.
+\end{itemize}
+
+The derivative class is thus in charge of evaluating the measures
+by calling the appropriate methods of the class \texttt{Patch},
+applying the function to it and defining the success, failure and
+stagnation criteria. In order to make the implementation easier
+and flexible, several functions along with the corresponding
+criteria are already implemented:
+
+\begin{itemize}
+\item The class \texttt{ObjContribFuncSimple} simply gives
+the value of the measure, with no particular criterion (it is always
+successful, never fails and never stagnates).
+\item The class \texttt{ObjContribFuncBarrierMovMin} implements
+a moving log barrier against the minimum of the measure, with a
+user-defined critical value.
+\item The class \texttt{ObjContribFuncBarrierMovMax} performs
+the same role for the  maximum of the measure.
+\item The class \texttt{ObjContribFuncBarrierFixMinMovMax} sets
+two log barriers: a fixed one against the minimum of the measure
+and a moving one against the maximum of the measure.
+\end{itemize}
+
+It is then possible to implement a contribution as a class deriving
+from \texttt{ObjContrib} and a template parameter that is
+instantiated with one of the function classes described above.
+
+
+\section{Applications}
+
+\subsection{High-Order Mesh Optimizer}
+
+The generation of a high-order mesh with Gmsh starts with creating a
+straight sided mesh. Then, each mesh entity corresponding to a curved
+boundary of the domain is curved by adding high-order mesh points on
+the model entity on which it is classified. This naive procedure does
+not ensure that all the elements of the final curved mesh are valid,
+as illustrated in Figure \ref{fig:untangling}. The high-order mesh
+optimizer aims to fix the invalid elements created by this process
+by ensuring that their scaled Jacobian, whose bounds are evaluated in
+a robust manner~\cite{bounds-jcp}, is positive and lies within a
+user-defined range $[J_{\min}, J_{\max}]$. More details are available
+in Ref.~\cite{untangling-jcp}.
+
+\begin{figure}
+  \begin{center}
+  \begin{tabular}{ccc}
+  \includegraphics[width=0.3\textwidth]{untangling/linear} &
+  \includegraphics[width=0.3\textwidth]{untangling/p2_bad} &
+  \includegraphics[width=0.3\textwidth]{untangling/p2}\\
+  First-order mesh & High-order vertices &\textbf{Untangling}
+  \end{tabular}
+\end{center}
+\caption{Straight sided mesh (left) basic curvilinear (quadratic)
+mesh with tangled elements (center) and untangled mesh (right).
+\label{fig:untangling}}
+\end{figure}
+
+To this end, elements whose scaled Jacobian lies outside the
+range $[J_{\min}, J_{\max}]$ are considered as bad elements. Two
+optimization passes are defined. In the first pass, two
+contributions are included: the square of the node displacement
+(see Section~\ref{sec:problem-def}) and a moving log barrier against
+the minimum of the scaled Jacobian, with $J_{\min}$ as target value
+and $0$ as critical value. In the second pass, the moving barrier
+against the minimum scaled Jacobian is replaced by a fixed barrier
+on the minimum scaled Jacobian plus a moving barrier on the maximum
+scaled Jacobian with $J_{\max}$ as target value.
+
+
+The high-order mesh optimizer is accessible from the ``High order
+tools'' window in Gmsh's graphical interface. The parameters are
+as follows:
+
+\begin{itemize}
+\item \texttt{Target Jacobian range} corresponds to $J_{\min}$ and
+$J_{\max}$.
+\item \texttt{Number of layers} is the maximum number of layers
+around a bad element to be included in a patch (see \texttt{minLayers}
+in Section~\ref{sec:patch-selec}).
+\item \texttt{Distance factor} controls the distance criterion
+for the creation of patches (see Section~\ref{sec:patch-selec}). The
+factor is multiplied by the maximum distance, among all high-order
+nodes in a bad element, between the node and the corresponding location
+in a straight-sided version of the bad element.
+\item \texttt{Boundary nodes} determines whether the boundary nodes
+are fixed or are allowed to move along the corresponding boundary
+in case a CAD model is available.
+\item \texttt{W fixed} and \texttt{W free} are the relative weights
+of the node displacement contribution for fixed and free vertices
+respectively, compared to the Jacobian contributions.
+\item \texttt{Maximum number of iterations} is the maximum number
+of iterations in the Conjugate Gradient algorithm (see
+\texttt{optIterMax} in Section~\ref{sec:input-param}).
+\item \texttt{Max. number of optimization passes} is the maximum number
+of times the log barriers are moved (see \texttt{barrierIterMax} in
+Section~\ref{sec:input-param}).
+\item \texttt{Strategy} determines the strategy for the treatment of
+patches (see Sections~\ref{sec:strategy} and~\ref{sec:patch-selec}).
+\item \texttt{Max. number of blob adaptation iter.},
+\texttt{Num. layer adaptation factor} and
+\texttt{Distance adaptation factor} control the adaptation of the
+patch size with the ``adaptive one-by-one'' strategy (see
+\texttt{maxAdaptPatch}, \texttt{maxLayersAdaptFact} and
+\texttt{distanceAdaptFact} in Section~\ref{sec:patch-selec}).
+\end{itemize}
+
+These options are likely to change as the high-order mesh
+optimizer is being further developed.
+
+
+\subsection{Mesh Quality Optimizer}
+
+The mesh quality optimizer aims to improve the quality of meshes,
+as measured by the ``inverse condition number'' quality metric.
+The elements below a quality threshold are marked as bad, and a
+unique optimization pass includes two contributions: the square
+of the node displacement (see Section~\ref{sec:problem-def}) and
+a moving log barrier against the minimum of the quality measure.
+
+The mesh quality optimizer is only accessible through Gmsh's API
+in C++ or Python. It is launched by the function
+\texttt{MeshQualityOptimizer}, that take as arguments a pointer to
+an instance of GModel and a structure \texttt{MeshQualOptParameters}
+as follows:
+\begin{verbatim}
+struct MeshQualOptParameters {
+  bool onlyValidity;
+  bool excludeQuad, excludeHex, excludePrism, excludeBL;
+  double minTargetIdealJac;
+  double minTargetInvCondNum;
+  double weightFixed;
+  double weightFree;
+  int nbLayers;
+  int dim;
+  int optIterMax;
+  int barrierIterMax;
+  bool onlyVisible;
+  double distanceFactor;
+  bool fixBndNodes;
+  int strategy;
+  int maxAdaptBlob;
+  int adaptBlobLayerFact;
+  double adaptBlobDistFact;
+  int SUCCESS;
+  double minIdealJac, maxIdealJac;
+  double minInvCondNum, maxInvCondNum;
+  double CPU;
+
+  MeshQualOptParameters ()
+    : onlyValidity(false), excludeQuad(false),
+      excludeHex(false), excludePrism(false), excludeBL(false),
+      minTargetIdealJac(0.1), minTargetInvCondNum(0.1),
+      weightFixed(1000.), weightFree (1.), nbLayers (6),
+      dim(3), optIterMax(300), barrierIterMax(50),
+      onlyVisible(true), distanceFactor(12),
+      fixBndNodes(false), strategy(0), maxAdaptBlob(3),
+      adaptBlobLayerFact(2.), adaptBlobDistFact(2.), CPU(0.),
+      minIdealJac(0.), maxIdealJac(0.), minInvCondNum(0.),
+      maxInvCondNum(0.), SUCCESS(-1)
+  {
+  }
+};
+\end{verbatim}
+
+Many parameters correspond directly to those of
+\texttt{MeshOptParameters} and \texttt{PatchDef} described in
+Sections~\ref{sec:input-param} and~\ref{sec:patch-selec}. The
+differences are:
+\begin{itemize}
+\item The boolean \texttt{onlyValidity} forces the optimizer to
+use the ``ideal Jacobian'' of the element instead of the inverse
+condition number when set to \texttt{true}.
+\item The booleans \texttt{excludeQuad}, \texttt{excludeHex} and
+\texttt{excludePrism} make it possible to exclude from the
+optimization the quadrangular, prismatic and hexahedral elements
+respectively.
+\item The boolean \texttt{excludeBL}, when set to \texttt{true},
+excludes the boundary layer elements from the optimisation.
+\item The field \texttt{minTargetIdealJac} sets the target value
+for the minimum ideal Jacobian (if \texttt{onlyValidity} is
+\texttt{true}).
+\item The field \texttt{minTargetInvCondNum} sets the target
+value for the inverse condition number (if \texttt{onlyValidity}
+is \texttt{false}).
+\item The fields \texttt{weightFixed} and \texttt{weightFree} are
+the relative weights of the node displacement contribution for
+fixed and free vertices respectively, compared to the inverse
+condition number or Jacobian contribution.
+\item The field \texttt{strategy} determines the strategy in the
+manner of the patch selection options in
+Section~\ref{sec:patch-selec}: $0$ corresponds to
+\texttt{STRAT\_CONNECTED} with \texttt{weakMerge} set to
+\texttt{false}, $1$ corresponds to \texttt{STRAT\_ONEBYONE}
+and $2$corresponds to \texttt{STRAT\_CONNECTED} with
+\texttt{weakMerge} set to \texttt{true}.
+\item The fields \texttt{minIdealJac} and \texttt{maxIdealJac}
+return the extrema of the ideal Jacobian in the output mesh
+(if \texttt{onlyValidity} is \texttt{true}).
+\item The fields \texttt{minInvCondNum} and
+\texttt{maxInvCondNum} return the extrema of the inverse condition
+number in the output mesh (if \texttt{onlyValidity} is
+\texttt{false}).
+\end{itemize}
+
+These options are likely to change as the mesh quality optimizer
+is being further developed.
+
+%-----------------------------------------
+%\clearpage
+%\bibliographystyle{abbrv}
+%\bibliography{D41-30b}
+
+
+\begin{thebibliography}{2}
+
+\bibitem{bounds-jcp}
+A.~Johnen, J.-F.~Remacle, and C.~Geuzaine.
+\newblock Geometrical validity of curvilinear finite elements.
+\newblock {\em J. Comput. Phys.}, 233:359--372, 2013.
+
+\bibitem{untangling-jcp}
+T.~Toulorge, C.~Geuzaine, J.-F. Remacle, and J.~Lambrechts.
+\newblock Robust untangling of curvilinear meshes.
+\newblock {\em J. Comput. Phys.}, 254:8--26, 2013.
+
+\end{thebibliography}
+
+
+\end{document}