%!TEX program = xelatex
\documentclass[a4paper,11pt]{article}
\usepackage{pos}
% \usepackage{ulem}
\usepackage{natbib}
\usepackage{cancel}
\usepackage{pgfplots}
\usepackage{wrapfig}
\usepackage{subcaption}
\usepackage{mathtools}
\pgfplotsset{compat=1.18}

\title{HMC with Normalizing Flows}
%% \ShortTitle{Short Title for header}

% TODO: Add citations !!

\author*[a]{Sam Foreman}
\author[b, c]{Taku Izubuchi}
\author[d]{Luchang Jin}
\author[a]{Xiao-Yong Jin}
\author[a]{James C. Osborn}
\author[b]{Akio Tomiya}

\affiliation[a]{Argonne National Laboratory,\\
  Lemont, IL 60439}

\affiliation[b]{RIKEN,\\
 2-1 Hirosawa, Wako, Saitama, 351-0198, Japan}

\affiliation[c]{Brookhaven National Laboratory,\\
 Upton, NY 11973}

\affiliation[d]{Dept. of Physics, University of Connecticut,\\
 Storrs, CT 06269}

\emailAdd{foremans@anl.gov}
\emailAdd{izubuchi@bnl.gov}
\emailAdd{luchang.jin@uconn.edu}
\emailAdd{xjin@anl.gov}
\emailAdd{osborn@alcf.anl.gov}

