\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amssymb}
\usepackage{hyperref}

\newcommand{\func}[1]{\mathsf{#1}}

\title{Haven Protocol code notes}
\author{Cypher Stack\thanks{\url{https://cypherstack.com}}}
\date{\today}

\begin{document}

\maketitle

\section{Introduction}

This document describes technical information relevant to Haven Protocol.
It reflects a snapshot of the codebase repository\footnote{\url{https://github.com/haven-protocol-org/haven-main/tree/v2.0.0-rc3}}, but its findings and observations may be superseded by later changes.
As with any code review, this analysis is limited and cannot capture all use cases or unintended behaviors of the codebase in all circumstances; it reflects a best-effort approach of the author to determine the extent to which relevant portions of the codebase reflect verification operations in the transaction protocol description\footnote{\url{https://github.com/cypherstack/haven-protocol-review/releases/tag/final}} approved by its designers.
It does not specifically address the scope of best-practice secure C\texttt{++} design principles, for which the authors recommend further detailed review.
The author asserts no warranty and disclaims liability for its use.
The author further expresses no endorsement of Haven Protocol or its associated entities.

\section{Structure}

In this section, we describe the structural similarities and differences between the protocol description and its implementation.

\subsection{Transaction types}

The protocol description describes two types of transactions: \textit{transfer} and \textit{conversion}.
Transfer transactions consume and generate assets of a single type, where balance is asserted if the combined value of spent inputs is equal to the combined value of generated outputs.
Conversion transactions consume assets of a single type, and generate assets of the consumed type and a single additional type.
In this case, balance is asserted if the combined value of spent input inputs is equal to the combined value of generated outputs after applying a scaling factor produced by a pricing oracle.

The protocol description requires that transfer transactions generate at least two outputs, which mitigates analysis based on knowledge of commitment masks or values.
It requires that conversion transactions generate at least one output of each of the two required types, but discussions with the designers indicate the intent is to require at least two source- and destination-type generated outputs.

The implementation differs from the protocol in further delineating transaction types based on specific asset types.
Transaction types are defined in \texttt{cryptonote::transaction\_type}, and are inferred from given source and destination strings in \texttt{cryptonote::get\_tx\_type}:
\begin{itemize}
	\item \texttt{UNSET}: no type has been specified
	\item \texttt{TRANSFER}: source and destination types are both \texttt{XHV}
	\item \texttt{OFFSHORE\_TRANSFER}: source and destination types are both \texttt{XUSD}
	\item \texttt{XASSET\_TRANSFER}: source and destination types are the same, but neither \texttt{XHV} nor \texttt{XUSD}
	\item \texttt{OFFSHORE}: source type is \texttt{XHV} and destination type is \texttt{XUSD}
	\item \texttt{ONSHORE}: source type is \texttt{XUSD} and destination type is \texttt{XHV}
	\item \texttt{XUSD\_TO\_XASSET}: source type is \texttt{XUSD} and destination type is neither \texttt{XHV} nor \texttt{XUSD}
	\item \texttt{XASSET\_TO\_XUSD}: source type is neither \texttt{XHV} nor \texttt{XUSD}, and destination type is \texttt{XUSD}
\end{itemize}
Any other combination of source and destination strings is rejected.

\subsection{Asset types}

Source and destination asset type strings for a transaction are established in \texttt{cryptonote::get\_tx\_asset\_types}, where protocol consistency rules are applied based on the structure of consumed and generated transaction outputs:
\begin{enumerate}
	\item The transaction must consume only a single asset type, which is defined to be the source asset type.
	\item If the transaction is a miner transaction, the destination asset type is defined to be the base \texttt{HXV} asset type, and no source transaction type is specifically defined.
	\item If the transaction is not a miner transaction and generates a single asset type, it must match the source asset type and is defined to be the destination asset type.
	\item If the transaction is not a miner transaction and generates two asset types, exactly one of them must match the source asset type; both are defined to be the destination asset types.
	\item If the transaction is not a miner transaction, it may not generate outputs of more than two asset types.
	\item All source and destination asset types must belong to the static list defined in \texttt{offshore:ASSET\_TYPES}.
\end{enumerate}
These rules differ from the protocol description.
Miner transactions, which are part of the parent transaction protocol, are not specifically defined in the scoped transaction protocol, but are restricted in implementation to the base asset; notably, miner transaction output types are not checked in this function to be of the base asset type; the destination asset type is set manually.
Source and destination types default to an empty string, which is not specifically defined as either an asset type nor an indicated error condition.

\subsection{Transfer transaction balance}

The balance logic for transfer transactions of the types \texttt{OFFSHORE\_TRANSFER}, \texttt{TRANSFER}, and \texttt{XASSET\_TRANSFER} is established and checked in the function \texttt{rct::verRctSemanticsSimple2}.
This function assumes prior establishment of source and destination asset type strings, which are checked against the static list of valid types.
In the case of transfer transactions, the source and destination type are identical.
The function is intended to process transfer and conversion transactions, and so we must ensure that the common logic applies to the specific protocol requirements of transfer transactions.
Using the notation of the protocol description, the following is computed and checked:
$$\sum_{u=0}^{w-1} C_u' - \func{Com}(f,0) - \func{Com}(f',0) - \sum_{j=0}^{t-1} \overline{C}_j = 0$$
Here $f$ is the transaction fee and $f'$ is the \textit{offshore fee} as noted in code comments.
The offshore fee is not captured by the protocol description, but is handled in the same manner as the transaction fee.
Transactions of type \texttt{TRANSFER} have the logic applied as the result of a default condition of a conditional block that checks against possible types; if another transaction type were presented that was not of the types in this block, it would evaluate using the transfer logic.

\subsection{Conversion transaction balance}

The balance logic for conversion transactions of the types \texttt{OFFSHORE}, \texttt{ONSHORE}, \texttt{XUSD\_TO\_XASSET}, and \texttt{XASSET\_TO\_XUSD} is also established and checked in the same function.
In these cases, the source and destination asset type strings are different, but checked against the static list of valid types.
Using the notation of the protocol description, the following is computed and checked:
$$\sum_{u=0}^{w-1} C_u' - \func{Com}(f,0) - \func{Com}(f',0) - \sum_{j=0}^{n_T-1} \overline{C}_j - \frac{1}{r} \sum_{n_T}^{t-1} \overline{C}_j = 0$$
Here, the value of $r$ is scaled by an atomic unit factor $\texttt{COIN}$ depending on whether \texttt{XUSD} is a source or destination asset type.
As with transfer transactions, the offshore fee is not captured by the protocol description.
Further, atomic unit conversions to and from \texttt{XUSD} type are not captured by the protocol description.

\subsection{Burn amount verification}

The conversion burn amount verification check required by the protocol also takes place in \texttt{rct::verRctSemanticsSimple2}.
This is intended to confirm a plaintext amount sum for the source asset type corresponds validly to the associated commitments presented in the transaction.
According to the protocol description, this is asserted by the following check:
$$\sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{n_T-1} \overline{C}_j - \func{Com}(f,0) - \func{Com}(0,a_T - \overline{a}_T) - \func{Com}(y_T,0) = 0$$
The check performed in the implementation differs in its commitment construction, performing this check:
$$\sum_{u=0}^{w-1} C_u' - \sum_{j=0}^{n_T-1} \overline{C}_j + \func{Com}(0,\overline{a}_T) = \func{Com}(y_T - f'',a_T) = 0$$
Here $f''$ is defined in the code as a scaled \textit{burn fee} computed from the offshore fee, which is not captured by the protocol description.
Note that while the commitments constructed in the implementation differ from the construction method in the protocol, they are algebraically equivalent (aside from the burn fee).

\subsection{Mint amount verification}

The conversion mint amount verification check required by the protocol takes place in the function \texttt{rct::checkBurntAndMinted}, which is called from the function \texttt{tx\_memory\_pool::add\_tx2}.
This is intended to check a claimed plaintext amount sum for the destination asset type.
As noted in the protocol description, this is not checked against commitments presented in the transaction.
It appears that a user generating such a transaction could simply provide a plaintext minted amount sum satisfying the check without any particular correspondence to commitments; however, we argue in the protocol description that security is not reduced by removing this check altogether.
The verifier can produce the value on its own if needed, and avoid relying on the value provided in the transaction.

\subsection{Linkable ring signature}

Both transfer and conversion transactions require a linkable ring signature on each consumed source asset.
The protocol description assumes the use of CLSAG signatures for this use.
The implementation uses the CLSAG implementation from its parent codebase, where verification of signatures is performed within \texttt{rct::verRctCLSAGSimple}, which binds an arbitrary message into the signature.
The implementation of \texttt{rct::verRctCLSAGSimple} appears to be correctly ported from the parent codebase.
While the protocol description does not specify the format of the message bound to each CLSAG signature, it should be checked that this message includes any replay-specific mitigations relevant to transactions that may differ from the parent codebase.

\subsection{Range proofs}

Generated outputs in both transfer and conversion transactions require one or more range proofs to assert committed values are within a protocol-specified range.
The protocol description assumes the use of the Bulletproofs range proving system for this use.
The implementation uses the Bulletproofs implementation from its parent codebase, where verification of aggregated proofs is performed within \texttt{rct::verBulletproof}.
The implementation of the verification wrapper \texttt{rct::verBulletproof} (and its underlying direct verification function) appears to be correct as unchanged from its parent repository.
Atomic unit conversion is not performed prior to range proof verification, as this is done for balance purposes separately.

\section{Observations}

In this section, we describe findings and observations within the Haven Protocol codebase relevant to verification in the transaction protocol, and note possible suggestions for improvement where appropriate.

\subsection{Pricing oracles}

The protocol relies heavily on a single pricing oracle that is assumed to securely provide responses to queries for asset conversion rates.
No checks are assumed to be made about the consistency of its responses.
The implementation relies on a set of hardcoded oracles \texttt{config::ORACLE\_URLS} defined for the live network and test networks; for each network, the oracles share a single verification public key.

Oracle queries are performed in \texttt{Blockchain::get\_pricing\_record}.
This function shuffles the oracle list (presumably for load balancing reasons), and then queries the shuffled list until a response is returned.
The query includes a network version flag and encoded block timestamp.
On receipt of a response, the function verifies a response signature against the hardcoded public key.
If verification fails or no response is received from any oracle, an empty response is constructed that instantiates with zero values.
The result is used to populate a pricing record on each supported asset type.

The oracle implementation currently deployed returns JSON data consisting of asset types with integer-valued conversion rates, a timestamp, an encoded signature, and unused auxiliary data.
To verify the signature, a JSON string is reconstructed with all asset types, corresponding conversion rates, and timestamp (if nonzero).
Signature values are decoded using a method that is not documented.
The algorithm used to verify the signature is not made explicit, as it appears to be inferred from the encoded public key.
Based on limited comments in the code, it may be ECDSA, but this is not confirmed.

All hardcoded mainnet oracles accept HTTPS queries on port 443, reject HTTP queries on port 80, and reject HTTP queries on port 443.
Oracles are hardcoded by domain and not IP, appear to defer to the user's chosen DNS provider for IP resolution, and appear to defer to the user's local certificate authority for server authentication.

\subsection{Pricing record inversion}

In balance computation, pricing record values are converted to scalar field elements and may be multiplicatively inverted.
The inversion algorithm is only guaranteed to succeed on nonzero input; there is a check within the \texttt{invert} function that will fail on zero input, but it only runs on the presence of a debugging flag.
The pricing record values in balance computation are not tested within \texttt{verRctSemanticsSimple2} to assert they are nonzero.
Pricing oracle queries may return zero values, or the entire query may fail and result in a zero-default pricing record instantiation.
There exists a check in \texttt{tx\_memory\_pool::add\_tx2} against zero-value specific entries within pricing records.
A safer additional guard is to enable the inversion check on production builds; the operation is extremely efficient, and is the most direct guarantee that the algorithm succeeded.
Another safe option is to test input scalars to the inversion function to assert they are nonero; this check would also be extremely efficient.

\subsection{Common key type}
\label{obs:common-key-type}

The codebase, like that of its upstream parent, uses a single byte array type \texttt{rct::key} to represent two underlying mathematical types: elliptic curve group elements and elements of this group's scalar field.
Both element types have canonical 32-byte representations, but they are not directly algebraically compatible.
A comprehensive codebase update might use separate byte array types for curve group and scalar elements in order to reduce confusion and the likelihood of errors in algorithm design or implementation; however, this common type is widely used throughout the implementation, implying risk in such a wide-ranging change that would need to be carefully considered.

\subsection{Inconsistent key initialization}
\label{obs:key-initialization}

Related to Observation \ref{obs:common-key-type}, group and scalar elements are occasionally initialized inconsistently.
The zero scalar is defined using the \texttt{rct::zero()} function, which returns a constant byte array \texttt{(0x00,...,0x00)} as its canonical byte representation.
The zero (identity) group element is defined using the \texttt{rct::identity()} function, which returns as its canonical byte representation a constant byte array \texttt{(0x01,0x00,...,0x00)}.
However, several locations in \texttt{rctSigs.cpp} initialize group elements unexpectedly using \texttt{rct::zero()} or \texttt{memwipe}, which could have unintended behavior if these values are not later set directly or by appropriate function calls to other algorithms or operations.

Examples of this behavior include:
\begin{itemize}
	\item \texttt{rctSigs.cpp}, lines 933-935
	\item \texttt{rctSigs.cpp}, line 1328
	\item \texttt{rctSigs.cpp}, line 1584
\end{itemize}
Relying on later function calls or algorithms to reset group elements to another value is not robust, and may lead to unsafe results.
Care should be taken to initialize group and scalar elements correctly when using \texttt{rct::key}, as it is not always obvious from context which element type is intended.

\subsection{Inconsistent asserts}
\label{obs:asserts}

Low-level balance verification in \texttt{verRctSemanticsSimple2} performs computations on input and output data based on transaction and asset types discussed previously.
For this reason, it is essential that these types are valid and consistent.
The asserts contained in the low-level balance verification check that source and destination asset types are valid by their inclusion in \texttt{offshore::ASSET\_TYPES}.
Later, the balance computation sorts outputs by asset type, and then uses the transaction type to complete the computation.
However, this does not account for the required consistency between output asset types, source and destination asset type strings, and transaction type provided as function arguments.
Rather, these consistency checks are offloaded.
For this reason, the inclusion of one consistency check for valid source and destination asset type strings appears inconsistent, as it is also performed prior to the function being called.
It may be useful to standardize the validity and consistency checks between transaction types and asset types to improve reliability and efficiency, and reduce the possibility of error.
In particular, if these validity checks are not intended to be used in other parts of the protocol, it may be safest to call them directly from \texttt{verRctSemanticsSimple2} (to ensure they are run whenever this verification takes place), or to document carefully the requirements and assumptions on the function arguments.

\subsection{Underspecified transaction type check}
\label{obs:transaction-type-check}

When performing the balance check in \texttt{verRctSemanticsSimple2}, the transaction type is crucially used to identify the scaling and outputs to be used in the calculation.
This is done by building the sum-to-zero element \texttt{Zi} in a way that is dependent on the transaction type.
Generic \texttt{TRANSFER} transactions are not specifically checked by the conditional in balance verification, instead being the result of a default condition.

While this does not pose a problem if possible valid transaction types are not added, it would be safest to reject transactions not meeting the expected type, as there may be unintended behavior resulting from attempting to complete the computation and balance validity check on an unexpected transaction type.

\subsection{Unnecessary identity computations}

As noted in Observation \ref{obs:key-initialization}, the elliptic curve group identity element can be obtained via a call to \texttt{rct::identity()}, which returns a constant byte array consisting of the canonical representation of this element.

In several locations in \texttt{rctSigs.cpp}, the identity group element is computed by computing the scalar-group multiplication \texttt{scalarmultH(d2h(0))}, which is unnecessary and less efficient.

Examples of this behavior include:
\begin{itemize}
	\item \texttt{rctSigs.cpp}, line 1327
	\item \texttt{rctSigs.cpp}, line 1583
	\item \texttt{rctSigs.cpp}, line 1866
	\item \texttt{rctSigs.cpp}, line 1869
	\item \texttt{rctSigs.cpp}, line 1870
	\item \texttt{rctSigs.cpp}, line 1871
\end{itemize}
All such function calls can safely be replaced with \texttt{rct::identity()} calls for clarity and speed.

\subsection{Fee ranges}

The protocol description requires that fees be checked to lie within a protocol-specified range.
Because fees are presented in the clear, they do not come equipped with range proofs.
However, fees are used in the verification function \texttt{verRctSemanticsSimple2} to produce commitments that may overflow the balance check if not asserted to be within the required range.
All fees, including those outside of the scope of the protocol description, should be carefully checked to ensure they cannot overflow the balance check.
One way to ensure this is by suitable truncation encoding that is properly re-encoded to a scalar value for commitment computation.

\subsection{Undocumented signature verification}

As noted previously, pricing oracle responses come equipped with a signature that is verified prior to acceptance using \texttt{pricing\_record::verifySignature}.
However, the details of this verification process are not clearly documented.

In particular, the signature algorithm intended to be used for the public key appears to be inferred from the key type, which is not specified in the code.
Second, a comment indicates that the decoded signature is reformatted to match an OpenSSL format, but the details of the formatting operation are unclear, so it is not possible to properly assess.
Finally, the verification algorithm is unspecified at the time of verification (related, presumably, to the key type as noted above).

Because price oracle response validity is crucial to the safe operation of the protocol, the methods used to verify oracle signatures should be clearly documented.

A separate option (if reliance on OpenSSL functionality is not desired) may be to use a Schnorr signature on the oracle response, which could take advantage of structures and functions already present in the codebase, including those for deseralizing keys and signatures.
However, this change could introduce additional implementation risk and complexity.

\end{document}


\section{Free Energy of Conformational Change Calculations}
\label{section:fenergy}

\NAMD\ incorporates methods for performing free energy of conformational change perturbation calculations.
The system is efficient if only a few coordinates, either of individual atoms or centers of mass of groups of atoms, are needed.
The following configuration parameters are used to enable free energy perturbation:

\begin{itemize}

\item
\NAMDCONFWDEF{freeEnergy}{is free energy perturbation active?}{{\tt on} or {\tt off}}{{\tt off}}
{Specifies whether or not free energy perturbation is active.  If it
is set to {\tt off}, then no free energy perturbation is performed.
If it is set to {\tt on}, then the free energy perturbation calculation specified in
{\tt freeEnergyConfig} parameters is executed.}

\item
\NAMDCONF{freeEnergyConfig}{free energy perturbation script}{file or \{script\}}
{Must contain either the name of a free energy perturbation script file or the script
itself between \{ and \} (may include multiple lines).
This parameter may occur multiple times and scripts will be executed
in order of appearance.
The format of the free energy perturbation script is described below.
}

\end{itemize}

The following sections describe the format of the free energy perturbation script.

% Free energy perturbation parameters
% Free energy perturbation parameters, included into usage description

\subsection{User-Supplied Conformational Restraints}

These restraints extend the scope of the available restraints beyond that
provided by the harmonic position restraints. Each restraint is imposed with
a potential energy term, whose form depends on the type of the
restraint.\medskip

{\bf Fixed Restraints}

{\em Position restraint (1 atom):} force constant $K_{f}$, and reference
position $\overrightarrow{r_{ref}}$

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left( \left|
\overrightarrow{r_{i}}-\overrightarrow{r_{ref}}\right| \right) ^{2}$

{\em Stretch restraint (2 atoms):} force constant $K_{f}$, and reference
distance $d_{ref}$

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left(
d_{i}-d_{ref}\right) ^{2}$

{\em Bend restraint (3 atoms):} force constant $K_{f}$, and reference angle $
\theta _{ref}$

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left( \theta
_{i}-\theta _{ref}\right) ^{2}$

{\em Torsion restraint (4 atoms):} energy barrier $E_{0}$, and reference
angle $\chi _{ref}$

$\qquad \qquad \qquad \qquad E=\left( E_{0}/2\right) \left\{ 1-\cos \left(
\chi _{i}-\chi _{ref}\right) \right\} $

{\bf Forcing restraints}

{\em Position restraint (1 atom):} force constant $K_{f}$, and two reference
positions $\overrightarrow{r_{0}}$ and $\overrightarrow{r_{1}}$

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left( \left|
\overrightarrow{r_{i}}-\overrightarrow{r_{ref}}\right| \right) ^{2}$

$\qquad \qquad \qquad \qquad \overrightarrow{r_{ref}}$ $=\lambda
\overrightarrow{r_{1}}+\left( 1-\lambda \right) $ $\overrightarrow{r_{0}}$

{\em Stretch restraint (2 atoms):} force constant $K_{f}$, and two reference
distances $d_{0}$ and $d_{1}$

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left(
d_{i}-d_{ref}\right) ^{2}$

$\qquad \qquad \qquad \qquad d_{ref}=d_{1}+\left( 1-\lambda \right) d_{0}$

{\em Bend restraint (3 atoms):} force constant $K_{f}$, and two reference
angles $\theta _{0}$ and $\theta _{1}$

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left( \theta
_{i}-\theta _{ref}\right) ^{2}$

$\qquad \qquad \qquad \qquad \theta _{ref}=\lambda \theta _{1}+\left(
1-\lambda \right) \theta _{0}$

{\em Torsion restraint (4 atoms):} energy barrier E$_{0}$, and two reference
angles $\chi _{0}$ and $\chi _{1}$

$\qquad \qquad \qquad \qquad E=\left( E_{0}/2\right) \left\{ 1-\cos \left(
\chi _{i}-\chi _{ref}\right) \right\} $

$\qquad \qquad \qquad \qquad \chi _{ref}=\lambda \chi _{1}+\left( 1-\lambda
\right) \chi _{0}$

The forcing restraints depend on the coupling parameter, $\lambda $,
specified in a conformational forcing calculation. For example, the
restraint distance, $d_{ref}$, depends on $\lambda $, and as $\lambda $
changes two atoms or centers-of-mass are forced closer together or further
apart. In this case $K_{f}$ = $K_{f,0}$, the value supplied at input.

Alternatively, the value of $K_{f}$ may depend upon the coupling parameter
$\lambda$ according to:

$K_{f}$ = $K_{f,0} \lambda$

{\bf Bounds}

\begin{tabular}{ll}
{\em Position bound (1 atom):} & Force constant $K_{f}$, reference position $
\overrightarrow{r_{ref}}$, \\
& and upper or lower reference distance, $d_{ref}$
\end{tabular}

\qquad Upper bound:

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left(
d_{i}-d_{ref}\right) ^{2}$ for $d_{i}>d_{ref}$, else $E=0$.

\qquad Lower bound:

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left(
d_{i}-d_{ref}\right) ^{2}$ for $d_{i}$ $<$ $d_{ref}$, else $E=0$.\smallskip

$\qquad \qquad \qquad \qquad d_{i}^{2}=\left( \left| \overrightarrow{r_{i}}-
\overrightarrow{r_{ref}}\right| \right) ^{2}\medskip \medskip $

\begin{tabular}{ll}
{\em Distance bound (2 atoms):} & Force constant $K_{f}$, \\
& and upper or lower reference distance, $d_{ref}$
\end{tabular}

\qquad Upper bound:

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left(
d_{ij}-d_{ref}\right) ^{2}$ for $d_{ij}>d_{ref}$, else $E=0$.

\qquad Lower bound:

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left(
d_{ij}-d_{ref}\right) ^{2}$ for $d_{ij}<d_{ref}$, else $E=0$.\medskip
\medskip

\begin{tabular}{ll}
{\em Angle bound (3 atoms):} & Force constant $K_{f}$, \\
& and upper or lower reference angle, $\theta _{ref}$
\end{tabular}

\qquad Upper bound:

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left( \theta -\theta
_{ref}\right) ^{2}$ for $\theta >\theta _{ref},$ else $E=0$.

\qquad Lower bound:

$\qquad \qquad \qquad \qquad E=\left( K_{f}/2\right) \left( \theta -\theta
_{ref}\right) ^{2}$ for $\theta <\theta _{ref},$ else $E=0.\medskip \medskip
\medskip $

\begin{tabular}{ll}
{\em Torsion bound (4 atoms):} & An upper and lower bound must be provided
together. \\
& Energy gap $E_{0}$, lower AND upper reference angles, $\chi _{1}$ and $
\chi _{2}$, \\
& and angle~interval, $\Delta \chi .$
\end{tabular}

\qquad \qquad
\begin{tabular}{llll}
$\chi _{1}$ & $<\chi $ & $<\chi _{2}$ : & $E=0$ \\
$\left( \chi _{1}-\Delta \chi \right) $ & $<\chi $ & $<\chi _{1}$ : & $
E=\left( G/2\right) \left\{ 1-\cos \left( \chi -\chi _{1}\right) \right\} $
\\
$\chi _{2}$ & $<\chi $ & $\left( \chi _{2}+\Delta \chi \right) $: & $
E=\left( G/2\right) \left\{ 1-\cos \left( \chi -\chi _{2}\right) \right\} $
\\
$\left( \chi _{2}+\Delta \chi \right) ~$ & $<\chi $ & $\left( \chi
_{1}-\Delta \chi +2\pi \right) $ : & $E=G$
\end{tabular}

$\qquad \qquad G=E_{0}/\left\{ 1-\cos \left( \Delta \chi \right) \right\}
\bigskip $

Bounds may be used in pairs, to set a lower and upper bound. Torsional
bounds always are defined in pairs.

\subsection{Free Energy Calculations}

{\bf Conformational forcing / Potential of mean force}

In conformational forcing calculations, structural parameters such as atomic
positions, inter-atomic distances, and dihedral angles are forced to change
by application of changing restraint potentials. For example, the distance
between two atoms can be restrained by a potential to a mean distance that
is varied during the calculation. The free energy change (or potential of
mean force, pmf) for the process can be estimated during the simulation.

The potential is made to depend on a coupling parameter, $\lambda $, whose
value changes during the simulation. In potential of mean force
calculations, the reference value of the restraint potential depends on $
\lambda $. Alternately, the force constant for the restraint potential may
change in proportion to the coupling parameter. Such a calculation gives the
value of a restraint free energy, i.e., the free energy change of the
syste\bigskip m due to imposition of the restraint potential.

{\bf Methods for computing the free energy}

With conformational forcing (or with molecular transformation calculations)
one obtains a free energy difference for a process that is forced on the
system by changing the potential energy function that determines the
dynamics of the system. One always makes the changing potential depend on a
coupling parameter, $\lambda $. By convention, $\lambda $ can have values
only in the range from $0$ to $1$, and a value of $\lambda =0$ corresponds
to one defined state and a value of $\lambda =1$ corresponds to the other
defined state. Intermediate values of $\lambda $ correspond to intermediate
states; in the case of conformational forcing calculations these
intermediate states are physically realizable, but in the case of molecular
transformation calculations they are not.

The value of $\lambda $ is changed during the simulation. In the first
method provided here, the change in $\lambda $ is stepwise, while in the
second method it is virtually continuous.\medskip

{\em Multi-configurational thermodynamic integration (MCTI).}

In MCTI one accumulates $\,\left\langle \partial U/\partial \lambda
\right\rangle $ at several values of $\lambda $, and from these averages
estimates the integral

\qquad \qquad \qquad \qquad $-\Delta A=\int \,\left\langle \partial U/
\partial \lambda \right\rangle d\lambda $

With this method, the precision of each $\left\langle \partial U/\partial
\lambda \right\rangle $ can be estimated from the fluctuations of the time
series of $\partial U/\partial \lambda $.\bigskip

{\em Slow growth.}

In slow growth, $\lambda $ is incremented by $\delta \lambda =\pm 1/N_{step}$
after each dynamics integration time-step, and the pmf is estimated as

\qquad \qquad \qquad \qquad $-\Delta A=\Sigma $ $\left( \partial U/\partial
\lambda \right) $ $\delta \lambda $

Typically, slow growth is done in cycles of: equilibration at $\lambda =0$,
change to $\lambda =1$, equilibration at $\lambda =1$, change to $\lambda =0$
. It is usual to estimate the precision of slow growth simulations from the
results of successive cycles.

\subsection{Options for Conformational Restraints}

{\bf User-supplied restraint and bounds specifications}

\qquad \qquad urestraint $\{$

\qquad \qquad \quad n * (restraint or bound specification)\qquad \qquad //
see below

\qquad \qquad $\}\medskip $

{\bf Restraint Specifications (not coupled to pmf calculations)}

\qquad \qquad
\begin{tabular}{llll}
posi & ATOM & kf = KF & ref = (X Y Z) \\
dist & 2 x ATOM & kf = KF & ref = D \\
angle & 3 x ATOM & kf = KF & ref = A \\
dihe & 4 x ATOM & barr = B & ref = A
\end{tabular}
\bigskip

{\bf Bound Specifications (not coupled to pmf calculations)}

\qquad \qquad
\begin{tabular}{llll}
posi bound & ATOM & kf = KF & [low = (X Y Z D) or hi = (X Y Z D)] \\
dist bound & 2 x ATOM & kf = KF & [low = D or hi = D] \\
angle bound & 3 x ATOM & kf = KF & [low = A or hi = A] \\
dihe bound & 4 x ATOM & gap = E & low = A0\quad hi = A1\quad delta = A2
\end{tabular}
\bigskip

{\bf Forcing Restraint Specifications (coupled to pmf calculations)}

\qquad \qquad
\begin{tabular}{llll}
posi pmf & ATOM & kf=KF & low = (X0 Y0 Z0)\quad hi = (X1 Y1 Z1) \\
dist pmf & 2 x ATOM & kf=KF & low = D0\quad hi = D1 \\
angle pmf & 3 x ATOM & kf=KF & low = A0\quad hi = A1 \\
dihe pmf & 4 x ATOM & barr=B & low = A0\quad hi = A1
\end{tabular}
\bigskip

{\bf Units}

\qquad \qquad
\begin{tabular}{|c|c|}
\hline
Input item & Units \\ \hline
E, B & kcal/mol \\
X, Y, Z, D & %TCIMACRO{\UNICODE{0xc5}{}}
\\
A & degrees \\
$K_{f}$ & kcal/(mol %TCIMACRO{\UNICODE{0xc5}{}}
$^{2}$) or kcal/(mol rad$^{2}$) \\ \hline
\end{tabular}

\subsection{Options for ATOM Specification}

The designation ATOM, above, stands for one of the following forms:\medskip

{\bf A single atom}

(segname, resnum, atomname)

{\em Example:} (insulin, 10, ca)\medskip

{\bf All atoms of a single residue}

(segname, resnum)

{\em Example:} (insulin, 10)\medskip

{\bf A list of atoms}

group $\{$ (segname, resnum, atomname), (segname, resnum, atomname), $\ldots
$ $\}$

{\em Example:} group $\{$ (insulin, 10, ca), (insulin, 10, cb), (insulin,
11, cg) $\}\medskip $

{\bf All atoms in a list of residues}

group $\{$ (segname, resnum), (segname, resnum), $\ldots $ $\}$

{\em Example:} group $\{$ (insulin, 10), (insulin, 12), (insulin, 14) $
\}\medskip $

{\bf All atoms in a range of residues}

group $\{$ (segname, resnum) to (segname, resnum) $\}$

{\em Example:} group $\{$ (insulin, 10) to (insulin, 12) $\}\medskip $

{\bf One or more atomnames in a list of residues}

\begin{tabular}{l}
group $\{$ atomname: (segname, resnum), (segname, resnum), $\ldots $ $\}$ \\
group $\{$ (atomname, atomname, $\ldots $ ): (segname, resnum), (segname,
resnum), $\ldots $ $\}$
\end{tabular}

\begin{tabular}{ll}
{\em Examples:} & group $\{$ ca: (insulin, 10), (insulin, 12), (insulin, 14)
$\}$ \\
& group $\{$ (ca, cb, cg): (insulin, 10), (insulin, 12), (insulin, 14) $\}$
\\
& group $\{$ (ca, cb): (insulin, 10), (insulin, 12) cg: (insulin, 11),
(insulin, 12) $\}\smallskip $
\end{tabular}
\medskip

{\em Note: }Within a group, atomname is in effect until a new atomname is
used, or the keyword all is used. atomname will not carry over from group to
group. This note applies to the paragraph below.\medskip

{\bf One or more atomnames in a range of residues}

\begin{tabular}{l}
group $\{$ atomname: (segname, resnum) to (segname, resnum) $\}$ \\
group $\{$ (atomname, atomname, $\ldots $ ): (segname, resnum) to (segname,
resnum) $\}$
\end{tabular}

\begin{tabular}{ll}
{\em Examples:} & group $\{$ ca: (insulin, 10) to (insulin, 14) $\}$ \\
& group $\{$ (ca, cb, cg): (insulin, 10) to (insulin, 12) $\}$ \\
& group $\{$ (ca, cb): (insulin, 10) to (insulin, 12) all: (insulin, 13) $\}$
\end{tabular}

\subsection{Options for Potential of Mean Force Calculation}

The pmf and mcti blocks, below, are used to simultaneously control all
forcing restraints specified in urestraint above. These blocks are performed
consecutively, in the order they appear in the config file. The pmf block is
used to either a) smoothly vary $\lambda $ from 0 $\rightarrow $1 or 1 $
\rightarrow $0, or b) set lambda. The mcti block is used to vary $\lambda $
from 0 $\rightarrow $1 or 1 $\rightarrow $0 in steps, so that $\lambda $ is
fixed while $dU/d\lambda $ is accumulated.\medskip

{\bf Lamba control for slow growth}

pmf $\{$

~~task = [up, down, stop, grow, fade, or nogrow]

~~time = T [fs, ps, or ns] (default = ps)

~~lambda = Y (value of $\lambda $; only needed for stop and nogrow)

~~lambdat = Z (value of $\lambda _{t}$; only needed for grow, fade, and
nogrow) (default = 0)

~~print = P [fs, ps, or ns] or noprint (default = ps)

$\}\medskip $

\begin{tabular}{ll}
up, down, stop: & $\lambda $ is applied to the reference values. \\
grow, fade, nogrow: & $\,\lambda $ is applied to $K_{f}$. A fixed value, $
\lambda _{t}$, is used to determine the ref. values. \\
up, grow: & $\lambda $ changes from 0 $\rightarrow $1. (no value of $
\,\lambda $ is required) \\
down, fade: & $\lambda $ changes from 1 $\rightarrow $0. (no value of $
\,\lambda $ is required) \\
stop, nogrow: & dU/d$\lambda $ is accumulated (for single point
MCTI)\medskip \smallskip
\end{tabular}
\bigskip

{\bf Lambda control for automated MCTI}

mcti $\{$

~~task = [stepup, stepdown, stepgrow, or stepfade]

~~equiltime = T1 [fs, ps, or ns] (default = ps)

~~accumtime = T2 [fs, ps, or ns] (default = ps)

~~numsteps = N

~~lambdat = Z (value of $\lambda _{t}$; only needed for stepgrow, and
stepfade) (default = 0)

~~print = P [fs, ps, or ns] or noprint (default = ps)

$\}\medskip $

\begin{tabular}{ll}
stepup, stepdown: & $\lambda $ is applied to the reference values. \\
stepgrow, stepfade: & $\lambda $ is applied to $K_{f}$. A fixed value, $
\lambda _{t}$, is used to determine the ref. values. \\
stepup, stepgrow: & $\lambda $ changes from 0 $\rightarrow $1. (no value of $
\lambda $ is required) \\
stepdown, stepfade: & $\lambda $ changes from 1 $\rightarrow $0. (no value
of $\lambda $ is required)\medskip
\end{tabular}

For each task, $\lambda $ changes in steps of (1.0/N) from 0 $\rightarrow $1
or 1 $\rightarrow $0. At each step, no data is accumulated for the initial
period T1, then dU/d$\lambda $ is accumulated for T2. Therefore, the total
duration of an mcti block is (T1+T2) x N.

\subsection{Examples}

{\bf Fixed restraints}

\begin{tabular}{l}
{\footnotesize // 1. restrain the position of the ca atom of residue 0.} \\
{\footnotesize // 2. restrain the distance between the ca's of residues 0
and 10 to 5.2\AA } \\
{\footnotesize // 3. restrain the angle between the ca's of residues 0-10-20
to 90}$^{o}${\footnotesize \ .} \\
{\footnotesize // 4. restrain the dihedral angle between the ca's of
residues 0-10-20-30 to 180}$^{o}${\footnotesize \ .} \\
{\footnotesize // 5. restrain the angle between the centers-of-mass of
residues 0-10-20 to 90}$^{o}${\footnotesize \ .}
\end{tabular}

urestraint $\{$

~~posi (insulin, 0, ca) kf=20 ref=(10, 11, 11)

~~dist (insulin, 0, ca) (insulin, 10, ca) kf=20 ref=5.2

~~angle (insulin, 0, ca) (insulin, 10, ca) (insulin, 20, ca) kf=20 ref=90

~~dihe (insulin, 0, ca) (insulin, 10, ca) (insulin, 20, ca) (insulin, 30,
ca) barr=20 ref=180

~~angle (insulin, 0) (insulin, 10) (insulin, 20) kf=20 ref=90

$\}\bigskip $

\begin{tabular}{ll}
{\footnotesize // 1. } & {\footnotesize restrain the center of mass of three
atoms of residue 0.} \\
{\footnotesize // 2.} & {\footnotesize restrain the distance between (the
COM of 3 atoms of residue 0) to  (the COM of 3 atoms of residue 10).} \\
{\footnotesize // 3.} & {\footnotesize \ restrain the dihedral angle of
(10,11,12)-(15,16,17,18)-(20,22)-(30,31,32,34,35) to 90}$^{o}$ \\
{\footnotesize //} & {\footnotesize ( (ca of 10 to 12), (ca, cb, cg of 15 to
18), (all atoms of 20 and 22), (ca of 30, 31, 32, 34, all atoms of 35) ).}
\end{tabular}

urestraint $\{$

~~posi group $\{$(insulin, 0, ca), (insulin, 0, cb), (insulin, 0, cg)$\}$
kf=20 ref=(10, 11, 11)

~~
\begin{tabular}{ll}
dist & group $\{$(insulin, 0, ca), (insulin, 0, cb), (insulin, 0, cg)$\}$ \\
& group $\{$(insulin, 10, ca), (insulin, 10, cb), (insulin, 10, cg)$\}$
kf=20 ref=6.2
\end{tabular}

~~
\begin{tabular}{ll}
dihe & group $\{$ca: (insulin, 10) to (insulin, 12)$\}$ \\
& group $\{$(ca, cb, cg): (insulin, 15) to (insulin, 18)$\}$ \\
& group $\{$(insulin, 20), (insulin, 22)$\}$ \\
& group $\{$ca: (insulin, 30) to (insulin, 32), (insulin, 34), all:
(insulin, 35)$\}$ barr=20 ref=90
\end{tabular}

$\}$

{\bf Bound specifications}

\begin{tabular}{ll}
{\footnotesize // 1. } & {\footnotesize impose an upper bound if an atom's
position strays too far from a reference position.} \\
{\footnotesize // } & {\footnotesize (add an energy term if the atom is more
than 10\AA\ {}from (2.0, 2.0, 2.0) ).} \\
{\footnotesize // 2\&3.} & {\footnotesize \ impose lower and upper bounds on
the distance between the ca's of residues 5 and 15.} \\
{\footnotesize //} & {\footnotesize (if the separation is less than 5.0\AA\
{}or greater than 12.0\AA\ {}add an energy term).} \\
{\footnotesize // 4.} & {\footnotesize \ impose a lower bound on the angle
between the centers-of-mass of residues 3-6-9.} \\
{\footnotesize //} & {\footnotesize (if the angle goes lower than 90}$^{o}$
{\footnotesize \ apply a restraining potential).}
\end{tabular}

urestraint $\{$

~~posi bound (insulin, 3, cb) kf=20 hi = (2.0, 2.0, 2.0, 10.0)

~~dist bound (insulin, 5, ca) (insulin, 15, ca) kf=20 low = 5.0

~~dist bound (insulin, 5, ca) (insulin, 15, ca) kf=20 hi = 12.0

~~angle bound (insulin, 3) (insulin, 6) (insulin, 9) kf=20 low=90.0

$\}\bigskip $

\begin{tabular}{l}
{\footnotesize // torsional bounds are defined as pairs. this example
specifies upper and lower bounds on the} \\
{\footnotesize // dihedral angle, }$\chi ${\footnotesize {}, separating the
planes of the 1-2-3 residues and the 2-3-4 residues.}
\end{tabular}

%\begin{Body Text}
\begin{tabular}{llll}
{\footnotesize // The energy is 0 for:} & {\footnotesize -90}$^{o}$ &
{\footnotesize < }$\chi $ & {\footnotesize <\ 120}$
^{o}$ \\
{\footnotesize // The energy is 20 kcal/mol for:} & {\footnotesize 130}$^{o}$
& {\footnotesize <\ }$\chi $ & {\footnotesize <\
260}$^{o}$
\end{tabular}

\begin{tabular}{l}
{\footnotesize // Energy rises from 0 }$\rightarrow ${\footnotesize \ 20
kcal/mol as }$\chi ${\footnotesize \ {}increases from 120}$^{o}\rightarrow $
{\footnotesize \ 130}$^{o}${\footnotesize \ , and decreases from --90}$
^{o}\rightarrow ${\footnotesize \ --100}$^{o}${\footnotesize .}
\end{tabular}
%\end{Body Text}

urestraint $\{$

~~dihe bound (insulin 1) (insulin 2) (insulin 3) (insulin 4) gap=20 low=-90
hi=120 delta=10

$\}$

{\bf Forcing restraints}

\begin{tabular}{l}
{\footnotesize // a forcing restraint will be imposed on the distance
between the centers-of-mass of residues (10 to 15) and} \\
{\footnotesize // residues (30 to 35). low=20.0, hi=10.0, indicates that the
reference distance is 20.0%TCIMACRO{\UNICODE{0xc5}{}}
at }$\lambda ${\footnotesize =0, and 10.0%TCIMACRO{\UNICODE{0xc5}{}}
at }$\lambda ${\footnotesize =1.}
\end{tabular}

urestraint $\{$

~~
\begin{tabular}{ll}
dist pmf & group $\{$ (insulin, 10) to (insulin, 15) $\}$ \\
& \hspace{0pt}group $\{$ (insulin, 30) to (insulin, 35) $\}$ kf=20,
low=20.0, hi=10.0
\end{tabular}

$\}\medskip $

\begin{tabular}{l}
{\footnotesize // 1. during the initial 10 ps, increase the strength of the
forcing restraint to full strength: 0 }$\rightarrow $ {\footnotesize 20
kcal/(mol %TCIMACRO{\UNICODE{0xc5}{}}
}$^{2}${\footnotesize )} \\
{\footnotesize // 2. next, apply a force to slowly close the distance from
20 %TCIMACRO{\UNICODE{0xc5}{}}
to 10 %TCIMACRO{\UNICODE{0xc5}{}}
(}$\lambda ${\footnotesize \ changes from 0 }$\rightarrow ${\footnotesize \
1)} \\
{\footnotesize // 3. accumulate dU/d}$\lambda ${\footnotesize \ for another
10 ps. ( stays fixed at 1)} \\
{\footnotesize // 4. force the distance back to its initial value of 20
%TCIMACRO{\UNICODE{0xc5}{}}
( changes from 1 }$\rightarrow $ {\footnotesize 0)}
\end{tabular}

pmf $\{$

~~task = grow

~~time = 10 ps

~~print = 1 ps

$\}$

pmf $\{$

~~task = up

~~time = 100 ps

$\}$

pmf $\{$

~~task = stop

~~time = 10 ps

$\}$

pmf $\{$

~~task = down

~~time = 100 ps

$\}\medskip $

\begin{tabular}{ll}
{\footnotesize // 1. } & {\footnotesize force the distance to close from 20
%TCIMACRO{\UNICODE{0xc5}{}}
to 10 %TCIMACRO{\UNICODE{0xc5}{}}
in 5 steps. (}$\lambda ${\footnotesize \ changes from 0 }$\rightarrow $
{\footnotesize \ 1: ~~0.2, 0.4, 0.6, 0.8, 1.0)} \\
{\footnotesize // } & {\footnotesize at each step equilibrate for 10 ps,
then collect dU/d}$\lambda ${\footnotesize \ for another 10 ps.} \\
{\footnotesize //} & {\footnotesize ref = 18, 16, 14, 12, 10
%TCIMACRO{\UNICODE{0xc5}{}}
, duration = (10 + 10) x 5 = 100 ps.} \\
{\footnotesize // 2.} & {\footnotesize \ reverse the step above (}$\lambda $
{\footnotesize \ changes from 1 }$\rightarrow $ {\footnotesize 0: ~~0.8,
0.6, 0.4, 0.2, 0.0)}
\end{tabular}

mcti $\{$

~~task = stepup

~~equiltime = 10 ps

~~accumtime = 10 ps

~~numsteps = 5

~~print = 1 ps

$\}$

mcti $\{$

~~task = stepdown

$\}$

\subsection{Appendix}

{\bf Gradient for position restraint}

$E=\left( K_{f}/2\right) \left( \left| \overrightarrow{r_{i}}-
\overrightarrow{r_{ref}}\right| \right) ^{2}$

$E=\left( K_{f}/2\right) \left\{ \left( x_{i}-x_{ref}\right) ^{2}+\left(
y_{i}-y_{ref}\right) ^{2}+\left( z_{i}-z_{ref}\right) ^{2}\right\} $

$\nabla (E)=K_{f}\left\{ \left( x_{i}-x_{ref}\right) \overrightarrow{i}
+\left( y_{i}-y_{ref}\right) \overrightarrow{j}+\left( z_{i}-z_{ref}\right)
\overrightarrow{k}\right\} $

{\bf Gradient for stretch restraint}

$E=\left( K_{f}/2\right) \left( d_{i}-d_{ref}\right) ^{2}$

$d_{i}=\left\{ \left( x_{2}-x_{1}\right) ^{2}+\left( y_{2}-y_{1}\right)
^{2}+\left( z_{2}-z_{1}\right) ^{2}\right\} ^{1/2}$

$\nabla (E)=K_{f}\left( d_{i}-d_{ref}\right) \cdot \nabla (di)\medskip $

{\em for atom 2 moving, and atom 1 fixed}

$\nabla (d_{i})=1/2\left\{ \left( x_{2}-x_{1}\right) ^{2}+\left(
y_{2}-y_{1}\right) ^{2}+\left( z_{2}-z_{1}\right) ^{2}\right\}
^{-1/2}\left\{ 2\left( x_{2}-x_{1}\right) +2\left( y_{2}-y_{1}\right)
+2\left( z_{2}-z_{1}\right) \right\} $

$\nabla (d_{i})=\left\{ \left( x_{2}-x_{1}\right) \overrightarrow{i}+\left(
y_{2}-y_{1}\right) \overrightarrow{j}+\left( z_{2}-z_{1}\right)
\overrightarrow{k}\right\} /d_{i}$

$\nabla (E)=K_{f}\left\{ \left( d_{i}-d_{ref}\right) /d_{i}\right\} \left\{
\left( x_{2}-x_{1}\right) \overrightarrow{i}+\left( y_{2}-y_{1}\right)
\overrightarrow{j}+\left( z_{2}-z_{1}\right) \overrightarrow{k}\right\} $

{\bf Gradient for bend restraint}

$E=\left( K_{f}/2\right) \left( \theta _{i}-\theta _{ref}\right) ^{2}$

Atoms at positions A-B-C

distances: (A to B) = c; (A to C) = b; (B to C) = a;

$\theta _{i}=\cos ^{-1}(u)=\cos ^{-1}\left\{ \left( a^{2}+c^{2}-b^{2}\right)
/\left( 2ac\right) \right\} $

$\nabla (E)=K_{f}\left( \theta _{i}-\theta _{ref}\right) \cdot \nabla
(\theta _{i})$

$\nabla (\theta _{i})=\frac{-1}{\sqrt{1-u^{2}}}\cdot \nabla (u)\medskip $

{\em for atom A moving, atoms B \& C fixed (distances b and c
change)}

$\nabla (u)=\left\{ -b/\left( ac\right) \right\} \cdot \nabla (b)+\left\{
-a/\left( 2c^{2}\right) +1/\left( 2a\right) +b^{2}/\left( 2ac^{2}\right)
\right\} \cdot \nabla (c)$

$\nabla (b)=\left\{ \left( x_{A}-x_{C}\right) \overrightarrow{i}+\left(
y_{A}-y_{C}\right) \overrightarrow{j}+\left( z_{A}-z_{C}\right)
\overrightarrow{k}\right\} /b$

$\nabla (c)=\left\{ \left( x_{A}-x_{B}\right) \overrightarrow{i}+\left(
y_{A}-y_{B}\right) \overrightarrow{j}+\left( z_{A}-z_{B}\right)
\overrightarrow{k}\right\} /c\medskip $

{\em for atom B moving, atoms A \& C fixed (distances a and c
change)}

$\nabla (u)=\left\{ 1/(2c)+-c/(2a^{2})+b^{2}/(2a^{2}c)\right\} \cdot \nabla
(a)+\left\{ -a/\left( 2c^{2}\right) +1/(2a)+b^{2}/\left( 2ac^{2}\right)
\right\} \cdot \nabla (c)$

$\nabla (a)=\left\{ (x_{B}-x_{C})\overrightarrow{i}+(y_{B}-y_{C})
\overrightarrow{j}+(z_{B}-z_{C})\overrightarrow{k}\right\} /a$

$\nabla (c)=\left\{ (x_{B}-x_{A})\overrightarrow{i}+(y_{B}-y_{A})
\overrightarrow{j}+(z_{B}-z_{A})\overrightarrow{k}\right\} /c\medskip $

{\em for atom C moving, atoms A \& B fixed (distances a and b
change)}

$\nabla (u)=\left\{ -b/\left( ac\right) \right\} \cdot \nabla (b)+\left\{
-c/\left( 2a^{2}\right) +1/(2c)+b^{2}/\left( 2ac^{2}\right) \right\} \cdot
\nabla (a)$

$\nabla (b)=\left\{ (x_{C}-x_{A})\overrightarrow{i}+(y_{C}-y_{A})
\overrightarrow{j}+(z_{C}-z_{A})\overrightarrow{k}\right\} /b$

$\nabla (a)=\left\{ (x_{C}-x_{B})\overrightarrow{i}+(y_{C}-y_{B})
\overrightarrow{j}+(z_{C}-z_{B})\overrightarrow{k}\right\} /a $

{\bf Gradient for dihedral angle restraint}

$E=(E_{0}/2)\left\{ 1-\cos \left( \chi _{i}-\chi _{ref}\right) \right\} $

Atoms at positions A-B-C-D

$\chi _{i}=\cos ^{-1}(u)=$ $\cos ^{-1}\left( \frac{\overrightarrow{(CD}
\times \overrightarrow{CB})\bullet (\overrightarrow{BC}\times
\overrightarrow{BA})}{\left| \overrightarrow{CD}\times \overrightarrow{CB}
\right| \left| \overrightarrow{BC}\times \overrightarrow{BA}\right| }\right)
\qquad $AND

$\chi _{i}=\sin ^{-1}(v)=$ $\sin ^{-1}\left( \frac{\overrightarrow{(CD}
\times \overrightarrow{CB})\times (\overrightarrow{BC}\times \overrightarrow{
BA})}{\left| \overrightarrow{CD}\times \overrightarrow{CB}\right| \left|
\overrightarrow{BC}\times \overrightarrow{BA}\right| }\bullet \frac{
\overrightarrow{CB}}{\left| \overrightarrow{CB}\right| }\right) $

$\nabla (E)=(E_{0}/2)\left\{ \sin \left( \chi _{i}-\chi _{ref}\right)
\right\} \cdot \nabla (\chi _{i})$

$\nabla (\chi _{i})=\frac{-1}{\sqrt{1-u^{2}}}\cdot \nabla (u)\smallskip
\medskip $

\begin{tabular}{ll}
$\overrightarrow{CD}\times \overrightarrow{CB}$ $=$ & $
((y_{D}-y_{C})(z_{B}-z_{C})-(z_{D}-z_{C})(y_{B}-y_{C}))\overrightarrow{i}+$
\\
& $((z_{D}-z_{C})(x_{B}-x_{C})-(x_{D}-x_{C})(z_{B}-z_{C}))\overrightarrow{j}+
$ \\
& $((x_{D}-x_{C})(y_{B}-y_{C})-(y_{D}-y_{C})(x_{B}-x_{C}))\overrightarrow{k}$
\\
\multicolumn{1}{c}{$=$} & $p_{1}\overrightarrow{i}+p_{2}\overrightarrow{j}
+p_{3}\overrightarrow{k}$
\end{tabular}
\medskip \medskip

\begin{tabular}{ll}
$\overrightarrow{BC}\times \overrightarrow{BA}=$ & $
((y_{C}-y_{B})(z_{A}-z_{B})-(z_{C}-z_{B})(y_{A}-y_{B}))\overrightarrow{i}+$
\\
& $((z_{C}-z_{B})(x_{A}-x_{B})-(x_{C}-x_{B})(z_{A}-z_{B}))\overrightarrow{j}+
$ \\
& $((x_{C}-x_{B})(y_{A}-y_{B})-(y_{C}-y_{B})(x_{A}-x_{B}))\overrightarrow{k}$
\\
\multicolumn{1}{c}{$=$} & $p_{4}\overrightarrow{i}+p_{5}\overrightarrow{j}
+p_{6}\overrightarrow{k}$
\end{tabular}
\medskip \medskip

$u=\frac{p_{1}p_{4}+p_{2}p_{5}+p_{3}p_{6}}{\sqrt{
p_{1}^{2}+p_{2}^{2}+p_{3}^{2}}\sqrt{p_{4}^{2}+p_{5}^{2}+p_{6}^{2}}}\medskip
\medskip $

\begin{tabular}{ll}
$\nabla (u)=$ & $\frac{p_{1}\cdot \nabla (p_{4})+p_{2}\cdot \nabla
(p_{5})+p_{3}\cdot \nabla (p_{6})}{\sqrt{p_{1}^{2}+p_{2}^{2}+p_{3}^{2}}\sqrt{
p_{4}^{2}+p_{5}^{2}+p_{6}^{2}}}$ $+$ \\
& $\frac{p_{1}p_{4}+p_{2}p_{5}+p_{3}p_{6}}{\sqrt{
p_{1}^{2}+p_{2}^{2}+p_{3}^{2}}}$ $\left( -1/2\left(
p_{4}^{2}+p_{5}^{2}+p_{6}^{2}\right) ^{-3/2}\left( 2p_{4}\cdot \nabla
(p_{4})+2p_{5}\cdot \nabla (p_{5})+2p_{6}\cdot \nabla (p_{6})\right) \right)
$ $+$ \\
& $\frac{p_{1}p_{4}+p_{2}p_{5}+p_{3}p_{6}}{\sqrt{
p_{4}^{2}+p_{5}^{2}+p_{6}^{2}}}$ $\left( -1/2\left(
p_{1}^{2}+p_{2}^{2}+p_{3}^{2}\right) ^{-3/2}\left( 2p_{1}\cdot \nabla
(p_{1})+2p_{2}\cdot \nabla (p_{2})+2p_{3}\cdot \nabla (p_{3})\right) \right)
$
\end{tabular}

{\em for atom A moving, atoms B, C, \& D fixed}

\begin{tabular}{lrrr}
$\nabla (p_{1})=$ & $(0.0)\overrightarrow{i}+$ & $(0.0)\overrightarrow{j}+$
& $(0.0)\overrightarrow{k}$ \\
$\nabla (p_{2})=$ & $(0.0)\overrightarrow{i}+$ & $(0.0)\overrightarrow{j}+$
& $(0.0)\overrightarrow{k}$ \\
$\nabla (p_{3})=$ & $(0.0)\overrightarrow{i}+$ & $(0.0)\overrightarrow{j}+$
& $(0.0)\overrightarrow{k}$ \\
$\nabla (p_{4})=$ & $(0.0)\overrightarrow{i}+$ & $(z_{B}-z_{C})
\overrightarrow{j}+$ & $(y_{C}-y_{B})\overrightarrow{k}$ \\
$\nabla (p_{5})=$ & $(z_{C}-z_{B})\overrightarrow{i}+$ & $(0.0)
\overrightarrow{j}+$ & $(x_{B}-x_{C})\overrightarrow{k}$ \\
$\nabla (p_{6})=$ & $(y_{B}-y_{C})\overrightarrow{i}+$ & $(x_{C}-x_{B})
\overrightarrow{j}+$ & $(0.0)\nolinebreak \bigskip \overrightarrow{k}$
\end{tabular}
\bigskip

{\em for atom B moving, atoms A, C, \& D fixed}

\begin{tabular}{lrrr}
$\nabla (p_{1})=$ & $(0.0)\overrightarrow{i}+$ & $(z_{C}-z_{D})
\overrightarrow{j}+$ & $(y_{D}-y_{C})\overrightarrow{k}$ \\
$\nabla (p_{2})=$ & $(z_{D}-z_{C})\overrightarrow{i}+$ & $(0.0)
\overrightarrow{j}+$ & $(x_{C}-x_{D})\overrightarrow{k}$ \\
$\nabla (p_{3})=$ & $(y_{C}-y_{D})\overrightarrow{i}+$ & $(x_{D}-x_{C})
\overrightarrow{j}+$ & $(0.0)\overrightarrow{k}$ \\
$\nabla (p_{4})=$ & $(0.0)\overrightarrow{i}+$ & $(z_{C}-z_{A})
\overrightarrow{j}+$ & $(y_{A}-y_{C})\overrightarrow{k}$ \\
$\nabla (p_{5})=$ & $(z_{A}-z_{C})\overrightarrow{i}+$ & $(0.0)
\overrightarrow{j}+$ & $(x_{C}-x_{A})\overrightarrow{k}$ \\
$\nabla (p_{6})=$ & $(y_{C}-y_{A})\overrightarrow{i}+$ & $(x_{A}-x_{C})
\overrightarrow{j}+$ & $(0.0)\overrightarrow{k}$
\end{tabular}

{\bf Gradient for forcing position restraint}

$E=(K_{f}/2)\left( \left| \overrightarrow{r_{i}}-\overrightarrow{r_{ref}}
\right| \right) ^{2}$

$r_{ref}=\lambda \overrightarrow{r_{1}}+\left( 1-\lambda \right)
\overrightarrow{r_{0}}$

\begin{tabular}{lll}
$dE/d\lambda =$ & $K_{f}\times $ & $\left( \left( x_{i}-x_{ref}\right)
^{2}+\left( y_{i}-y_{ref}\right) ^{2}+\left( z_{i}-z_{ref}\right)
^{2}\right) ^{1/2}\times $ \\
&  & $1/2\left( \left( x_{i}-x_{ref}\right) ^{2}+\left( y_{i}-y_{ref}\right)
^{2}+\left( z_{i}-z_{ref}\right) ^{2}\right) ^{-1/2}\times $ \\
&  & $\left( 2\left( x_{i}-x_{ref}\right) \left( x_{0}-x_{1}\right) +2\left(
y_{i}-y_{ref}\right) \left( y_{0}-y_{1}\right) +2\left( z_{i}-z_{ref}\right)
\left( z_{0}-z_{1}\right) \right) $
\end{tabular}

$dE/d\lambda =K_{f}\times \left( \left( x_{i}-x_{ref}\right) \left(
x_{0}-x_{1}\right) +\left( y_{i}-y_{ref}\right) \left( y_{0}-y_{1}\right)
+\left( z_{i}-z_{ref}\right) \left( z_{0}-z_{1}\right) \right) \bigskip $

{\bf Gradient for forcing stretch restraint}

$E=\left( K_{f}/2\right) \left( d_{i}-d_{ref}\right) ^{2}$

$d_{ref}=\lambda d_{1}+\left( 1-\lambda \right) d_{0}$

$dE/d\lambda =K_{f}~\times ~\left( d_{i}-d_{ref}\right) ~\times ~\left(
d_{0}-d_{1}\right) \bigskip $

{\bf Gradient for forcing bend restraint}

$E=\left( K_{f}/2\right) \left( \theta _{i}-\theta _{ref}\right) ^{2}$

$\theta _{ref}=\lambda \theta _{1}+\left( 1-\lambda \right) \theta _{0}$

$dE/d\lambda =K_{f}~\times ~\left( \theta _{i}-\theta _{ref}\right) ~\times
~\left( \theta _{0}-\theta _{1}\right) \bigskip $

{\bf Gradient for forcing dihedral restraint}

$E=\left( E_{0}/2\right) \left( 1-\cos \left( \chi _{i}-\chi _{ref}\right)
\right) $

$\chi _{ref}=\lambda \chi _{1}+\left( 1-\lambda \right) \chi _{0}$

$dE/d\lambda =\left( E_{0}/2\right) ~\times ~\sin \left( \chi _{i}-\chi
_{ref}\right) ~\times ~\left( \chi _{0}-\chi _{1}\right) $


\chapter{\acro{rtn} Support}

\label{sec:openfstrtn}

%\section{Two Distinct Flavors of \acro{rtn} Support}

% See saprtn.tex.notrack
%Kleene is currently being expanded to provide support for two distinct
%flavors of Recursive Transition Networks or \acro{rtn}s.  This is work in
%progress.

%This section describes the Kleene support for \acro{rtn}s
%compatible with the off-the-shelf functions from the OpenFst library.
%\acro{sap} linguists creating pattern networks for the \acro{sap}
%\acro{rtn} pattern-matching runtime code should ignore this section and
%proceed immediately to section~\ref{sec:saprtn} starting on
%page~\pageref{sec:saprtn}.

\section{OpenFst Recursive Transition Networks (\acro{rtn}s)}

\subsection{Status}

[KRB 2013-04]  WORK IN PROGRESS:  There is currently no runtime-code support for
\init{rtn}s.  This chapter has not be reviewed recently.

Kleene supports the building of Recursive Transition Networks
(\acro{rtn}s) that are compatible with the OpenFst \texttt{Replace()} and
\texttt{ReplaceFst()} operations.  An \acro{rtn} contains arc labels that
are to be interpreted as ``references'' to subnetworks; and compatible
\acro{rtn}-savvy runtime code, when applying a network to data, will
recognize such a reference and ``push'' to the referenced subnetwork to
continue the matching, and then ``pop'' back to the calling network when
the subnetwork has successfully matched.  The references to subnetworks
can also be thought of as non-terminal labels.

\acro{rtn}s, containing references to subnetworks, are often smaller than
full-sized networks that must contain a full copy of each subnetwork
wherever it is needed.  However, \acro{rtn}s can denote context-free
languages, and so can go beyond regular power; a special subclass of
\acro{rtn}s remain regular.  The recognition/parsing of context-free
languages requires memory, in particular a push-down stack, and so any
runtime code to apply \acro{rtn}s must include such a stack.

At the time of writing (13 October 2010) there are hints that the
\acro{rtn} conventions currently required in OpenFst might change, and
there is new library support for mathematically equivalent Pushdown
Automata (\acro{pda}s) that we have not yet tested.  Kleene support for
OpenFst \acro{rtn}s and \acro{pda}s will necessarily evolve along with
the library.

\subsection{Syntax for Creating an OpenFst \acro{rtn}}

For the programmer, there needs to be a Kleene syntax to denote a
reference to a subnetwork, and it needs to be distinct from the syntax
that causes a copy of a network to be inserted.  For example, in this
example

\begin{Verbatim}[fontsize=\small]
$vowel = [aeiou] ;
$net = k $vowel t $vowel b $vowel ;
\end{Verbatim}

\noindent
the \verb!$vowel! network will be copied three times into \verb!$net!.
In real-life applications, a subnetwork might encode something much
larger, such as nouns or even noun phrases in a natural language, and
multiple copies could easily cause the final network to become very
large, or even too large to compute.

Kleene currently supports a wired-in function \verb!$^sub($s)! that
programmers can use to denote a reference to a subnetwork \verb!$s!.\footnote{I'm
not tied to \verb!$^sub($s)! and would be comfortable with alternatives such
as \verb!$^ref($s)! or \verb!$^push($s)!, or even some special syntax like
\verb!>$s<! or \verb!>>$s!.}

To continue with our trivial example,

\begin{Verbatim}[fontsize=\small]
$vowel = [aeiou] ;
$rtn = k $^sub($vowel) t $^sub($vowel) b $^sub($vowel) ;
\end{Verbatim}

\noindent
would result in an \verb!$rtn! network that contains three compact
one-label references to \verb!$vowel! rather than three full copies of
it.  In real-life applications, the savings in memory can be very
significant.

\subsection{What does a Reference Look Like in an OpenFst \acro{rtn}?}

OpenFst networks consist of states and arcs, and each arc has two labels,
an input label, and an output label.\footnote{The terminology of
\emph{input} and \emph{output} labels is that of the OpenFst tradition.
In the Xerox tradition, they are called \emph{upper} and \emph{lower}, or
sometimes \emph{lexical} and \emph{surface}.}  In the actual network, the
labels are really integers, and all Unicode characters, such as \emph{a},
\emph{b}, \emph{c}, etc.\@ are represented using their standard Unicode
code point values.  Multichar symbols are stored using code point values
selected at random from a Unicode Private Use Area.

To maximize compatibility with the off-the-shelf OpenFst
\texttt{Replace()} and \texttt{ReplaceFst()} operations, the integer
representing a reference to a subnetwork must currently appear on the
\emph{output} side of an arc.  In Kleene, multichar symbol names
representing a call to a subnetwork \verb!$s! are spelled \verb!__$s!,
with two initial underscores, and the syntax \verb!$^sub($s)!  currently
yields the following network.

% see images/README for converting .ps files to .pdf and cropping them
\begin{center}
\includegraphics{images/reference.pdf}
\end{center}

\noindent
Currently in OpenFst, the symbol \verb!__$s! could in fact appear also on
the input side.  Of course, in the real network, the labels are really
just integers, 0 for epsilon, and some arbitrary value from the Private
Use Area for the multichar symbol.

Kleene programmers should use the wired-in \verb!$^sub()! function to
denote references to subnetworks and should not try to specify special
symbols like \verb!__$s! directly.  For example, the following statement
is illegal and will cause an exception to be thrown.

\begin{Verbatim}[fontsize=\small]
$rtn = "":'__$foo' ;    // raises an exception
\end{Verbatim}

\noindent
The use of \verb!$^sub()! at the programming level will also make it easy
for Kleene to adapt to any changes to \acro{rtn} representations that
might be made in the underlying OpenFst library.

\subsection{Embedding Subnetworks in an OpenFst \acro{rtn}}

The \verb!$^embedRtnSubnets($rtn)! function takes an OpenFst \acro{rtn}
argument, i.e.\@ a network that contains OpenFst-format references to
subnetworks, and returns a network that consists of the original network
unioned with a prefixed copy of each referred-to subnetwork.  For each
referred-to network \verb!$s!, the prefix consists of the special symbol
\verb!__SUBNETWORKS! followed by the special symbol \verb!__$s!.  Thus
from the following code

\begin{Verbatim}[fontsize=\small]
$p = p ;
$q = q ;
$rtn = a $^sub($p) b $^sub($q) ;
\end{Verbatim}

\noindent
the result \verb!$rtn! is this network containing two references to subnetworks

\begin{center}
\includegraphics[width=\textwidth]{images/twoReferences.pdf}
\end{center}

\noindent
but the three referred-to networks remain separate.  After the following
call to \verb!$^embedRtnSubnets($rtn)!,

\begin{Verbatim}[fontsize=\small]
$embedded = $^embedRtnSubnets($rtn) ;
\end{Verbatim}

\noindent
the resulting \verb!$embedded! network looks like this

\begin{center}
\includegraphics[width=\textwidth]{images/embedded.pdf}
\end{center}

\noindent
The embedded network can be saved to file as a single network and could be
applied by \acro{rtn}-savvy runtime code (not yet written) that knows the prefix convention.

The unioning of the base network with the subnetworks also guarantees that
the meaning of OTHER, if present, is standardized throughout all the
networks.

\subsection{Expanding an OpenFst \acro{rtn} into a Full Normal Network}

In some cases, it may also be useful to take an OpenFst \acro{rtn} and replace
each reference to a subnetwork with an actual copy of that subnetwork,
expanding the \acro{rtn} into a full normal network.  This is mathematically and
computationally possible only if the \acro{rtn} is regular.  Using the same
\verb!$rtn! example, a call to \verb!$^expandRtn()!

\begin{Verbatim}[fontsize=\small]
$expanded = $^expandRtn($rtn) ;
\end{Verbatim}

\noindent
produces the following \verb!$expanded! network

\begin{center}
\includegraphics[width=\textwidth]{images/expanded.pdf}
\end{center}

\noindent
In real-life \acro{rtn}s, with multiple references to the same
subnetwork, the expanded network will be significantly bigger than the
original.

If the \acro{rtn} contains cyclic references to subnetworks, it is
context-free in power (i.e.\@ no longer regular in power), and its
expansion would result in an infinite network.  The
\verb!$^expandRtn($rtn)! function checks for cyclic references and throws
an exception if the \verb!$rtn! is not regular.\footnote{In the OpenFst
library, the \verb!ReplaceFst()! operation provides a convenient method
that checks for cyclic references, and \verb!$^expandRtn()! invokes this
method.}


\section{UTxO}
\label{sec:utxo}

Some of the functions related to scripts, datums and collateral need
to be adjusted for the new features. Most of these adjustments are
self-explanatory. Note that the new $\fun{collOuts}$ function
generates a single output with an index $| \txouts{txb} |$. This is to
avoid potential confusion for transactions spending that output.

\begin{figure*}[htb]
  \emph{Functions}
  %
  \begin{align*}
    & \fun{isTwoPhaseScriptAddress} : \Tx \to \hldiff{\UTxO} \to \Addr \to \Bool \\
    & \fun{isTwoPhaseScriptAddress}~tx~\hldiff{utxo}~a = \\
    &\quad\begin{cases}
        \True  & a \in \AddrScr \land \fun{validatorHash}~a \mapsto s \in \fun{txscripts}~tx~\hldiff{utxo} \land s \in \ScriptPhTwo \\
        \False & \text{otherwise}
      \end{cases}
    \nextdef
    & \fun{collBalance} : \TxBody \to \UTxO \to \Value \\
    & \fun{collBalance}~txb~utxo = \fun{ubalance}~(\var{utxo}|_{\fun{collInputs}~{txb}}) -
      \begin{cases}
         0                 & \fun{collRet}~txb = \Nothing \\
         \fun{collRet}~txb & \text{otherwise}
      \end{cases}
    \nextdef
    & \fun{collOuts} : \TxBody \to \UTxO \\
    & \fun{collOuts}~txb =
      \begin{cases}
        \emptyset                                                      & \fun{collRet}~txb = \Nothing \\
        \{ (\txid{txb}, | \txouts{txb} |) \mapsto \fun{collRet}~txb \} & \text{otherwise}
      \end{cases}
    \nextdef
    & \fun{feesOK} : \PParams \to \Tx \to \UTxO \to \Bool  \\
    & \fun{feesOK}~\var{pp}~tx~utxo = \\
    &~~      \minfee{pp}{tx} \leq \txfee{tx} \wedge (\fun{txrdmrs}~tx \neq \Nothing \Rightarrow \\
    &~~~~~~((\forall (a, \wcard, \wcard) \in \fun{range}~(\fun{collInputs}~tx \restrictdom \var{utxo}), a \in \AddrVKey) \\
    &~~~~~~\wedge \fun{adaOnly}~\var{balance} \\
    &~~~~~~\wedge \var{balance} \geq \hldiff{\lceil \txfee{txb} * \fun{collateralPercent}~pp / 100 \rceil} \\
    &~~~~~~\wedge \hldiff{(\fun{txcoll}~tx \neq \Nothing) \Rightarrow \var{balance} = \fun{txcoll}~tx} \\
    &~~~~~~\wedge \fun{collInputs}~{tx} \neq \emptyset) \\
    &~~      \where \\
    & ~~~~~~~ \var{balance}=\hldiff{\fun{collBalance}~tx~utxo}
  \end{align*}
  \caption{Functions related to fees and collateral}
  \label{fig:functions:utxo}
\end{figure*}

\begin{figure*}
  \begin{align*}
    & \fun{getDatum} : \Tx \to \UTxO \to \ScriptPurpose \to \seqof{\Datum} \\
    & \fun{getDatum}~{tx}~{utxo}~{sp} =
      \begin{cases}
        [\var{d}] & \var{sp} \in \TxIn, (\_, \_, h, \_) \in \var{utxo}~\var{sp},~ \var{d}\in\fun{txdats}~(\fun{txwits}~tx)~\var{h} \\
        [\var{d}] & \hldiff{\var{sp} \in \TxIn, (\_, \_, d, \_) \in \var{utxo}~\var{sp},~ \var{d} \in \Datum} \\
        \epsilon  & \text{otherwise}
      \end{cases}
    \nextdef
    & \fun{txscripts} : \Tx \to \hldiff{\UTxO} \to \powerset{\Script} \\
    & \fun{txscripts}~tx~utxo = \fun{txwitscripts}~tx \cup \hldiff{\{ \fun{hash}~s \mapsto s \mid (\_, \_, \_, s) \in \var{utxo}~(\fun{spendInputs}~tx \cup \fun{refInputs}~tx)\}}
    \nextdef
    & \fun{languages} : \Tx \to \UTxO \to \powerset{\Language} \\
    & \fun{languages}~tx~utxo =
      \{\fun{language}~s \mid s \in \range (\fun{txscripts}~tx~utxo) \cap \ScriptPhTwo\}
    \nextdef
    & \fun{allowedLanguages} : \Tx \to \UTxO \to \powerset{\Language} \\
    & \fun{allowedLanguages}~tx~utxo = \\
    & \begin{cases}
        \emptyset                   & \text{if}~\exists (a, \_, \_, \_) \in os, a \in \AddrBS \\
        \{ \PlutusVII \}            & \text{if}~\exists (\_, \_, d, s) \in os, d \in \Datum \lor s \neq \Nothing \lor \fun{refInputs}~tx \neq \emptyset \\
        \{ \PlutusVI, \PlutusVII \} & \text{otherwise}
      \end{cases} \\
    & \where \var{os} = \range \txouts{tx} \cup \var{utxo}~(\fun{spendInputs}~tx \cup \fun{refInputs}~tx)
  \end{align*}
  \caption{Functions related to scripts}
  \label{fig:functions:data}
\end{figure*}

\begin{figure}[htb]
  \begin{equation}
    \inference[Scripts-Yes]
    {
    \var{txb}\leteq\txbody{tx} &
    \var{sLst} := \fun{collectTwoPhaseScriptInputs}~\var{pp}~\var{tx}~\var{utxo}
    \\
    ~
    \\
    \fun{isValid}~\var{tx} = \fun{evalScripts}~\var{tx}~\var{sLst} = \True
    \\~\\
    {
      \begin{array}{r}
        \var{slot} \\
        \var{pp} \\
        \var{genDelegs} \\
      \end{array}
    }
    \vdash \var{pup} \trans{\hyperref[fig:rules:update]{ppup}}{\fun{txup}~\var{tx}} \var{pup'}
    \\~\\
    \var{refunded} \leteq \keyRefunds{pp}{txb}
    \\
    \var{depositChange} \leteq
      (\fun{totalDeposits}~{pp}~\var{poolParams}~\txcerts{txb})~-~\var{refunded}
    }
    {
    \begin{array}{l}
      \var{slot}\\
      \var{pp}\\
      \var{poolParams}\\
      \var{genDelegs}\\
    \end{array}
      \vdash
      \left(
      \begin{array}{r}
        \var{utxo} \\
        \var{deposits} \\
        \var{fees} \\
        \var{pup} \\
      \end{array}
      \right)
      \trans{utxos}{tx}
      \left(
      \begin{array}{r}
        \varUpdate{\var{(\fun{spendInputs}~txb \subtractdom \var{utxo}) \cup \outs{txb}}}  \\
        \varUpdate{\var{deposits} + \var{depositChange}} \\
        \varUpdate{\var{fees} + \txfee{txb}} \\
        \varUpdate{\var{pup'}} \\
      \end{array}
      \right) \\
    }
  \end{equation}
  \begin{equation}
    \inference[Scripts-No]
    {
    \var{txb}\leteq\txbody{tx} &
    \var{sLst} := \fun{collectTwoPhaseScriptInputs}~\var{pp}~\var{tx}~\var{utxo} \\
    \hldiff{\var{collateralFees} := \fun{valueToCoin}~(\fun{collBalance}~txb~utxo)}
    \\
    ~
    \\
    \fun{isValid}~\var{tx} = \fun{evalScripts}~\var{tx}~\var{sLst} = \False
    }
    {
    \begin{array}{l}
      \var{slot}\\
      \var{pp}\\
      \var{poolParams}\\
      \var{genDelegs}\\
    \end{array}
      \vdash
      \left(
      \begin{array}{r}
        \var{utxo} \\
        \var{deposits} \\
        \var{fees} \\
        \var{pup} \\
      \end{array}
      \right)
      \trans{utxos}{tx}
      \left(
      \begin{array}{r}
        \varUpdate{\var{(\fun{collInputs}~{txb} \subtractdom \var{utxo})} \cup \hldiff{\fun{collOuts}~txb}}  \\
        \var{deposits} \\
        \varUpdate{\var{fees} + \hldiff{\var{collateralFees}}} \\
        \var{pup} \\
      \end{array}
      \right)
    }
  \end{equation}
  \caption{State update rules}
  \label{fig:rules:utxo-state-upd}
\end{figure}

\begin{figure}[htb]
  \begin{equation}
    \inference[UTxO-inductive]
    {
      \var{txb}\leteq\txbody{tx} &
      \fun{ininterval}~\var{slot}~(\fun{txvldt}~{txb}) &
      \var{(\wcard, i_f)}\leteq\fun{txvldt}~{tx} \\~\\
      \Nothing \notin \{\fun{txrdmrs}~\var{tx}, i_f\} \Rightarrow \fun{epochInfoSlotToUTCTime}~\mathsf{EI}~\mathsf{SysSt}~i_f \neq \Nothing \\
      \fun{spendInputs}~txb \neq \emptyset
      & \fun{feesOK}~pp~tx~utxo
      \\
      \fun{spendInputs}~txb \cup \fun{collInputs}~txb \cup \hldiff{\fun{refInputs}~{tx}} \subseteq \dom \var{utxo} \\
      \consumed{pp}{utxo}{txb} = \produced{pp}{poolParams}~{txb}
      \\~\\
      \mathsf{adaID}\notin \supp {\fun{mint}~tx} \\~\\
      \forall txout \in \txouts{txb}, \\
      \fun{getValue}~txout \geq \fun{inject}~(\hldiff{\lceil\fun{serSize}~txout * \fun{coinsPerUTxOWord}~pp/8\rceil}) \\~
      \\
      \forall txout \in \txouts{txb},\\
      \fun{serSize}~(\fun{getValue}~txout) \leq \fun{maxValSize}~pp \\~
      \\
      \forall (\wcard\mapsto (a,~\wcard)) \in \txouts{txb}, a \in \AddrBS \Rightarrow \fun{bootstrapAttrsSize}~a \leq 64 \\
      \forall (\wcard\mapsto (a,~\wcard)) \in \txouts{txb}, \fun{netId}~a = \NetworkId
      \\
      \forall (a\mapsto\wcard) \in \txwdrls{txb}, \fun{netId}~a = \NetworkId \\
      (\fun{txnetworkid}~\var{txb} = \NetworkId) \vee (\fun{txnetworkid}~\var{txb} = \Nothing)
      \\~\\
      \fun{txsize}~{tx}\leq\fun{maxTxSize}~\var{pp} \\~\\
      \fun{totExunits}~{tx} \leq \fun{maxTxExUnits}~{pp} &  \| \fun{collInputs}~{tx} \| \leq \fun{maxCollateralInputs}~{pp}
      \\
      ~
      \\
      {
        \begin{array}{c}
          \var{slot}\\
          \var{pp}\\
          \var{poolParams}\\
          \var{genDelegs}\\
        \end{array}
      }
      \vdash
      {
        \left(
          \begin{array}{r}
            \var{utxo} \\
            \var{deposits} \\
            \var{fees} \\
            \var{pup}\\
          \end{array}
        \right)
      }
      \trans{utxos}{\var{tx}}
      {
        \left(
          \begin{array}{r}
            \var{utxo'} \\
            \var{deposits'} \\
            \var{fees'} \\
            \var{pup'}\\
          \end{array}
        \right)
      }
    }
    {
      \begin{array}{l}
        \var{slot}\\
        \var{pp}\\
        \var{poolParams}\\
        \var{genDelegs}\\
      \end{array}
      \vdash
      \left(
      \begin{array}{r}
        \var{utxo} \\
        \var{deposits} \\
        \var{fees} \\
        \var{pup}\\
      \end{array}
      \right)
      \trans{utxo}{tx}
      \left(
      \begin{array}{r}
        \varUpdate{\var{utxo'}}  \\
        \varUpdate{\var{deposits'}} \\
        \varUpdate{\var{fees'}} \\
        \varUpdate{\var{pup'}}\\
      \end{array}
      \right)
    }
  \end{equation}
  \caption{UTxO inference rules}
  \label{fig:rules:utxo-babbage}
\end{figure}

To the UTXOW rule, in addition to the changes required by the new
features, we add a check that all scripts and datums involved in the
transaction are well-formed. Also, we forbid transactions that use the
new features and try to use $\PlutusVI$ scripts.

\begin{figure}
  \begin{equation}
    \label{eq:utxo-witness-inductive-babbage}
    \inference[UTxO-witG]
    {
      \var{txb}\leteq\txbody{tx} &
      \var{txw}\leteq\fun{txwits}~{tx} \\
      (utxo, \wcard, \wcard, \wcard) \leteq \var{utxoSt} \\
      \var{witsKeyHashes} \leteq \{\fun{hashKey}~\var{vk} \vert \var{vk} \in
      \dom (\txwitsVKey{txw}) \}\\
      \var{inputHashes}\leteq \left\{ h \,\middle|
        {
          \begin{array}{l}
            (a, \_, h) \in \range(\var{utxo}|_{\fun{spendInputs}~tx}) \\
            \fun{isTwoPhaseScriptAddress}~tx~\hldiff{utxo}~a \\
          \end{array}
        }
      \right\} \cap \hldiff{\DataHash} \\~\\
      \forall \var{s} \in \range (\fun{txscripts}~txw~\hldiff{utxo}) \cap \ScriptPhOne,
      \fun{validateScript}~\var{s}~\var{tx}\\~\\
      \{ h \mid (\_, h) \in \fun{scriptsNeeded}~\var{utxo}~txb\} = \dom (\fun{txscripts}~txw~\hldiff{utxo}) \\~\\
      \var{inputHashes} \subseteq \dom (\fun{txdats}~{txw}) \\~\\
      \dom (\fun{txdats}~{txw}) \subseteq \var{inputHashes} \cup \{h \mid (\wcard, \wcard, h)\in\fun{txouts}~{tx} \cup \hldiff{\var{utxo}~(\fun{refInputs}~{tx})}\}
      \\~\\
      \dom (\fun{txrdmrs}~tx) = \left\{ \fun{rdptr}~txb~sp \,\middle|
        {
          \begin{array}{l}
            (sp,h) \in \fun{scriptsNeeded}~\var{utxo}~txb \\
            \fun{txscripts}~{txw}~\hldiff{utxo}~h \in \ScriptPhTwo
          \end{array}
        } \right\}
      \\~\\
      \var{txbodyHash}\leteq\fun{hash}~(\txbody{tx}) \\
      \forall \var{vk} \mapsto \sigma \in \txwitsVKey{tx},
      \mathcal{V}_{\var{vk}}{\serialised{txbodyHash}}_{\sigma} \\
      \fun{witsVKeyNeeded}~{utxo}~{tx}~{genDelegs} \subseteq witsKeyHashes
      \\~\\
      genSig \leteq
      \left\{
        \fun{hashKey}~gkey \vert gkey \in\dom{genDelegs}
      \right\}
      \cap
      \var{witsKeyHashes}
      \\
      \left\{
        c\in\txcerts{txb}~\cap\DCertMir
      \right\} \neq\emptyset \implies \vert genSig\vert \geq \Quorum \wedge
      \fun{d}~\var{pp} > 0
      \\~\\
      \var{adh}\leteq\fun{txADhash}~\var{txb}
      &
      \var{ad}\leteq\fun{auxiliaryData}~\var{tx}
      \\
      (\var{adh}=\Nothing \land \var{ad}=\Nothing)
      \lor
      (\var{adh}=\fun{hashAD}~\var{ad})
      \\~\\
      \hldiff{\forall x \in \range (\fun{txdats}~txw) \cup \range (\fun{txwitscripts}~txw) \cup \bigcup_{(\_, \_, d, s) \in \txouts{tx}} \{s, d\},} \\
      \hldiff{x \in \Script \cup \Datum \Rightarrow \fun{isWellFormed}~x}
      \\~\\
      \fun{languages}~tx~\hldiff{utxo} \subseteq \dom(\fun{costmdls}~pp) \cap \fun{allowedLanguages}~tx~utxo \\
      \fun{scriptIntegrityHash}~{txb} =
      \fun{hashScriptIntegrity}~\var{pp}~(\fun{languages}~{txw})~(\fun{txrdmrs}~{txw})~(\fun{txdats}~{txw})
      \\~\\
      {
        \begin{array}{r}
          \var{slot}\\
          \var{pp}\\
          \var{poolParams}\\
          \var{genDelegs}\\
        \end{array}
      }
      \vdash \var{utxoSt} \trans{\hyperref[fig:rules:utxo-shelley]{utxo}}{tx}
      \var{utxoSt'}\\
    }
    {
      \begin{array}{r}
        \var{slot}\\
        \var{pp}\\
        \var{poolParams}\\
        \var{genDelegs}\\
      \end{array}
      \vdash \var{utxoSt} \trans{utxow}{tx} \varUpdate{\var{utxoSt'}}
    }
  \end{equation}
  \caption{UTxO with witnesses inference rules for Tx}
  \label{fig:rules:utxow-babbage}
\end{figure}


\chapter{Mesh and Element Configuration} \label{chap:meshconfig}

 \NOTE{This description has not been updated for ViennaGrid 1.1.0 yet!}

A mesh and all its topological elements as well as the underlying geometric space are specified in a common configuration class.
The setup of such a configuration class is explained in detail in Section \ref{sec:config-class}.

Even though mathematically all $n$-cells of a mesh are well defined and available on paper, it may not make sense to store explicit representations of these elements in memory.
As discussed in the Introduction, a particular algorithm may not require the storage of edges and/or facets of a mesh, thus keeping these elements in memory can be a considerable waste of resources.
Section \ref{sec:customizing-storage} explains how the underlying storage scheme of {\ViennaGrid} can be adjusted to the library user's requirements and to be as memory-efficient as possible.

\section{The Configuration Class} \label{sec:config-class}
A valid configuration class for {\ViennaGrid} is any class that provides the following three public member types:
\begin{center}
\begin{tabular}{|l|p{8cm}|}
\hline
 \lstinline|numeric_type|   & The underlying scalar type of the geometric space. \\
\hline
 \lstinline|coordinate_system_tag| & A tag specifying the underlying coordinate system.\\
\hline
 \lstinline|cell_tag|       & A tag that identifies the cell type inside the mesh.\\
\hline
\end{tabular}
\end{center}

More details on the types are given in the following:
\begin{itemize}
 \item \lstinline|numeric_type|: This refers to the type of the coordinates of a point in the geometric space. In most cases, one may want to use \lstinline|double|. However, it may also be the case that the user prefers to use integer coordinates, or high-precision floating point libraries such as ARPREC \cite{arprec}.

 \item \lstinline|coordinate_system_tag|: Any of the following predefined classes from namespace \lstinline|viennagrid| can be defined as \lstinline|coordinate_system_tag| to select the coordinate system of the underlying geometric space:
   \begin{center}
   \begin{tabular}{|l|l|}
    \hline
    \lstinline|cartesian_cs<dim>|   &  Cartesian coordinate system of dimension \lstinline|dim| \\
    \hline
    \lstinline|polar_cs|       &  Polar coordinate system in two dimensions \\
    \hline
    \lstinline|spherical_cs|   &  Spherical coordinates in three dimensions \\
    \hline
    \lstinline|cylindrical_cs| &  Cylindrical coordinates in three dimensions \\
    \hline
   \end{tabular}
   \end{center}

 \item \lstinline|cell_tag|: A tag that specifies the type of the elements with maximum topological dimension in the mesh. The following two families of topological elements are provided with {\ViennaGrid} in namespace \lstinline|viennagrid|:
   \begin{center}
   \begin{tabular}{|l|l|}
    \hline
    \lstinline|simplex<n>|     &  Refers to an $n$-simplex \\
    \hline
    \lstinline|hypercube<n>|   &  Refers to an $n$-hypercube \\
    \hline
   \end{tabular}
   \end{center}
 It should be noted that \lstinline|simplex<1>| and \lstinline|hypercube<1>| both refer to a line segment. Typical examples from these families for common values of $n$ are as follows:
\begin{center}
 \begin{tabular}{|l|c|c|}
  \hline
          & {\ViennaGrid} tag type   & Convenience \lstinline|typedef| \\
  \hline
  Vertex  & \lstinline|point_tag|    &  - \\
  \hline
  Line    & \lstinline|simplex_tag<1>|   & \lstinline|line_tag| \\
  Line    & \lstinline|hypercube_tag<1>| & - \\
  \hline
  Triangle & \lstinline|simplex_tag<2>|  & \lstinline|triangle_tag| \\
  Quadrilateral & \lstinline|hypercube_tag<2>| & \lstinline|quadrilateral_tag| \\
  \hline
  Tetrahedron & \lstinline|simplex_tag<3>| & \lstinline|tetrahedron_tag| \\
  Hexahedron & \lstinline|hypercube_tag<3>| & \lstinline|hexahedron_tag| \\
  \hline
 \end{tabular}
\end{center}
 The reference orientations of these cells can be found in Appendix \ref{chap:orientations}.
\end{itemize}

All geometric and topological types inside the mesh are then derived from the configuration class. To this end, {\ViennaGrid} provides
a number of meta-functions that reside in namespace \lstinline|viennagrid::result_of|. The naming follows the conventions in the Boost libraries \cite{boost}.
For a configuration class \lstinline|Config|, the respective types are obtained as follows:
\begin{lstlisting}
 using namespace viennagrid;

 typedef result_of::mesh<Config>::type     MeshType;
 typedef result_of::segment<Config>::type    SegmentType;
 typedef result_of::ncell<Config, 0>::type   VertexType;
 typedef result_of::ncell<Config, 1>::type   EdgeType;
\end{lstlisting}
In particular, the type of any $n$-cell in the mesh is obtained as
\begin{lstlisting}
 typedef result_of::ncell<Config, n>::type   ElementType;
\end{lstlisting}
where $n$ has to be replaced with the respective value. This allows to formulate algorithms such as a mesh boundary detection in a very general manner and can be used for recursively iterating through the $n$-cells of different dimension. In order to obtain the types of cells and facets, one should use the topological dimension from the cell tag:
\begin{lstlisting}
 typedef Config::cell_tag                                CellTag;
 typedef result_of::ncell<Config, CellTag::dim-1>::type  FacetType;
 typedef result_of::ncell<Config, CellTag::dim>::type    CellType;
\end{lstlisting}

\TIP{Please note that in template classes and template functions one needs to add an extra \lstinline|typename| after each \lstinline|typedef| keyword in the code snippets above.}

{\ViennaGrid} ships with a number of default configurations, which can directly be used without the need for setting up a separate config class:
\begin{center}
 \begin{tabular}{|l|l|}
  \hline
   Class Name           & Description \\
  \hline
   \lstinline|line_1d|  & one-dimensional mesh \\
   \lstinline|line_2d|  & mesh of lines in 2d \\
   \lstinline|line_3d|  & mesh of lines in 3d \\
   \lstinline|triangular_2d| & triangular mesh in 2d \\
   \lstinline|triangular_3d| & triangular mesh in 3d \\
   \lstinline|tetrahedral_3d| & tetrahedral mesh in 2d \\
   \lstinline|quadrilateral_2d| & quadrilateral mesh in 2d \\
   \lstinline|quadrilateral_3d| & quadrilateral mesh in 3d \\
   \lstinline|hexahedral_3d| & hexahedral mesh in 2d \\
  \hline
 \end{tabular}
\end{center}
The classes reside in namespace \lstinline|viennagrid::config| and in the files \lstinline|simplex.hpp| and \lstinline|others.hpp| (for non-simplex meshes) in the \lstinline|viennagrid/config| folder.
Each of these configurations uses a numeric type \lstinline|double| and a Cartesian coordinate system.

\section{Customizing Storage of $n$-Cells} \label{sec:customizing-storage}
One of the outstanding features of {\ViennaGrid} over other libraries related to grid handling is the possibility to customize the internal storage of elements. By default, all $n$-cells of a mesh are stored explicitly inside the mesh. In addition, each $n$-cell stores links to its boundary $k$-cells, with $k<n$. While this overhead is not a concern for topologically one-dimensional meshes and moderate for topologically two-dimensional meshes, it can be a considerable issue for dimensions three and above.

As an example, linear finite elements need information about the cells and the vertices inside the mesh, while edges and facets may not be needed depending on the boundary conditions imposed.

\begin{table}[tb]
 \centering
 \begin{tabular}{|l|r|r|r|}
  \hline
         & Amount      & Bytes/Object         & Total Memory \\
  \hline
  Vertices & 4913 & 24 & 115 KB \\
  \hline
  Edges   & 31024 & 16 & 485 KB \\
  \hline
  Facets  & 50688 & 48 & 2376 KB \\
  \hline
  Cells   & 24576 & 112 & 2688 KB \\
  \hline
  \textbf{Total}  &       &     &  \textbf{5664 KB} \\
  \hline
 \end{tabular}
 \caption{Minimum memory consumption for a tetrahedral mesh of the unit cube where all $n$-cells are stored explicitly and boundary information on each $n$-cell is stored. Vertices use \lstinline|double|-precision coordinates and elements are linked with pointers sized eight bytes each.}
 \label{tab:full-mesh-memory}
\end{table}

\begin{table}[tb]
 \centering
 \begin{tabular}{|l|r|r|r|}
  \hline
         & Amount      & Bytes/Object         & Total Memory \\
  \hline
  Vertices & 4913 & 24 & 115 KB \\
  \hline
  Edges   & 0 & - & 0 KB \\
  \hline
  Facets  & 0 & - & 0 KB \\
  \hline
  Cells   & 24576 & 32 & 768 KB \\
  \hline
  \textbf{Total}  &       &     &  \textbf{883 KB} \\
  \hline
 \end{tabular}
 \caption{Minimum memory consumption for a tetrahedral mesh of the unit cube where only $0$-cells and $3$-cells are stored explicitly. $3$-cells have knowledge of their $0$-cells only. Vertices use \lstinline|double|-precision coordinates and elements are linked with pointers sized eight bytes each.}
 \label{tab:slim-mesh-memory}
\end{table}

As shown in Tab.~\ref{tab:full-mesh-memory} and Tab.~\ref{tab:slim-mesh-memory}, storing facets and edges explicitly increases the total memory consumption by a factor of more than six. In cases where additional maps for the mapping from local to global $n$-cell orientations are stored together with the topological boundary information, the difference in memory consumption is even higher.

{\ViennaGrid} can be customized to switch seamlessly between the different storage models, as will be shown in the following subsections.

\NOTE{Note that in {\ViennaGrid} a cell always stores pointers to its vertices. Similarly, the mesh always stores the cells and vertices.}

\subsection{Boundary $n$-Cells} \label{subsec:boundary-ncells-storage}

Disabling the storage of boundary $n$-cells can be achieved in two ways, which are equivalent on a source-code level, but differ with respect to convenience:
\begin{itemize}
 \item \textbf{Method 1}: Use the provided macros. The storage of elements can be customized either for a particular configuration class, or globally for all mesh configuration classes. To disable the storage of edges (i.e.~$1$-cells) inside a tetrahedron for a mesh with configuration class \lstinline|MyConfig|, the line
  \begin{lstlisting}
VIENNAGRID_DISABLE_BOUNDARY_NCELL(MyConfig,
                                  viennagrid::tetrahedron_tag, 1)
  \end{lstlisting}
right after the {\ViennaGrid}-includes in the source file containing \lstinline|main()| is sufficient. Make sure that the macro is placed in the global namespace. The first argument is the configuration class, the second class is the tag for the respective $n$-cell for which the boundary element should be disabled, and the third parameter is the topological dimension for which the handling should be disabled.
 If no edges should be stored for a tetrahedron irrespective of the configuration class, the macro
  \begin{lstlisting}
VIENNAGRID_GLOBAL_DISABLE_BOUNDARY_NCELL(viennagrid::tetrahedron_tag,
                                         1)
  \end{lstlisting}
 should be used. If one wishes to selectively enable the handling of boundary cells within a globally disabled storage of boundary $n$-cells, one can use e.g.
  \begin{lstlisting}
VIENNAGRID_ENABLE_BOUNDARY_NCELL(MyConfig,
                                 viennagrid::tetrahedron_tag, 1)
  \end{lstlisting}
 to enable the storage of edges inside a tetrahedron for a configuration class \lstinline|MyConfig|.

 \item \textbf{Method 2}: The macros above are shortcuts for class specializations. The first two macros expand to the following code:
\begin{lstlisting}
namespace viennagrid { namespace result_of {
    template <>
    struct bndcell_handling<MyConfig,
                            viennagrid::tetrahedron_tag, 1>{
      typedef no_handling_tag    type;
    };

    template <typename ConfigType>
    struct bndcell_handling<ConfigType,
                            viennagrid::tetrahedron_tag, 1>{
      typedef no_handling_tag    type;
    };
} }
\end{lstlisting}
The third macro explained for method 1 results in the same code as the first macro, with the exception that \lstinline|no_handling_tag| is replaced with \lstinline|full_handling_tag|.

Finally, we wish to point at a potential pitfall when disabling $n$-cells that are neither $0$-cells, $N-1$-cells, nor $N$-cells: Consider the case of disabling edges for a tetrahedron. Using the line
  \begin{lstlisting}
VIENNAGRID_DISABLE_BOUNDARY_NCELL(MyConfig,
                                  viennagrid::tetrahedron_tag, 1)
  \end{lstlisting}
only disables the edges for the tetrahedron, but still edges are pushed and stored inside the mesh, because the triangular facets of the tetrahedron store pointers to their edges. Thus, to completely disable the storage of any edges, one also has to disable the storage of edges for triangles. As a check, one should verify that the number of edges stored inside a mesh \lstinline|my_mesh| and obtained by
 \begin{lstlisting}
  viennagrid::ncells<1>(my_mesh).size()
 \end{lstlisting}
is zero.

\TIP{Have a look at \texttt{examples/tutorial/slim\_mesh.cpp} and selectively enable or disable the storage of elements to see the impact on total memory consumption. Note that the bytes per object may differ from Tab.~\ref{tab:full-mesh-memory} and Tab.~\ref{tab:slim-mesh-memory} depending on the use of local-to-global-orienters and the eventual use of integral IDs.}

\subsection{Local Orientations} \label{subsec:customize-local-orientations}
\begin{figure}[tb]
\centering
 \includegraphics[width=0.5\textwidth]{figures/interface-tets.eps}
 \caption{Boundary $n$-cells have different orientations with respect to different cells.}
 \label{fig:orientation-boundary-ncells}
\end{figure}

In cases where $n$-cells store boundary $k$-cells, $k<n$, it may be required to know the orientation of the globally (i.e.~in the mesh) stored $k$-cell with respect to the local reference orientation of the $n$-cell. The common facet of the two tetrahedra in Fig.~\ref{fig:orientation-boundary-ncells} may be stored globally using the sequence of vertex indices $[1, 2, 3]$. Inside the tetrahedron $[0, 1, 2, 3]$ the facet again possesses the orientation $[1, 2, 3]$, thus matching the global orientation. However, within the tetrahedron $[4, 2, 1, 3]$ the facet has the local orientation $[2, 1, 3]$ (refer to the Appendix for an overview of reference orientations). For applications such as high-order finite elements, such a local orientation with respect to the cell is required.

By default, {\ViennaGrid} stores the local orientation of each boundary $k$-cell inside the hosting $n$-cell, where one byte per vertex of each $k$-cell is consumed. In order to disable the storage of these local orientations for scenarios where the local orientation is not needed, there are again two methods provided:
\begin{itemize}
 \item \textbf{Method 1}: Using the macros provided. To disable the storage of local orientations of edges (i.e.~$1$-cells) inside a tetrahedron for a mesh with configuration class \lstinline|MyConfig|, the line
\begin{lstlisting}
VIENNAGRID_DISABLE_BOUNDARY_NCELL_ORIENTATION(MyConfig,
                              viennagrid::tetrahedron_tag, 1)
\end{lstlisting}
is sufficient. The second argument denotes the hosting $n$-cell tag, while the third argument denotes the topological dimension $k$ of the boundary $k$-cells.

Similar to the previous section, one can disable the storage of local orientations globally for all configuration classes by
\begin{lstlisting}
VIENNAGRID_GLOBAL_DISABLE_BOUNDARY_NCELL_ORIENTATION(
                              viennagrid::tetrahedron_tag, 1)
\end{lstlisting}
To selectively enable the storage of local orientations in a globally disabled setting, the macro \lstinline|VIENNAGRID_ENABLE_BOUNDARY_NCELL_ORIENTATION| can be used in the same way as \lstinline|VIENNAGRID_DISABLE_BOUNDARY_NCELL_ORIENTATION|.
Again, it is recommended to define the macros in the source file containing \lstinline|main()| after the inclusion of the {\ViennaGrid} header files.

 \item \textbf{Method 2}: Instead of using the macros, one may manually adjust the meta-function \lstinline|bndcell_orientation|. The first macro of method 1 expands to
 \begin{lstlisting}
namespace viennagrid { namespace result_of {
  template <>
  struct bndcell_orientation<MyConfig,
                             viennagrid::tetrahedron_tag, 1>
  {  typedef no_handling_tag    type;  };
}  }
 \end{lstlisting}
Using the type \lstinline|full_handling_tag| instead of \lstinline|no_handling_tag| enables the storage of local orientations.
\end{itemize}

\TIP{If the storage of boundary $k$-cells is disabled (cf.~Sec.~\ref{subsec:boundary-ncells-storage}), there are automatically no local orientations for boundary $k$-cells stored. The local orientations do not need to be disabled explicitly in this case.}

\subsection{$n$-Cell IDs} \label{subsec:ncell-ids}
It is often convenient to have enumerated $n$-cells within a mesh such that every $n$-cell is aware of its index inside the random access container it resides in. This allows for some algorithms to use fast random-accesses with $\LandauO(1)$ costs rather than searching trees with $\LandauO(\log N)$ costs or linked lists with $\LandauO(N)$ costs, where $N$ here denotes the number of $n$-cells inside the mesh. Conversely, if $\LandauO(\log N)$ access times are acceptable, then the memory for storing the container index (which we refer to in the following as \emph{$n$-cell ID}) is wasted. To accommodate for these two scenarios, {\ViennaGrid} allows to selectively enable or disable the storage of $n$-cell IDs. By default, $n$-cell IDs are stored, since they have negligible impact on the total memory consumption as soon as other boundary $k$-cells are stored for an $n$-cell.

As for the storage of boundary $k$-cells and local orientations, there are two possibilities for customizing the storage of IDs:
\begin{itemize}
 \item \textbf{Method 1}: Using the provided macros. To disable the storage of IDs for tetrahedrons inside a mesh with configuration \lstinline|MyConfig|, the line
 \begin{lstlisting}
VIENNAGRID_DISABLE_NCELL_ID(viennagrid::config::tetrahedral_3d,
                            viennagrid::tetrahedron_tag)
 \end{lstlisting}
 is sufficient. The second argument denotes the element tag for which the storage of IDs should be disabled.

 To globally disable the storage of IDs for tetrahedrons, use
 \begin{lstlisting}
VIENNAGRID_GLOBAL_DISABLE_NCELL_ID(viennagrid::tetrahedron_tag)
 \end{lstlisting}
 To selectively enable the storage of IDs for certain configuration classes in a globally disabled setting, one can use
 \begin{lstlisting}
VIENNAGRID_ENABLE_NCELL_ID(viennagrid::config::tetrahedral_3d,
                           viennagrid::tetrahedron_tag)
 \end{lstlisting}

 \item \textbf{Method 2}:
The macros from the first method expand to
\begin{lstlisting}
template <>
struct element_id_handler<MyConfig, viennagrid::tetrahedron_tag>
{  typedef pointer_id    type;  };
\end{lstlisting}
for the configuration class \lstinline|MyConfig|, and to
\begin{lstlisting}
template <typename ConfigType>
struct element_id_handler<ConfigType, viennagrid::tetrahedron_tag>
{  typedef pointer_id    type;  };
\end{lstlisting}
for globally disabling the storage of IDs. To selectively enable IDs, \lstinline|integral_id| should be used instead of \lstinline|pointer_id|.

\end{itemize}

\TIP{Have a look at \texttt{examples/tutorial/slim\_mesh.cpp} and selectively enable or disable the storage of elements, local orientations and IDs to see the impact on total memory consumption. Note that the bytes per object may differ from Tab.~\ref{tab:full-mesh-memory} and Tab.~\ref{tab:slim-mesh-memory} depending on the use of local orientations and integral IDs.}

\NOTE{Disabling $n$-cell IDs eliminates the possibility to store and access data for the respective $n$-cells with $\LandauO(1)$ costs, see Chapter \ref{chap:data}.}

\end{itemize}


\chapter{Introduction}

The \numbers\ program is a shell program which reads and stores data
from a finite element model described in the \exo\ database
format~\cite{EXODUS}.
Within this shell program are several utility routines which calculate
information about the finite element model.  The utilities currently
implemented in \numbers\ allow the analyst to determine:
\begin{itemize}
\item the volume and coordinate limits of each of the materials in the model;
\item the mass properties of the model;
\item the minimum, maximum, and average element volumes for each material;
\item the volume and change in volume of a cavity;
\item the nodes or elements that are within a specified distance from a
user-defined point, line, or plane;
\item an estimate of the explicit central-difference timestep for each
material;
\item the validity of contact surfaces or slidelines, that is, whether
two surfaces overlap at any point; and
\item the distance between two surfaces.
\end{itemize}

These utilities have been developed to automate and simplify some of the
tasks normally performed during an analysis.  The \numbers\ program
reads the finite element model and results from a file written in the
\exo\ binary file format which is used in the Engineering
Analysis Department at \SNLA.

The capabilities of \numbers\ have evolved during the past eighteen
months.  Originally, it was written solely to calculate the mass
properties of a body.  However, once the basic function of reading and
storing an \exo\ database was in place, it was realized that several
tasks that were usually performed manually could easily be implemented
in \numbers.  Tasks such as determining node and element numbers,
verifying contact surfaces, and others, are now performed more
efficiently and, hopefully, more accurately since the code performs the
repetitive calculations automatically.

Although the original reason for developing \numbers\ was to simply
calculate mass properties, the code now functions as an \exo\ shell that
can be easily extended by analysts who require specific calculations or
need to create information not currently available.  The analyst can
simply write a subroutine to perform their function, and insert it into
\numbers\ without worrying about the details of reading an \exo\
database and providing a user interface. For most cases, adding a
function to \numbers\ requires only writing the function subroutine,
adding the command name to the table of valid commands, and adding a few
statements to call the routine.

The remainder of this report is organized as follows.
Chapter~\ref{c:numerics} describes the numerical algorithms used by the
utility functions in \numbers.  A list of the commands and the command
syntax are presented in Chapter~\ref{c:commands}.
Chapter~\ref{c:examples} gives several examples of the use of the
utilities, and Chapter~\ref{c:conclude} concludes the report.  Three
appendixes are included.  Appendix~\ref{a:cmdsum} is a summary of the
command syntax for each of the commands.

The descriptions in the following chapters assume that the reader is
familiar with the \gen\ and \exo\ file formats and with the analysis,
preprocessing, and postprocessing codes used in the Engineering Analysis
Department at \SNLA.  Readers not familiar with these can check the
references at the end of this report for a list of the documentation for
these codes and file formats.