\abstract{%
    We propose using Normalizing Flows as a trainable kernel within the
    molecular dynamics update of Hamiltonian Monte Carlo (HMC).
    %
    By learning (invertible) transformations that simplify our dynamics, we can
    outperform traditional methods at generating independent configurations.
    %
    We show that, using a carefully constructed network architecture, our
    approach can be easily scaled to large lattice volumes with minimal
    retraining effort.
    %
    The source code for our implementation is publicly available online at
    \href{https://www.github.com/nftqcd/fthmc}{github.com/nftqcd/fthmc}.
}

\FullConference{%
 The 38th International Symposium on Lattice Field Theory, LATTICE2021
  26th-30th July, 2021
  Zoom/Gather@Massachusetts Institute of Technology
}

%% \tableofcontents

\begin{document}
\maketitle
\section{\label{sec:intro}Introduction}
\subsection{%
    \label{subsec:gauge_theory}%
    2D \texorpdfstring{\(U(1)\)}{U(1)} Gauge Theory
}
%
\begin{wrapfigure}{r}{.33\columnwidth}
  \includegraphics[width=0.33\columnwidth]{assets/plaq.pdf}
  \caption{\label{fig:plaq} Plaquette \(x_{P}\).}
\end{wrapfigure}
%
Let \(U_{\mu}(n) = e^{i x_{\mu}(n)}\in U(1)\), with \(x_{\mu}(n)\in [-\pi,
\pi]\) denote the \emph{link variables}, where \(x_{\mu}(n)\) is a link at the
site \(n\) oriented in the direction \(\hat{\mu}\).
%
Our goal is to generate an ensemble of configurations, distributed according to
% %
% For the 2D \(U(1)\) gauge theory on a square lattice with periodic boundary
% conditions, we can write the target distribution
% We can write our target distribution \(p(x)\) in terms of the Wilson action
% \(S(x)\) as
%
\begin{equation}
    p(x)\propto e^{-S(x)},\quad S(x) \equiv \sum_{P} 1 - \cos x_{P},
\end{equation}
%
where $S(x)$ is the Wilson action for the 2D \(U(1)\) gauge
theory\footnote{Explicitly, on a square lattice with periodic boundary
conditions.}, and \(x_{P} = x_{\mu}(n) + x_{\nu}(n+\hat{\mu}) -
x_{\mu}(n+\hat{\nu}) - x_{\nu}(n)\) is the sum of the links around the
elementary plaquette as shown in Figure~\ref{fig:plaq}.
%
For a given lattice configuration, we can define the topological charge as \(Q
= \frac{1}{2\pi}\sum_{P}\mathrm{arg}(x_{P}) \in\mathbb{Z}\), where
\(\mathrm{arg}(x_{P})\in [-\pi, \pi]\).
% \begin{equation}
%     Q = \frac{1}{2\pi}\sum_{P}\mathrm{arg}(x_{P}),\text{where}\quad
%     \mathrm{arg}(x_{P})\in[-\pi,\pi].
% \end{equation}
%

Traditional sampling techniques such as HMC are known to suffer from
\emph{critical slowing down}~\cite{Schaefer:2010hu}, a phenomenon characterized
by the freezing of the topological charge \(Q\) as we approach physical lattice
spacings.
%
This effect can be seen clearly in Figure~\ref{subfig:q8},~\ref{subfig:q16},
where \(Q\) typically remains stuck for the duration of the HMC trajectories.
%
In this work we describe a method for training a normalizing flow model that is
capable of sampling from different topological charge sectors, thereby reducing
the computational effort required to generate independent configurations.
%
% The most commonly used approach, Hamiltonian Monte Carlo (HMC), is
% This can be seen in the samplers inability to mix between different
% \textcolor{blue}{We are interested in how this quantity evolves over a finite length Markov
% chain, and in particular, we can define the tunneling rate, \(\delta Q\) as}

% \marginpar{\color{red}{Remove references to \(\delta Q\)?}}
% %
% \begin{equation}
%     \delta Q = \sqrt{\left(Q_{i+1} - Q_{i}\right)^{2}}
% \end{equation}
% %
% \textcolor{blue}{where the difference is between subsequent states in the chain.}
% %
% \textcolor{blue}{This quantity is analogous to the lag-one autocorrelation in the
% topological charge.}
\subsection{\label{subsec:ft}Field Transformations}
%
For a random variable \(z\) with a given distribution \(z \sim r(z)\), and an
invertible function \(x = f(z)\) with \(z = f^{-1}(x)\), we can use the change
of variables formula to write
%
\begin{equation}
    p(x) = r(z)\left|\det\frac{\partial z}{\partial x}\right| =
    r(f^{-1}(x))\left|\det\frac{\partial f^{-1}}{\partial x}\right|
\end{equation}
%
where \(r(z)\) is the (simple) prior density, and our goal is to generate
independent samples from the (difficult) target distribution \(p(x)\).
%
This can be done using \emph{normalizing flows}~\cite{rezende2015variational}
to construct a model density \(q(x)\) that approximates the target
distribution, i.e. \(q(\cdot)\simeq p(\cdot)\) for a suitably-chosen flow
\(f\).

\begin{figure}[htpb]
    \centering
    \includegraphics[width=\textwidth]{assets/flow_model.pdf}
    % \includegraphics[width=\textwidth]{assets/flow_model.pdf}
    \caption{\label{fig:flow_model} Using a flow to generate data \(x'\). Image
    adapted from~\cite{weng2018flow}}
\end{figure}
%
We can construct a normalizing flow by composing multiple invertible functions
\(f_{i}\) so that \(x\equiv \left[f_{k}\circ f_{k-1}\circ \cdots \circ
f_{2}\circ f_{1}\right](z)\).
%
In practice, the functions \(f_{i}\) are usually implemented as \emph{coupling
layers}, which update an ``active'' subset of the variables, conditioned on the
complimentary ``frozen'' variables~\cite{Kanwar:2020xzo,Albergo:2021vyo}.
%
\subsection{\label{subsec:coupling_layers}Affine Coupling Layers}
A particularly useful template function for constructing our normalizing flows
is the affine coupling layer~\cite{DinhSB16,rezende2015variational},
%
\begin{align*}
    f(x_{1}, x_{2}) &= \left(e^{s(x_2)}x_{1} + t(x_{2}),\, x_{2}\right),
        \quad\text{with}\quad \log J(x) = \sum_{k}\left[s(x_{2})\right]_{k}\\
    f^{-1}(x'_{1}, x'_{2}) &= \left((x'_{1}-t(x'_{2}))e^{-s(x'_{2})},\, x'_{2}\right),
        \quad\text{with}\quad \log J(x') = \sum_{k}-\left[s(x'_{2})\right]_{k}
\end{align*}
%
where \(s(x_{2})\) and \(t(x_{2})\) are of the same dimensionality as \(x_{1}\)
and the functions act element-wise on the inputs.

In order to effectively draw samples from the correct target distribution
\(p(\cdot)\), our goal is to minimize the error introduced by approximating
\(q(\cdot)\simeq p(\cdot)\).
%
To do so, we use the (reverse) Kullback-Leibler (KL) divergence from
Eq.~\ref{eq:kl_div}, which is minimized when \(p=q\).
%
\begin{align}
    \label{eq:kl_div}
    D_{\mathrm{KL}}(q\|p)
    &\equiv\int dy q(y)\left[\log q(y) - \log p(y)\right]\\
    &\simeq \frac{1}{N}\sum_{i=1}^{N} \left[\log q(y_{i})-\log p(y_{i})\right],
        \,\,\text{where}\,\, y_{i}\sim q
\end{align}
%
\section{\label{sec:trivializing_map}Trivializing Map}
%
Ultimately, our goal is to evaluate expectation values of the form
%
\begin{equation}
    \label{eq:exp_val}
    \langle \mathcal{O} \rangle = \tfrac{1}{\mathcal{Z}} \int dx\, \mathcal{O} (x) e^{-S(x)}.
\end{equation}
%
Using a normalizing flow, we can perform a change of variables \(x = f(z)\), so
Eq.~\ref{eq:exp_val} becomes
%
\begin{align}
    \langle \mathcal{O} \rangle
    &= \frac{1}{\mathcal{Z}} \int dz \left|\det \left[ J(z) \right]\right|
        \mathcal{O} (f(z)) e^{-S(f(z))},
        \text{ where } J (z) = \frac{\partial f(z)}{\partial z} \\
    &= \frac{1}{\mathcal{Z}}\int dz \mathcal{O} (f(z)) e^{-S(f(z))
        + \log |\det[J(z)]|}.
\end{align}
%
We require the Jacobian matrix, \(J(z)\), to be:
%
\begin{enumerate}
    \item Injective (1-to-1) between domains of integration
    \item Continuously differentiable (\emph{or}, differentiable with
        continuous inverse)
\end{enumerate}
%
The function \(f\) is a \emph{trivializing map}~\cite{luscher2009} when
\(S(f(z)) - \log\left|\det J(z)\right| = \text{const.}\), and our expectation
value simplifies to
%
\begin{equation}
    \langle\mathcal{O}\rangle =
    \frac{1}{\mathcal{Z}^{\ast}}\int dz\, \mathcal{O}(f(z)), \text{ where }
    \frac{1}{\mathcal{Z}^{\ast}}
    = \frac{1}{\mathcal{Z}}\exp(-\text{const.}).
\end{equation}
%
\section{\label{sec:hmc_nf}Field Transformation HMC: \texttt{fthmc}}
%
We can implement the trivializing map defined in
Sec.~\ref{sec:trivializing_map} using a normalizing flow model.
%
For conjugate momenta \(\pi\), we can write the Hamiltonian as
%
\begin{equation}
    H(z, \pi) = \frac{1}{2}\pi^{2} + S(f(z)) - \log\left|\det J(f(z))\right|,
\end{equation}
%
and the associated equations of motion as
%
\begin{align}
    \dot{z} &= \frac{\partial H}{\partial \pi} = \pi \\
    \dot{\pi} &= -J(z) S'(f(z)) + \mathrm{tr}\left[ J^{-1}\frac{d}{dz} J \right].
\end{align}
%
If we introduce a change of variables, \(\pi = J(z)\rho = J(f^{-1}(x))\rho\)
and \(z = f^{-1}(x)\), the determinant of the Jacobian matrix reduces to \(1\),
and we obtain the modified Hamiltonian
%
\begin{equation}
    \tilde{H}(x, \rho) = \frac{1}{2}\rho^{\dagger}\rho + S(x) - \log|\det J|.
\end{equation}
%
As shown in Figure~\ref{fig:fthmc}, we can use a \emph{field transformation},
\(f^{-1}: z \rightarrow x\) to perform HMC updates on the transformed variables
\(x\), and \(f: x \rightarrow z\) to recover the physical target distribution.
%
\begin{figure}[htpb]
    \centering
    \includegraphics[width=\textwidth]{assets/fthmc.pdf}
    \caption{\label{fig:fthmc}Normalizing flow with inner HMC block.}
\end{figure}
%
\subsection{\label{subsec:hmc}Hamiltonian Monte Carlo (HMC)}
We describe the general procedure of the Hamiltonian Monte Carlo
algorithm~\cite{Betancourt:2017}.
\begin{enumerate}
    \item Introduce \(v \sim \mathcal{N} (0,\mathbb{I}_{n}) \in \mathbb{R}^{n}\)
        and write the joint distribution as
        \begin{equation}
            p(x, v) = p(x) p(v) \propto e^{-S(x)} e^{-\frac{1}{2} v^{T} v}
        \end{equation}
    \item Evolve the joint system \((\dot x, \dot v)\) according to
        Hamilton's equations along \(H=\text{const.}\) using the leapfrog
        integrator:
        \begin{equation}
            \textbf{ (a.)  } \tilde{v} \leftarrow v - \frac{\varepsilon}{2}\partial_{x}S(x)\quad
            \textbf{ (b.)  } x' \leftarrow x + \varepsilon \tilde{v}\quad
            \textbf{ (c.)  } v' \leftarrow \tilde{v} - \frac{\varepsilon}{2}\partial_{x} S(x')
        \end{equation}
    \item Accept or reject the proposal configuration using the
        Metropolis-Hastings test,
        \begin{equation}
            x_{i+1} = \begin{cases}
                x', \text{ with probability }
                    A(x'|x) \equiv \min\left\{1, \frac{p(x')}{p(x)}%
                    \left|\frac{\partial x'}{\partial x^{T}}\right|\right\}\\
                x, \text{ with probability } 1 - A(x'|x)
            \end{cases}
        \end{equation}
\end{enumerate}
%
\subsection{\label{subsec:volume_scaling}Volume Scaling}
%
We use gauge equivariant coupling layers that act on plaquettes as the
base layer for our network architecture.
%
As in~\cite{Albergo:2021vyo}, these layers are composed of inner coupling
layers which are implemented as stacks of convolutional layers.
%
One advantage of using convolutional layers is that we can re-use the trained
weights when scaling up to larger lattice volumes.
%
Explicitly, when scaling up the lattice volume we can initialize the weights
of our new network with the previously trained values.
%
This approach has the advantage of requiring minimal retraining effort while
being able to efficiently generate models on large lattice volumes.
%
\section{\label{sec:results}Results}
%
For traditional HMC, we see in Figure~\ref{subfig:q8},\ref{subfig:q16}
that \(Q \simeq 0\) for across all trajectories for both \(8\times 8\) and
\(16\times 16\) lattice volumes.
%
Conversely, we see in Figure~\ref{subfig:q8},\ref{subfig:q16} that the trained
models are able to sample from multiple values of \(Q\) for both the \(8\times
8\) and \(16\times16\) volumes.
%

The results in Figure~\ref{subfig:loss} took \(\sim 4\) hours to train using a
single A100 Nvidia GPU.
%
The performance of the trained sampler is limited by the acceptance rate of the
proposed configurations, which in turn, is ultimately limited by the
computational resources used to train the model.
%
Because of this, we would expect a continued improvement in performance with
additional training.
%
For this relatively simple proof of concept, we were able to
demonstrate the usefuleness of our approach without requiring prohibitively
large upfront training costs.
%
\begin{figure}[htpb]
    \centering
    \begin{subfigure}[b]{\linewidth}
        \includegraphics[width=\linewidth]{assets/histories_8x8_beta6.pdf}
        \caption{\label{subfig:q8}The average plaquette \(x_{P}\) and
            topological charge \(Q\) histories for the trained model and
        HMC at \(\beta = 6\) with \(V = 8 \times 8\).}
    \end{subfigure}
    \hfill
    \begin{subfigure}[b]{\linewidth}
        \includegraphics[width=\linewidth]{assets/histories_16x16_beta6_xfr.pdf}
        \caption{\label{subfig:q16}The same model from Figure~\ref{subfig:q8}
        used to generate configurations on \(V = 16\times16\) lattice.}
    \end{subfigure}
    \caption{\label{fig:histories}Comparison of lattice observables for both
        HMC and the trained model at \(V = 8\times 8\), and \(V =
    16\times16\).}
\end{figure}
    % \begin{subfigure}[b]{\linewidth}
\begin{figure}
    \centering
    \includegraphics[width=\linewidth]{assets/ess_loss_dkl_train.pdf}
    \caption{\label{subfig:loss}Loss and Effective Sample
        Size~\cite{2018arXiv180904129E} (ESS) vs train epoch at \(\beta = 6\)
    on \(V = 8\times 8\) lattice.}
\end{figure}
%
\section{\label{sec:ack}Acknowledgments}
This research was supported by the Exascale Computing Project (17-SC-20-SC), a
collaborative effort of the U.S. Department of Energy Office of Science and the
National Nuclear Security Administration.
%
This research was performed using resources of the Argonne Leadership Computing
Facility (ALCF), which is a DOE Office of Science User Facility supported under
Contract DE\_AC02--06CH11357.
%
This work describes objective technical results and analysis.
%
Any subjective views or opinions that might be expressed in the work do not
necessarily represent the views of the U.S. DOE or the United States
Government.
%
Results presented in this research were obtained using the Python
\citep{van1995python}, programming language and its many data science libraries
\cite{%
    matplotlib,
    harris2020array,
    ipython4160251%
}
%
% \begin{thebibliography}{99}
\bibliographystyle{JHEP}
\bibliography{main}
% \bibitem{...}

% \end{thebibliography}

\end{document}


\section{CIR- model}
\subsection{Calibration Parameters}
	\input{CIRParam/cirParam.tex}
	\cirParamTableA\hfill\\
	\cirErrorTableA\hfill\\
\subsection{Model Parameters}
	\input{ModelParam/modelParam.tex}
	\modelParamTableA
\subsection{Euler Parameter}
	\input{Euler/euler.tex}
	\eulerParamA
\subsection{Computational Times}
	\input{CompTimes/ctime.tex}
	\ctimeA
\hfill\\
	\input{CompTimes/ctimeTests.tex}
	\ctimeTestsA
\subsection{Mean errors of Discount Factor}
	\input{DF/dfMeanErr.tex}
\begin{table}
	\dfMeanErrA
\centering
\caption{Market data containing the zero rate curve and zero coupon curve at 30/12/2019.}
\label{tab:market_dataA}
\end{table}
\subsection{Errors of Swaption}
	\input{Swaption/swaption.tex}
\begin{table}
	\errorSwaptionA
\centering
\caption{Swaption error for data at 30/12/2019.}
\label{tab:swaption_errorA}
\end{table}
\subsection{Plots of Zero Coupon Prices}
	\input{ZC/figure.tex}
\subsection{Plots of Discount Factor}
	\input{DF/figure.tex}
\subsection{Plots of Interest Rates}
	\input{Rates/figure.tex}
\subsection{Plots of theoretical Mean and Variance}
	\input{MeanVar/figure.tex}
\subsection{Plots of Forward Zero-Coupon Prices}
	\input{Forward/figure.tex}
\appendix
\section{Market Data}
	\input{MarketData/marketData.tex}
\begin{table}
	\marketDataA
\centering
\caption{Market data containing the zero rate curve and zero coupon curve at 30/12/2019.}
\label{tab:market_dataA}
\end{table}
\section{Market Data}
	\input{MarketData/swaptionStrike.tex}
\begin{table}
	\strikeSwaptionA
\centering
\caption{Market data containing the swaption strikes at 30/12/2019.}
\label{tab:strike_swaptionA}
\end{table}
\section{Market Data}
	\input{MarketData/swaptionMarket.tex}
\begin{table}
	\marketSwaptionA
\centering
\caption{Market data containing the swaption prices at 30/12/2019.}
\label{tab:market_swaptionA}
\end{table}


\section{Conclusions and Future Work}\label{sect:conc}

The paper's primary contributions are to explore two subprogram value driven questions.  The first question addressed the importance of a choice of modeling algorithm. The modeling algorithm can impact one or both of selective pressure (because model fitness can be integrated back into program fitness) and genetic variation (because subprograms used by a model can be inserted into the BGP archive and used in BFGP crossover).   We tried two algorithms for decision trees: \REPTREE and \SCIKIT. Neither of the algorithms produced significantly better results across all the 17 benchmarks.  For some benchmarks  the average fitness results were significantly different but, again, neither of algorithms was consistently superior in each case.
Using a completely different modeling technique, i.e. one different from decision trees altogether,  that also provides feature selection would be an interesting comparison to using \REPTREE.  All feature selection algorithms are stochastic so their results vary. Perhaps the stochasticity of any algorithm overwhelms the impact of a particular technique's bias. We next will consider whether the stronger dissimilarity between the modeling bias of LASSO and decision trees has significant impact. LASSO is a linear technique and has a regularization pressure parameter making it an interesting option.

Our second investigation explored choosing different sets of subprograms for modeling. Rather than use all the subprograms of one program, it mixed subprograms across a subset of programs from the entire population. Our question was whether identifying useful subprograms in this way and integrating them into selection (via integration of model fitness for a program) and/or genetic variation (via archive based crossover) would yield superior error for the best GP model of the run.  Again, we found our results to be equivocal.  None of the configurations emerged consistently superior. Again, however ranking and error differed among benchmarks.

This work brings to light particular paths  that to extend the concepts and understanding of BGP.  There are several avenues that could be explored:
\begin{inparaenum}
\item
It would be interesting to see if using a machine learning model whose purpose is more inline with what BGP asks for would benefit the evolutionary process.  For example, instead of building an entire machine learning model on the trace, one could use a feature selection technique, or measure the statistical correlation between the columns.  The output would provide material with which to populate the archive.  However, this would not provide additional fitness measures.

\item
It is unclear exactly why the BGP model that uses the combined traces of all of the programs in the population performed less well than running the model on each program trace independently.  It is possible that the idea has merit, but the particulars were not a good fit for BGP.  In particular, in each generation only a single machine learning model is built.  Therefore, all of the selected trees put into the archive in a single generation have the same weight.

\item
In BGP if two subtrees have identical columns in the program trace (i.e. identical \textit{semantics}), only the smaller subtree is kept.  This introduces a bias that is not necessarily beneficial to the evolutionary process.  It would be interesting to explore how common subtrees with identical semantics are, and if choosing the smaller tree is the better choice.
\end{inparaenum}

\section*{Acknowledgments} Suppressed to honor the author blind review process.


%!TEX root = modelguide.tex

\chapter{Muscle Wrapping and Via Points}
\label{multipointSpringIntro:sec}

ArtiSynth provides support for multipoint springs and muscles, which
are similar to axial springs and muscles (Sections
\ref{AxialSprings:sec} and \ref{PointToPointMuscles:sec}), except that
they can contain multiple via points and also wrap around obstacles.
This allows the associated force directions to vary in response to
obstacles and constraints in the model, which is particularly
important in biomechanical models where point-to-point muscles need to
wrap around anatomical structures such as bones.  A schematic
illustration is shown in Figure \ref{multiPointSpring:fig}, where a
single spring connects points $\p_0$ and $\p_2$, while passing through
a single via point $\p_1$ and wrapping around obstacles $W_1$ and
$W_2$. Figure \ref{multiSpringExamples:fig} shows two examples
involving a rigid body with fixed via points and a spring wrapping
around three rigid bodies.

\begin{figure}[ht]
\begin{center}
 \includegraphics[width=4in]{images/multiPointSpring}
\end{center}
\caption{Schematic illustration of a multipoint spring passing through
a via point $\p_1$ and wrapping around two obstacles $W_1$ and
$W_2$. The points $A_1$, $B_1$ and $A_2$, $B_2$ denote the first and
last locations where $W_1$ and $W_2$ make contact with the spring.}
\label{multiPointSpring:fig}
\end{figure}

\begin{figure}[ht]
\begin{center}
  \begin{tabular}{cc}
    \iflatexml
       \includegraphics[width=3in]{images/multiSpringDemo}&
       \includegraphics[width=3in]{images/multiBodyWrap2}
    \else
       \includegraphics[width=2.5in]{images/multiSpringDemo}&
       \includegraphics[width=2.5in]{images/multiBodyWrap2}
    \fi
  \end{tabular}
\end{center}
\caption{Left: A multipoint spring with two via points rigidly fixed
to a box-shaped rigid body. Right: A multipoint spring wrapped around
three obstacles.}
\label{multiSpringExamples:fig}
\end{figure}

As with axial springs and muscles, multipoint springs and muscles must
have two points to denote their beginning and end. In between, they can
have any number of {\it via} points, which are fixed locations which
the spring must pass through in the specified order. Any ArtiSynth
\javaclass[\mech]{Point} object may be specified
as a via point, including particles and markers. The purpose of the
via point is generally to direct the spring along some particular
path. In particular, the path directions before and after a via point
will generally be different, and forces acting on the via point will
be determined by the tension in the spring (or muscle) acting along
these two different directions.

\begin{figure}[ht]
\begin{center}
 \includegraphics[width=2.5in]{images/multiPointViaPoint}
\end{center}
\caption{A multipoint spring with a single via point $\p_1$, showing
the unit direction vectors $\u_A$ and $\u_B$ immediately before and
after.}
\label{multiPointViaPoint:fig}
\end{figure}

\begin{sideblock}
Conceptually, the spring or muscle ``slides'' through its via points,
which act analogously to virtual three dimensional pulleys. In
particular, the proportional distance between via points does {\it not}
remain fixed.
\end{sideblock}

The tension $f$ within the spring or muscle is computed from its
material, using the relation $f(l,\dot l, a)$ described in Sections
\ref{AxialSprings:sec} and \ref{sec:mechii:musclematerials},
where $l$ now denotes the {\it entire} length of the spring
as it passes through the via points and wraps around obstacles. The
total force $\f$ acting on each via point is then given by
%
\begin{equation*}
\f = f \cdot (\u_B - \u_A)
\end{equation*}
%
where $\u_B$ and $\u_A$ are unit vectors giving the spring's direction
immediately after and before the via point
(Figure \ref{multiPointViaPoint:fig}).

Multipoint springs can also be made to wrap around one or more {\it
wrappable} objects. Unlike via points, wrappable objects can occur in
any order along the spring and wrapping only occurs when the spring
and the object actually collide. Any ArtiSynth object that implements
\javaclass[\mech]{Wrappable} can be used as a wrapping object
(currently, only \javaclass[\mech]{RigidBody} objects
implement {\tt Wrappable}).
The forces acting on a wrappable are those
generated by the forces $\f_A$ and $\f_B$ acting on the points
A and B where the spring makes and leaves contact with the
it (Figure \ref{multiPointObstacle:fig}). These forces
are given by
%
\begin{equation*}
\f_A = - f \u_A, \quad \f_B = f \u_B,
\end{equation*}
%
where $\u_B$ are $\u_A$ are unit vectors giving the spring's direction
immediately before A and after B. Points A and B are collectively
known as the A/B points.

\begin{figure}[ht]
\begin{center}
 \includegraphics[width=2.5in]{images/multiPointObstacle}
\end{center}
\caption{A multipoint spring wrapping around a single obstacle $W$,
with initial and final contact at points A and B,
and associated unit direction vectors $\u_A$ and $\u_B$.}
\label{multiPointObstacle:fig}
\end{figure}

\section{Via Points}
\label{ViaPoints:sec}

Multipoint springs and muscles are implemented by the classes
\javaclass[\mech]{MultiPointSpring} and
\javaclass[\mech]{MultiPointMuscle}, respectively.
The relationship between {MultiPointSpring} and
{MultiPointMuscle} is the same as that between
\javaclass[\mech]{AxialSpring} and \javaclass[\mech]{Muscle}:
The latter is a subclass of the former, and allows
the creation of active tension forces in response to
its {\sf excitation} property.

An application allocates one of these components, sets the appropriate
material properties for the tension forces, and then adds points and
wrappable objects as desired.

Points can be added, queried, and removed using the methods
%
\begin{lstlisting}[]
   void addPoint (Point pnt)
   Point getPoint (int idx)
   int numPoints()
   boolean removePoint (Point pnt)
\end{lstlisting}
%
As with \javaclass[\mech]{AxialSpring}, there must
be at least two points anchoring the beginning and end of the
spring. Any additional points will be {\it via points}.

\begin{figure}[ht]
\begin{center}
  \begin{tabular}{cc}
    \iflatexml
       \includegraphics[width=3in]{images/cylinderWrapping}&
       \includegraphics[width=3in]{images/cylinderWrappingKnots}
    \else
       \includegraphics[width=2.5in]{images/cylinderWrapping}&
       \includegraphics[width=2.5in]{images/cylinderWrappingKnots}
    \fi
  \end{tabular}
\end{center}
\caption{A multipoint spring with two segments, separated by a blue
via point (top), with the rightmost segment set to be wrappable so
that it can wrap around a cylinder. The right image shows the
wrappable segment's knots.}
\label{cylinderWrappingKnots:fig}
\end{figure}

The section of a multipoint spring between any two adjacent points is
known as a {\it segment}. By default, each segment forms a straight
line between the two points and does {\it not} interact with any
wrappable obstacles. To interact with wrappables, a segment needs to
be declared {\it wrappable}, as described in
Section \ref{ObstacleWrapping:sec}.

Spring construction is illustrated by the following code fragment:
%
\begin{lstlisting}[]
   MultiPoint spring = new MultiPointSpring();
   spring.setMaterial (new LinearAxialMaterial (stiffness, damping));
   spring.addPoint (p0); // start point
   spring.addPoint (p1); // via point
   spring.addPoint (p2); // via point
   spring.addPoint (p3); // stop point
\end{lstlisting}
%
This creates a new {\tt MultiPointSpring} and sets its material to a
simple linear material with a specified stiffness and damping.  Four points
{\tt p0}, {\tt p1}, {\tt p2}, {\tt p3} are then added, forming a start
point, two via points, and a stop point.

\subsection{Example: a muscle with via points}
\label{ViaPointMuscle:sec}

\begin{figure}[t]
\begin{center}
\iflatexml
 \includegraphics[]{images/ViaPointMuscle}
\else
 \includegraphics[width=3.75in]{images/ViaPointMuscle}
\fi
\end{center}
\caption{ViaPointMuscle model loaded into ArtiSynth.}
\label{ViaPointMuscle:fig}
\end{figure}

A simple example of a muscle containing via points is given by
{\tt artisynth.demos.tutorial.ViaPointMuscle}.  It consists
of a MultiPointMuscle passing through two via points attached to a
block. The code is given below:
\lstset{numbers=left}
\lstinputlisting{../../src/artisynth/demos/tutorial/ViaPointMuscle.java}
\lstset{numbers=none}

Lines 21-30 of the {\tt build()} method create a {\tt MechModel} and
add a simple rigid body block to it. Two non-dynamic points ({\tt p0}
and {\tt p1}) are then created to act as muscle end points
(lines 33-38), along with two markers ({\tt via0} and {\tt via1})
which are attached to the block to act as via points
(lines 41-44). The muscle itself is created by lines 42-53, with the
end points and via points being added in order from start to end.
The muscle material is a
\javaclass[artisynth.core.materials]{SimpleAxialMuscle},
which computes tension according to the simple linear formula
(\ref{SimpleAxialMuscle:eqn}) described in Section
\ref{sec:mechii:musclematerials}. Lines 56-57 set render
properties for the model, and line 59 creates a control panel
(Section \ref{ControlPanels:sec}) that allows the muscle {\sf
excitation} property to be interactively controlled.

To run this example in ArtiSynth, select {\sf All demos > tutorial >
ViaPointMuscle} from the {\sf Models} menu. The model should load and
initially appear as in Figure \ref{ViaPointMuscle:fig}.  Running the
model will cause the block to fall and swing about under gravity,
while changing the muscle's {\sf excitation} in the control panel will
vary its tension.

\section{Obstacle Wrapping}
\label{ObstacleWrapping:sec}

As mentioned in Section \ref{ViaPoints:sec}, segments between pairs of
via points can be declared {\it wrappable}, allowing them to interact
with wrappable obstacles. This can be done as via points are added
to the spring, using the methods
%
\begin{lstlisting}[]
   void setSegmentWrappable (int numKnots)
   void setSegmentWrappable (int numKnots, Point3d[] initialPoints)
\end{lstlisting}
%
These make {\it wrappable} the next segment to be created (i.e., the segment
between the most recently added point and the next point to be added),
with {\tt numKnots} specifying the number of {\it knots} that should
be used to implement the wrapping. Knots are points that divide the
wrappable segment into a piecewise linear curve, and are used to
check for collisions with the wrapping surfaces
(Figure \ref{cylinderWrappingKnots:fig}).  The argument {\tt
initialPoints} used by the second method is an optional argument
which, if non-null, can be used to specify intermediate guide points
to give the segment an initial path around around any obstacles (for
more details, see Section \ref{wrappingInit:sec}).

Each wrappable segment will be capable of colliding with any of the
wrappable obstacles that are known to the spring.  Wrappables can be
added, queried and removed using the following methods:
%
\begin{lstlisting}[]
   void addWrappable (Wrappable wrappable)
   Wrappable getWrappable (int idx)
   int numWrappables()
   boolean removeWrappable (Wrappable wrappable)
\end{lstlisting}
%
Unlike points, however, there is no implied ordering and wrappables
can be added in any order and at any time during the spring's
construction.

Wrappable spring construction is illustrated by the following code
fragment:
%
\begin{lstlisting}[]
   MultiPoint spring = new MultiPointSpring();
   spring.setMaterial (new LinearAxialMaterial (stiffness, damping));
   spring.addPoint (p0); // start point
   spring.setSegmentWrappable (50);  // wrappable segment
   spring.addPoint (p1); // via point
   spring.addPoint (p2); // end point
   spring.addWrappable (wrappable1);
   spring.addWrappable (wrappable2);
   spring.updateWrapSegments(); // ``shrink wrap'' spring to the obstacles
\end{lstlisting}
%
This creates a new {\tt MultiPointSpring} with a linear material and
three points {\tt p0}, {\tt p1}, and {\tt p2}, forming a start point,
via point, and stop point.  The segment between {\tt p0} and {\tt p1}
is set to be wrappable with 50 knot points. Two wrappable obstacles
are added next, each of which will interact with the {\tt p0}-{\tt p1}
segment, but {\it not} with the non-wrappable {\tt p1}-{\tt p2}
segment. Finally, {\tt updateWrapSegments()} is called to do an
initial solve for the wrapping segments, so that they will be ``pulled
tight'' around any obstacles before simulation begins.

It is also possible to make a segment wrappable {\it after}
spring construction, using the method
%
\begin{lstlisting}[]
   void setSegmentWrappable (int segIdx, int numKnots, Point3d[] initialPoints)
\end{lstlisting}
%
where {\tt segIdx} identifies the segment between points ${\tt segIdx}$
and ${\tt segIdx}+1$.

How many knots should be specified for a wrappable segment? Enough so
that the resulting piecewise-linear approximation to the wrapping
curve is sufficiently "smooth", and also enough to adequately detect
contact with the obstacles without passing through them. Values
between 50 and 100 generally give good results. Obstacles that are
small with respect to the segment length may necessitate more
knots. Making the number of knots very large will slow down the
computation (although the computational cost is only $O(n)$ with
respect to the number of knots).

At the time of this writing, ArtiSynth implements two types of
\javaclass[\mech]{Wrappable} object, both of which are instances of
\javaclass[\mech]{RigidBody}. The first are specialized {\it analytic}
subclasses of {\tt RigidBody}, listed in Table
\ref{analyticWrappables:tbl}, which define specific geometries and use
analytic methods for the collision handling with the knot points.  The
use of analytic methods allows for greater accuracy and
(possibly) computational efficiency,
and so because of this, these special geometry
wrappables should be used whenever possible.

\begin{table}[h]
\centering
\begin{tabular}{ll}
   \hline
   \hline
   Wrappable & Description \\
   \hline
   \javaclass[\mech]{RigidCylinder} &
              A cylinder with a specified height and radius\\
   \javaclass[\mech]{RigidSphere} &
              A sphere with a specified radius \\
   \javaclass[\mech]{RigidEllipsoid} &
              An ellipsoid with specified semi-axis lengths\\
   \javaclass[\mech]{RigidTorus} &
              A torus with specified inner and outer radii\\
\hline
\end{tabular}
\caption{Specialized analytic subclasses of {\tt RigidBody}}
\label{analyticWrappables:tbl}
\end{table}

\begin{figure}[ht]
\begin{center}
\begin{tabular}{cc}
\iflatexml
 \includegraphics[]{images/HumerusWrap}&
 \includegraphics[]{images/HipWrap}
\else
 \includegraphics[width=2.5in]{images/HumerusWrap}&
 \includegraphics[width=2.5in]{images/HipWrap}
\fi
\end{tabular}
\end{center}
\caption{Muscle strands wrapped around general bone-shaped meshes: a
humerus (left), and a pelvis (right)}
\label{GeneralWrapping:fig}
\end{figure}

The second are general rigid bodies which are {\it not} analytic
subclasses, and for which the wrapping surface is determined directly
from the geometry of its collision mesh returned by
\javamethod[\mech.RigidBody]{getCollisionMesh()}.  (Typically the
collision mesh corresponds to the surface mesh, but it is possible to
specify alternates; see Section \ref{rigidBodyMultipleMeshes:sec}.)
This is useful in that it permits wrapping around {\it arbitrary} mesh
geometries (Figure \ref{GeneralWrapping:fig}), but in order for the
wrapping to work well, these geometries should be smooth, without
sharp edges or corners.  Wrapping around general meshes is implemented
using a quadratically interpolated signed-distance grid (Section
\ref{DistanceGrids:sec}), and the resolution of this grid also affects
the effective smoothness of the wrapping surface. More details on this
are given in Section \ref{GeneralSurfaceWrapping:sec}.

\subsection{Example: wrapping around a cylinder}
\label{CylinderWrapping:sec}

\begin{figure}[t]
\begin{center}
\iflatexml
 \includegraphics[]{images/CylinderWrappingStart}
\else
 \includegraphics[width=3.75in]{images/CylinderWrappingStart}
\fi
\end{center}
\caption{CylinderWrapping model loaded into ArtiSynth.}
\label{CylinderWrapping:fig}
\end{figure}

A example showing multipoint spring wrapping is given by {\tt
artisynth.demos.tutorial.CylinderWrapping}.  It consists of a
{\tt MultiPointSpring} passing through a single via point, with both
segments on either side of the point made wrappable. Two analytic
wrappables are used: a fixed {\tt RigidCylinder}, and a moving {\tt
RigidEllipsoid} attached to the end of the spring. The code, excluding
include directives, is given below:

\lstset{numbers=left}
\iflatexml
%% Hack: latexml lstinputlisting doesn't handle firstline correctly
\lstset{firstnumber={-15}}
\lstinputlisting[firstline=1]{../../src/artisynth/demos/tutorial/CylinderWrapping.java}
\lstset{firstnumber={1}}
\else
\lstinputlisting[firstline=17]{../../src/artisynth/demos/tutorial/CylinderWrapping.java}
\fi
\lstset{numbers=none}

Lines 4-17 of the {\tt build()} method create a {\tt MechModel} with
two fixed particles {\tt via0} and {\tt p1} to be used as via and stop
points. Next, two analytic wrappables are created: a {\tt
RigidCylinder} and a {\tt RigidEllipsoid}, with the former fixed in
place and the latter connected to the start of the spring via the
marker {\tt p0} (lines 20-37). Collisions are enabled between these
two wrappables at line 40. The spring itself is created (lines 44-52),
using {\tt setSegmentWrappable()} to make the segments ({\tt p0}, {\tt
via0}) and ({\tt via0}, {\tt p1}) wrappable with 50 knots each, and
{\tt addWrappable()} to make it aware of the two wrappables.  Finally,
render properties at set (lines 55-58), and a control panel (Section
\ref{ControlPanels:sec}) is added that allows the spring's {\sf
drawKnots} and {\sf drawABPoints} properties to be interactively set.

To run this example in ArtiSynth, select {\sf All demos > tutorial >
CylinderWrapping} from the {\sf Models} menu. The model should load and
initially appear as in Figure \ref{CylinderWrapping:fig}.  Running the
model will cause the ellipsoid to fall and the spring to wrap around
the cylinder. Using the pull tool
(Section ``Pull Manipulation'' in the
\artisynthManual{uiguide}{ArtiSynth User Interface Guide})
on the ellipsoid can cause additional motions and make it also collide
with the spring. Selecting {\sf drawKnots} or {\sf drawABPoints} in
the control panel will cause the spring to render its knots and/or A/B
points.

\section{General Surfaces and Distance Grids}
\label{GeneralSurfaceWrapping:sec}

As mentioned in Section \ref{ObstacleWrapping:sec}, wrapping around
general mesh geometries is implemented using a quadratically
interpolated signed distance grid. By default, for a rigid body, this
grid is generated automatically from the body's collision mesh (as
returned by {\tt getCollisionMesh()}; see Section
\ref{collisionMeshes:sec}).

Using a distance grid allows very efficient collision handling between
the body and the wrap segment knots. However, it also means that the
true wrapping surface is not actually the collision mesh itself, but
instead the zero-valued isosurface associated with quadratic grid
interpolation.  Well-behaved wrapping behavior requires that this
isosurface be smooth and free of sharp edges, so that knot motions
remain relatively smooth as they move across it. Quadratic
interpolation helps with this, which is the reason for employing
it. Otherwise, one should try to ensure that (a) the collision mesh
from which the grid is generated is itself smooth and free of sharp
edges, and (b) the grid has sufficient resolution to not introduce
discretization artifacts.

Muscle wrapping is often performed around structures such as bones,
for which the representing surface mesh is often insufficiently smooth
(especially if segmented from medical image data).  In some cases, the
distance grid's quadratic interpolation may provide sufficient
smoothing on its own; to determine this, one should examine the
quadratic isosurface as described below. In other cases, it may be
necessary to explicitly smooth the mesh itself, either externally or
within ArtiSynth using the \javaclass[\mgeo]{LaplacianSmoother} class,
which can apply iterations of either Laplacian or volume-preserving
Taubin smoothing, via the method
%
\begin{lstlisting}[]
  LaplacianSmoother.smooth (mesh, numi, lam, mu);
\end{lstlisting}
%
Here {\tt numi} is the number of iterations and {\tt tau} and {\tt mu}
are the Taubin parameters. Setting ${\tt lam} = 1$ and ${\tt mu} = 0$
results in traditional Laplacian smoothing. If this causes the mesh to
shrink more than desired, one can counter this by setting {\tt tau}
and {\tt mu} to values used for Taubin smoothing, as described in
\cite{taubin1995curve}.

\begin{sideblock}
If the mesh is large (i.e., has many vertices), then smoothing it may
take noticable computational time. In such cases, it is generally best
to simply save and reuse the smoothed mesh.
\end{sideblock}

By default, if a rigid body contains only one polygonal mesh, then its
surface and collision meshes (returned by
\javamethod[\mech.RigidBody]{getSurfaceMesh()} and
\javamethod[\mech.RigidBody]{getCollisionMesh()}, respectively) are
the same.  However, if it is necessary to significantly smooth or
modify the collision mesh, for wrapping or other purposes, it may be
desirable to use different meshes for the surface and collision. This
can be done by making the surface mesh non-collidable and adding an
additional mesh that {\it is} collidable, as discussed in Section
\ref{rigidBodyMultipleMeshes:sec} as illustrated by the following code
fragment:
%
\begin{lstlisting}[]
  PolygonalMesh surfaceMesh;
  PolygonalMesh wrappingMesh;

  // ... initialize surface and wrapping meshes ...

  // create the body from the surface mesh
  RigidBody body = RigidBody.createFromMesh (
      "body", mesh, /*density=*/1000, /*scale=*/1.0);

  // set the surface mesh to be non-collidable, and add the wrapping mesh as
  // collidable but not having mass
  body.getSurfaceMeshComp().setIsCollidable (false);
  RigidMeshComp wcomp = body.addMesh (
      wrappingMesh, /*hasMass=*/false, /*collidable=*/true);
  RenderProps.setVisible (wcomp, false); // hide the wrapping mesh
\end{lstlisting}
%
Here, to ensure that the wrapping mesh does {\it not} to contribute to
the body's inertia, its {\sf hasMass} property is set to false.

Although it is possible to specify a collision mesh that is separate
from the surface mesh, there is currently no way to specify {\it separate}
collision meshes for wrapping and collision handling.  If this is
desired for some reason, then one alternative is to create a separate
body for wrapping purposes, and then attach it to the main body, as
described in Section \ref{AlternateWrappingSurfaces:sec}.

To verify that the distance grid's quadratic isosurface is
sufficiently smooth for wrapping purposes, it is useful to visualize
the both distance grid and its isosurface directly, and if necessary
adjust the resolution used to generate the grid. This can be
accomplished using the body's
\javaclass[artisynth.core.mechmodels]{DistanceGridComp}, which is a
subcomponent named {\tt distanceGrid} and which may be obtained using
the method
%
\begin{lstlisting}
   DistanceGridComp getDistanceGridComp()
\end{lstlisting}
%
A {\tt DistanceGridComp} exports a number of properties that can be
used to control the grid's visualization, resolution, and fit around
the collision mesh. These properties are described in detail in
Section \ref{DistanceGrids:sec}, and can be set either in code using
their set/get accessors, or interactively using custom control panels
or by selecting the grid component in the GUI and choosing {\sf Edit
properties ...} from the right-click context menu.

\begin{sideblock}
When rendering the mesh isosurface, it is usually desirable to also
disable rendering of the collision meshes within the rigid body.  For
convenience, this can be accomplished by setting the body's {\sf
gridSurfaceRendering} property to {\tt true}, which will cause the
grid isosurface to be rendered {\it instead} of the body's meshes.
The isosurface type will be that indicated by the grid component's
{\sf surfaceType} property (which should be {\tt QUADRATIC} for the
quadratic isosurface), and the rendering will occur independently of
the visibility settings for the meshes or the grid component.
\end{sideblock}

\subsection{Example: wrapping around a bone}
\label{TalusWrapping:sec}

\begin{figure}[t]
\begin{center}
\begin{tabular}{cc}
\iflatexml
 \includegraphics[]{images/TalusWrapping}&
 \includegraphics[]{images/TalusWrapping2}
\else
 \includegraphics[width=3.2in]{images/TalusWrapping}&
 \includegraphics[width=3.2in]{images/TalusWrapping2}
\fi
\end{tabular}
\end{center}
\caption{TalusWrapping model, with a dragger being used to move {\tt
p0} (left), and the knots visible and grid visible with restricted
range (right).}
\label{TalusWrapping:fig}
\end{figure}

An example of wrapping around a general mesh is given by
{\tt artisynth.demos.tutorial.TalusWrapping}.  It consists
of a MultiPointSpring anchored by two via points and wrapped around a
rigid body representing a talus bone. The code, with include
directives omitted, is given below:
\lstset{numbers=left}
\iflatexml
%% Hack: latexml lstinputlisting doesn't handle firstline correctly
\lstset{firstnumber={-12}}
\lstinputlisting[firstline=1]{../../src/artisynth/demos/tutorial/TalusWrapping.java}
\lstset{firstnumber={1}}
\else
\lstinputlisting[firstline=14]{../../src/artisynth/demos/tutorial/TalusWrapping.java}
\fi
\lstset{numbers=none}

The mesh describing the talus bone is loaded from the file {\tt
"data/TalusBone.obj"} located beneath the model's source directory
(lines 11-19), with the utility class
\javaclass[maspack.util]{PathFinder} used to determine the file path
(Section \ref{PathFinder:sec}).
To ensure better wrapping behavior, the mesh is smoothed
using Laplacian smoothing (line 21) before being used to create
the rigid body (lines 23-27). The spring and its anchor points {\tt
p0} and {\tt p1} are created between lines 30-49, with the talus added
as a wrappable. The spring contains a single segment which is made
wrappable using 100 knots, and initialized with an intermediate point
(line 45) to ensure that it wraps around the bone in the correct way.
Intermediate points are described in more detail in Section
\ref{wrappingInit:sec}.

Render properties are set at lines 52-56; this includes turning off
rendering for grid normals by zeroing the {\sf lineWidth} render
property for the grid component.

Finally, lines 59-67 create a control panel (Section
\ref{ControlPanels:sec}) for interactively controlling a variety of
properties, including {\sf gridSurfaceRendering} for the talus (to see
the grid isosurface instead of the bone mesh), {\sf resolution}, {\sf
maxResolution}, {\sf renderGrid}, and {\sf renderRanges} for the grid
component (to control its resolution and visibility), and {\sf
drawKnots} and {\sf wrapDamping} for the spring (to make knots visible
and to adjust the wrap damping as described in Section
\ref{wrapTuning:sec}).

To run this example in ArtiSynth, select {\sf All demos > tutorial >
TalusWrapping} from the {\sf Models} menu. Since all of the dynamic
components are fixed, running the model will not cause any initial
motion. However, while simulating, one can use the viewer's graphical
dragger fixtures (see the section ``Transformer Tools'' in the
\artisynthManual{uiguide}{ArtiSynth User Interface Guide}) to move
{\tt p0} or {\tt p1} and hence pull the spring across the bone surface
(Figure \ref{TalusWrapping:fig}, left). One can also interactively
adjust the property settings in the control panel to view the grid,
isosurface, and knots, and the adjust the grid's resolution.  Figure
\ref{TalusWrapping:fig}, right, shows the model with {\sf renderGrid}
and {\sf drawKnots} set to {\tt true} and {\sf renderRanges} set to
{\tt "10:12 * *"}.

\section{Initializing the Wrap Path}
\label{wrappingInit:sec}

By default, when a multipoint spring or muscle is initialized (either
at the start of the simulation or as a result of calling
\javamethod*[\mech .MultiPointSpring]{updateWrapSegments()}), each
wrappable segment is initialized to a straight line between its via
points. This path is then adjusted to avoid and wrap around obstacles,
using artificial linear forces as described in Section
\ref{wrapTuning:sec}. The result is a local shortest path that wraps
around obstacles instead of penetrating them.  However, in some cases,
the initial path may not be the one desired; instead, one may want it
to wrap around obstacles some other way. This can be achieved by
specifying additional intermediate points to initialize the segment as
a piecewise linear path which threads its way around obstacles in the
desired manner (Figure \ref{wrapInitialization:fig}).  These are
specified using the optional {\tt initialPnts} argument to the {\tt
setSegmentWrappable()} methods.

\begin{figure}[ht]
\begin{center}
 \includegraphics[width=6in]{images/wrapInitialization}
\end{center}
\caption{By default, the path for each wrappable segment is
initialized to a straight line between its via points (dotted line,
left), which is then adjusted to wrap around obstacles (solid line,
middle). To cause the path to wrap around obstacles in a different
way, it can instead be initialized using a piecewise-linear
path defined by intermediate initial points (dotted line, right),
which will then adjust to an alternate configuration.}
\label{wrapInitialization:fig}
\end{figure}

\begin{sideblock}
When initial points are specified, it is recommended to finish
construction of the spring or muscle with a call to
\javamethod[\mech.MultiPointSpring]{updateWrapSegments()}.  This fits
the wrappable segments to their correct path around the obstacles,
which can then be seen immediately when the model is first loaded. On
the other hand, by {\it omitting} an initial call to {\tt
updateWrapSegments()}, it is possible to see the initial path as
specified by the initial points. This may be useful to
verify that they are in the correct locations.
\end{sideblock}

\begin{sideblock}
In some cases, initial points may also be necessary to help ensure
that the initial path does not penetrate obstacles. While obstacle
penetration will normally be resolved by the artificial forces
described in Section \ref{wrapTuning:sec}, this may not always work
correctly if the starting path penetrates an obstacle too deeply.
\end{sideblock}

\subsection{Example: wrapping around a torus}
\label{TorusWrapping:sec}

\begin{figure}[ht]
\begin{center}
\iflatexml
 \includegraphics[]{images/TorusWrapping}
\else
 \includegraphics[width=3.75in]{images/TorusWrapping}
\fi
\end{center}
\caption{{\tt TorusWrapping} model loaded into ArtiSynth.}
\label{TorusWrapping:fig}
\end{figure}

An example of using initial points is given by {\tt
artisynth.demos.tutorial.TorusWrapping}, in which a spring
is wrapped completely around the inner section of a torus.
The primary code for
the build method is given below:
\lstset{numbers=left}
\iflatexml
%% Hack: latexml lstinputlisting doesn't handle firstline correctly
\lstset{firstnumber={-20}}
\lstinputlisting[firstline=1,lastline=41]{../../src/artisynth/demos/tutorial/TorusWrapping.java}
\lstset{firstnumber={1}}
\else
\lstinputlisting[firstline=22,lastline=62]{../../src/artisynth/demos/tutorial/TorusWrapping.java}
\fi
\lstset{numbers=none}

The mech model is created in the usual way with frame and rotary
damping set to 1 and 10 (lines 4-5). The torus is created using the
analytic wrappable \javaclass[\mech]{RigidTorus} (lines 8-14). The
spring start and end points {\tt p0} and {\tt p1} are created at lines
(17-22), and the spring itself is created at lines (26-41), with six
initial points being specified to {\tt setSegmentWrappable()} to wrap
the spring completely around the torus inner section.

To run this example in ArtiSynth, select {\sf All demos > tutorial >
TorusWrapping} from the {\sf Models} menu. The torus will slide along
the wrapped spring until it reaches equilibrium.

\section{Alternate Wrapping Surfaces}
\label{AlternateWrappingSurfaces:sec}

Although it common to use the general mesh geometry of a {\tt
RigidBody} as the wrapping surface, situations may arise where it is
desirable to {\it not} do this. These may include:

\begin{itemize}

\item The general mesh geometry is not sufficiently smooth
to form a good wrapping surface;

\item Wrapping around the default mesh geometry is not stable, in
that it is too easy for the wrap strand to ``slip off'';

\item Using one of the simpler analytic geometries
(Table \ref{analyticWrappables:tbl}) may result in a more efficient
computation.

\end{itemize}

There are a couple of ways to handle this. One, discussed in Section
\ref{GeneralSurfaceWrapping:sec}, involves creating a collision mesh
which is separate from the general mesh geometry. However, that same
collision mesh must then also be used for collision handling (Section
\ref{sec:mechii:collisions}). If that is undesirable, or if {\it
multiple} wrapping surfaces are needed, then a different approach may
be used. This involves creating the desired wrappable as a separate
object and then {\it attaching} it to the main {\tt
RigidBody}. Typically, this wrappable will be created with zero mass
(or density), so that it does not alter the effective mass or inertia
of the main body. The general procedure then becomes:

\begin{enumerate}

\item Create the main {\tt RigidBody} with whatever desired geometry
and inertia is needed;

\item Create the additional wrappable object(s), usually
with zero density/mass;

\item Attach the wrappables to the main body using
one of the {\tt MechModel} {\tt attachFrame()} methods described in
Section \ref{sec:mech:frameattachments}.

\end{enumerate}

\subsection{Example: wrapping for a finger joint}
\label{PhalanxWrapping:sec}

\begin{figure}[t]
\begin{center}
\iflatexml
 \includegraphics[]{images/PhalanxWrapping}
\else
 \includegraphics[width=3.75in]{images/PhalanxWrapping}
\fi
\end{center}
\caption{PhalanxWrapping model loaded into ArtiSynth.}
\label{PhalanxWrapping:fig}
\end{figure}

An example using an alternate wrapping surface is given by {\tt
artisynth.demos.tutorial.PhalanxWrapping}, which shows a
a muscle wrapping around a joint between two finger
bones. Because the bones themselves are fairly narrow, using them as
wrapping surfaces would likely lead to the muscle slipping
off. Instead, a \javaclass[\mech]{RigidCylinder} is used for the
wrapping and attached to one of the bones. The code, with include
directives excluded, is given below: \lstset{numbers=left} \iflatexml
%% Hack: latexml lstinputlisting doesn't handle firstline correctly
\lstset{firstnumber={-10}}
\lstinputlisting[firstline=1]{../../src/artisynth/demos/tutorial/PhalanxWrapping.java}
\lstset{firstnumber={1}}
\else
\lstinputlisting[firstline=12]{../../src/artisynth/demos/tutorial/PhalanxWrapping.java}
\fi
\lstset{numbers=none}

The method {\tt createBody()} (lines 6-14) creates a rigid body from a
geometry mesh stored in a file in the directory ``{\tt data}'' beneath
the source directory, using the utility class
\javaclass[maspack.util]{PathFinder} used to determine the file path
(Section \ref{PathFinder:sec}).

Within the {\tt build()} method, a {\tt MechModel} is created
containing two rigid bodies representing the bones, {\tt proximal} and
{\tt middle}, with {\tt proximal} fixed and {\tt middle} free to move
with a frame damping of 0.03 (lines 18-28). A cylindrical joint is
then added between the bones, along with markers describing the
muscle's origin and insertion points (lines 31-42).  A {\tt
RigidCylinder} is created to act as a wrapping obstacle and attached
to the {\tt middle} bone in the same location as the joint (lines
46-50); since it is created with a density of 0 it has no mass and
hence does not affect the bone's inertia. The muscle itself is created
at lines 53-64, using a
\javaclass[artisynth.core.materials]{SimpleAxialMuscle} as a material
and an extra initial point specified to
{\tt setSegmentWrappable()} to ensure that it wraps around
the cylinder in the correct way (Section
\ref{wrappingInit:sec}). Finally, render properties are set at lines
67-69.

To run this example in ArtiSynth, select {\sf All demos > tutorial >
PhalanxWrapping} from the {\sf Models} menu. The model should load and
initially appear as in Figure \ref{PhalanxWrapping:fig}.  When running
the model, one can move the {\tt middle} bone either
by using the pull tool (Section ``Pull
Manipulation'' in the
\artisynthManual{uiguide}{ArtiSynth User Interface Guide}),
or selecting the muscle in the GUI, invoking a property dialog by
choosing {\sf Edit properties ...} from the right-click context menu,
and adjusting the {\sf excitation} property.

\section{Tuning the Wrapping Behavior}
\label{wrapTuning:sec}

Wrappable segments are implemented internally using artificial linear
elastic forces to draw the knots together and keep them from
penetrating obstacles. These artificial forces are invisible to the
simulation: the wrapping segment has no mass, and the knot forces are
used to create what is essentially a first order physics that ``shrink
wraps'' each segment around the obstacles at the beginning of each
simulation step, forming a shortest-distance geodesic curve from
which the wrapping contact points A and B are calculated. This process
is now described in more detail.

Assume that a wrappable segment has $m$ knots, indexed by $k =
1, \ldots, m$, each located at a position $\x_k$. Two types of
artificial forces then act on each knot: a {\it wrapping force}
that pulls it closer to other knots, and {\it contact forces} that
push it away from wrappable obstacles. The wrapping force is given by
%
\begin{equation*}
\f_{w,k} = K_w (\x_{k+1} - 2 \x_k + \x_{k-1})
%\label{knotForce:eqn}
\end{equation*}
%
where $K_w$ is the {\it wrapping stiffness}. To determine the contact
forces, we compute, for each wrappable, the knot's distance to the
surface $d_k$ and associated normal direction $\n_k$, where $d_k < 0$
implies that the knot is inside. These quantities are determined
either analytically (for analytic wrappables, Table
\ref{analyticWrappables:tbl}), or using a signed distance grid (for
general wrappables, Section \ref{GeneralSurfaceWrapping:sec}).  The
contact forces are then given by
%
\begin{equation*}
\f_{c,k} =
\begin{cases}
-K_c \, d_k \, \n_k & \text{if} \; d_k < 0 \\
0 & \text{otherwise},
\end{cases}
%\label{contactForce:eqn}
\end{equation*}
%
where $K_c$ is the {\it contact stiffness}.

The total force $\f_k$ acting on each knot is then given by
%
\begin{equation*}
\f_k = \f_{w,k} + \sum_c \f_{c,k}
%\label{XXX:eqn}
\end{equation*}
%
where the latter term is the sum of contact forces for all wrappables.
If we let $\x$ and $\f$ denote the aggregate position and force vectors
for all knots, then computing the wrap path involves finding the
equilibrium position such that $\f(\x) = 0$. This is done at the
beginning of each simulation step, or whenever \javamethod*[\mech
.MultiPointSpring]{updateWrapSegments()} is called, and
is achieved iteratively using Newton's method.
If $\x^j$ and $\f(\x^j)$ denote the positions and forces at iteration $j$,
and
%
\begin{equation*}
\K \equiv \frac{\partial \f}{\partial \x}
\end{equation*}
%
denotes the local force derivative (or ``stiffness''), then the basic
Newton update is given by
%
\begin{equation*}
\x^{j+1} = \x^j - \K^{-1} \f(\x^j).
\label{NewtonSolve:eqn}
\end{equation*}
%
In practice, to help deal with the nonlinearities associated with
contact, we use a damped Newton update,
%
\begin{equation}
\x^{j+1} = \x^j + \alpha (D \I - \K)^{-1} \f(\x^j),
\label{DampedNewtonSolve:eqn}
\end{equation}
%
where $D$ is a constant {\it wrap damping} parameter, and $\alpha$ is
an adaptively computed step size adjustment. The computation of
(\ref{DampedNewtonSolve:eqn}) can be performed quickly, in $O(m)$
time, since $\K$ is a block-tridiagonal matrix, and the number of
iterations required is typically small (on the order of 10 or less),
particularly since the iterative procedure continues across simulation
steps and so $\f(\x)$ does not need to be brought to $0$ for any given
step. The maximum number of Newton iterations used for each
time step is $N_\text{max}$.

\begin{sideblock}
Again, it is important to understand the artificial knot forces
$\f(\x)$ described here are separate from the physical spring/muscle
tension forces $f(l,\dot l, a)$ discussed in Sections
\ref{AxialSprings:sec} and \ref{sec:mechii:musclematerials}, and {\it
only} facilitate the computation of each wrappable segment's path
around obstacles.
\end{sideblock}

The default values for the wrapping parameters are $K_w = 1$, $K_c =
10$, $D = 10$, and $N_\text{max} = 10$, and these often give
satisfactory results without the need for modification.  However, in
some situations the default muscle wrapping may not perform adequately
and it is necessary to adjust these parameters. Problems may include:

\begin{itemize}

\item The wrapping path does not settle down and tends to ``jump
around''.  Solutions include increasing the damping parameter $D$ or
the maximum number of wrap iterations $N_i$. For general wrapping
surfaces (Section \ref{GeneralSurfaceWrapping:sec}), one should also
ensure that the surface is sufficiently smooth.

\item A wrapping surface is too thin and so the wrapping
path ``jumps through'' it. Solutions include increasing the damping
parameter $D$, increasing the number of knots in the segment, or
decreasing the simulation step size. An alternative approach is to use
an alternative wrapping surface
(Section \ref{AlternateWrappingSurfaces:sec}) that is thicker and
better behaved.

\end{itemize}

Wrapping parameters are exported as properties of {\tt
MultiPointSpring} and {\tt MultiPointMuscle}, and may be changed in
code (using their set/get accessors), or interactively,
either by exposing them through a control panel,
or by selecting the spring/muscle in the GUI and choosing {\sf Edit
properties ...} from the right-click context menu.  Property values
include:

\begin{description}

\item[wrapStiffness] Wrapping stiffness $K_w$ between knot points
(default value 1). Since the wrapping behavior is determined by the
damping to stiffness {\it ratio}, it is generally not necessary to
change this value.

\item[wrapDamping] Damping factor $D$ (default
value 10). Increasing this value relative to $K_w$ results in wrap
path motions that are smoother and less likely to penetrate obstacles,
but which are also less dynamically responsive. Applications generally
work with damping values between 10 and 100 (assuming $K_w = 1$).

\item[contactStiffness] Contact stiffness $K_c$ used to resolve obstacle
penetration (default value 10). It is generally not necessary
to change this value. Decreasing it will increase the distance that
knots are permitted to penetrate obstacles, which {\it may} result in
a slightly more stable contact behavior.

\item[maxWrapIterations] Maximum number of Newton iterations
$N_\text{max}$ per time step (default value 10). If the wrapping
simulation exhibits instability, particularly with regard to obstacle
contact, increasing the number of iterations (to say 100) may help.

\end{description}

In addition, {\tt MultiPointSpring} and {\tt MultiPointMuscle} also
export the following properties to control the rendering of knot and
A/B points:

\begin{description}

\item[drawKnots] If true, renders the knot points in each wrappable segment.
This can be useful to visualize the knot density. Knots are rendered
using the style, size, and color given by the {\sf pointStyle},
{\sf pointRadius}, {\sf pointSize}, and {\sf pointColor} values of the
spring/muscle's render properties.

\item[drawABPoints] If true, renders the A/B points. These
are the first and last points of contact that a wrap segment makes
with each wrappable, and correspond to the
points where the spring/muscle's tension acts on that wrappable
(Section \ref{multipointSpringIntro:sec} and
Figure \ref{multiPointObstacle:fig}).  A/B points are rendered using
the style and size given by the {\sf pointStyle}, {\sf pointRadius}
($\times 1.2$) and {\sf pointSize} values of the spring/muscle's render
properties, and the color given by the {\sf ABPointColor} property.

\end{description}