summaryrefslogtreecommitdiff
path: root/doc/ReferenceManual
diff options
context:
space:
mode:
authorjthorn <jthorn@17b73243-c579-4c4c-a9d2-2d5706c11dac>2003-07-20 11:02:41 +0000
committerjthorn <jthorn@17b73243-c579-4c4c-a9d2-2d5706c11dac>2003-07-20 11:02:41 +0000
commitfedfdaf24fef7513ccc1220f7f85906081c96ab2 (patch)
treec3590b113f643c442ba35ced3921cc29353b4c1f /doc/ReferenceManual
parentf4c4cc7009600c75afb98fed689bd3707661aaf0 (diff)
initial draft of Cactus Reference Manual
FunctionReference.tex copied from ../UsersGuide/FunctionReference.tex; see there for older CVS history git-svn-id: http://svn.cactuscode.org/flesh/trunk@3325 17b73243-c579-4c4c-a9d2-2d5706c11dac
Diffstat (limited to 'doc/ReferenceManual')
-rw-r--r--doc/ReferenceManual/FunctionReference.tex10852
-rw-r--r--doc/ReferenceManual/Preface.tex111
-rw-r--r--doc/ReferenceManual/ReferenceManual.tex89
3 files changed, 11052 insertions, 0 deletions
diff --git a/doc/ReferenceManual/FunctionReference.tex b/doc/ReferenceManual/FunctionReference.tex
new file mode 100644
index 00000000..df7eb0c3
--- /dev/null
+++ b/doc/ReferenceManual/FunctionReference.tex
@@ -0,0 +1,10852 @@
+% /*@@
+% @file FunctionReference.tex
+% @date 27 Jan 1999
+% @author Tom Goodale, Gabrielle Allen, Gerd Lanferman
+% @desc
+% Function Reference for the Cactus User's Guide
+% @enddesc
+% @version $Header$
+% @history
+% @date Sat Nov 3 18:47:53 MET 2001
+% @author Jonathan Thornburg <jthorn@aei.mpg.de>
+% @desc Add new section for Utility functions,
+% add key/value table functions in that section
+% @endhistory
+% @@*/
+
+\begin{cactuspart}{FunctionReference}{$RCSfile$}{$Revision$}
+\label{part:FunctionReference}
+\renewcommand{\thepage}{\Alph{part}\arabic{page}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Cactus Functions}
+
+In this section all \hbox{{\tt CCTK\_}*} Cactus functions are described.
+These functions are callable from Fortran or C thorns. Note that whereas
+all functions are available from C, not all are currently available
+from Fortran.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Functions Alphabetically}
+
+\begin{Lentry}
+
+\item[CCTK\_Abort]
+ [\pageref{CCTK-Abort}]
+ Causes abnormal Cactus termination
+
+\item[CCTK\_ActiveTimeLevels]
+ [\pageref{CCTK-ActiveTimeLevels}]
+ Returns the number of active timelevels from a group name
+
+\item[CCTK\_ActiveTimeLevelsGN]
+ [\pageref{CCTK-ActiveTimeLevels}]
+ Returns the number of active timelevels from a group name
+
+\item[CCTK\_ActiveTimeLevelsGI]
+ [\pageref{CCTK-ActiveTimeLevels}]
+ Returns the number of active timelevels from a group index
+
+\item[CCTK\_ActiveTimeLevelsVN]
+ [\pageref{CCTK-ActiveTimeLevels}]
+ Returns the number of active timelevels from a variable name
+
+\item[CCTK\_ActiveTimeLevelsVI]
+ [\pageref{CCTK-ActiveTimeLevels}]
+ Returns the number of active timelevels from a variable index
+
+\item[CCTK\_ArrayGroupSize]
+ [\pageref{CCTK-ArrayGroupSize}]
+ Returns a pointer to the local size for a group, given by its group name
+
+\item[CCTK\_ArrayGroupSizeI]
+ [\pageref{CCTK-ArrayGroupSizeI}]
+ Returns a pointer to the local size for a group, given by its group index
+
+\item[CCTK\_Barrier]
+ [\pageref{CCTK-Barrier}]
+ Synchronizes all processors
+
+\item[CCTK\_Cmplx]
+ [\pageref{CCTK-Cmplx}]
+ Turns two real numbers into a complex number (only C)
+
+\item[CCTK\_CmplxAbs]
+ [\pageref{CCTK-CmplxAbs}]
+ Returns the absolute value of a complex number (only C)
+
+\item[CCTK\_CmplxAdd]
+ [\pageref{CCTK-CmplxAdd}]
+ Returns the sum of two complex numbers (only C)
+
+\item[CCTK\_CmplxConjg]
+ [\pageref{CCTK-CmplxConjg}]
+ Returns the complex conjugate of a complex number (only C)
+
+\item[CCTK\_CmplxCos]
+ [\pageref{CCTK-CmplxCos}]
+ Returns the Cosine of a complex number (only C) [not yet available]
+
+\item[CCTK\_CmplxDiv]
+ [\pageref{CCTK-CmplxDiv}]
+ Returns the division of two complex numbers (only C)
+
+\item[CCTK\_CmplxExp]
+ [\pageref{CCTK-CmplxExp}]
+ Returns the Exponentiation of a complex number (only C) [not yet available]
+
+\item[CCTK\_CmplxImag]
+ [\pageref{CCTK-CmplxImag}]
+ Returns the imaginary part of a complex number (only C)
+
+\item[CCTK\_CmplxLog]
+ [\pageref{CCTK-CmplxLog}]
+ Returns the Logarithm of a complex number (only C) [not yet available]
+
+\item[CCTK\_CmplxMul]
+ [\pageref{CCTK-CmplxMul}]
+ Returns the multiplication of two complex numbers (only C)
+
+\item[CCTK\_CmplxReal]
+ [\pageref{CCTK-CmplxReal}]
+ Returns the real part of a complex number (only C)
+
+\item[CCTK\_CmplxSin]
+ [\pageref{CCTK-CmplxSin}]
+ Returns the Sine of a complex number (only C) [not yet available]
+
+\item[CCTK\_CmplxSqrt]
+ [\pageref{CCTK-CmplxSqrt}]
+ Returns the square root of a complex number (only C) [not yet available]
+
+\item[CCTK\_CmplxSub]
+ [\pageref{CCTK-CmplxSub}]
+ Returns the subtraction of two complex numbers (only C)
+
+\item[CCTK\_CoordDir]
+ [\pageref{CCTK-CoordDir}]
+ Give the direction for a given coordinate name.
+
+\item[CCTK\_CoordIndex]
+ [\pageref{CCTK-CoordIndex}]
+ Give the grid variable index for a given coordinate.
+
+\item[CCTK\_CoordRange]
+ [\pageref{CCTK-CoordRange}]
+ Return the global upper and lower bounds for a given coordinate name on a cctkGH
+
+\item[CCTK\_CoordRegisterData]
+ [\pageref{CCTK-CoordRegisterData}]
+ Register a coordinate as belonging to a coordinate system, with a given name and direction, and
+ optionally with a grid variable
+
+\item[CCTK\_CoordRegisterRange]
+ [\pageref{CCTK-CoordRegisterRange}]
+ Saves the global upper and lower bounds for a given coordinate name on a cctkGH
+
+\item[CCTK\_CoordRegisterSystem]
+ [\pageref{CCTK-CoordRegisterSystem}]
+ Registers a coordinate system with a given dimension
+
+\item[CCTK\_CoordSystemDim]
+ [\pageref{CCTK-CoordDim}]
+ Provides the dimension of a given coordinate system
+
+\item[CCTK\_CoordSystemHandle]
+ [\pageref{CCTK-CoordSystemHandle}]
+ Get the handle associated with a registered coordinate system
+
+\item[CCTK\_CoordSystemName]
+ [\pageref{CCTK-CoordSystemName}]
+ Provides the name of the coordinate system identified by its handle
+
+\item[CCTK\_CreateDirectory]
+ [\pageref{CCTK-CreateDirectory}]
+ Creates a directory
+
+\item[CCTK\_DecomposeName]
+ [\pageref{CCTK-DecomposeName}]
+ Given the full name of a variable/group, separates the name returning both the implementation and the variable/group
+
+\item[CCTK\_DisableGroupComm]
+ [\pageref{CCTK-DisableGroupComm}]
+ Disable the communication for a group
+
+\item[CCTK\_DisableGroupCommI]
+ [\pageref{CCTK-DisableGroupCommI}]
+ Disable the communication for a group
+
+\item[CCTK\_DisableGroupStorage]
+ [\pageref{CCTK-DisableGroupStorage}]
+ Disable the storage for a group
+
+\item[CCTK\_DisableGroupStorageI]
+ [\pageref{CCTK-DisableGroupStorageI}]
+ Disable the storage for a group
+
+\item[CCTK\_EnableGroupComm]
+ [\pageref{CCTK-EnableGroupComm}]
+ Enable the communication for a group
+
+\item[CCTK\_EnableGroupCommI]
+ [\pageref{CCTK-EnableGroupComm}]
+ Enable the communication for a group
+
+\item[CCTK\_EnableGroupStorage]
+ [\pageref{CCTK-EnableGroupStorage}]
+ Enable the storage for a group
+
+\item[CCTK\_EnableGroupStorageI]
+ [\pageref{CCTK-EnableGroupStorage}]
+ Enable the storage for a group
+
+\item[CCTK\_Equals]
+ [\pageref{CCTK-Equals}]
+ Check a STRING or KEYWORD parameter for equality equality with a given string
+
+\item[CCTK\_Exit]
+ [\pageref{CCTK-Exit}]
+ Causes normal Cactus termination
+
+\item[CCTK\_FirstVarIndex]
+ [\pageref{CCTK-FirstVarIndex}]
+ Given a group name returns the first variable index in the group
+
+\item[CCTK\_FirstVarIndexI]
+ [\pageref{CCTK-FirstVarIndexI}]
+ Given a group index returns the first variable index in the group
+
+\item[CCTK\_FortranString]
+ [\pageref{CCTK-FortranString}]
+ Changes a C string into a Fortran string
+
+\item[CCTK\_FullName]
+ [\pageref{CCTK-FullName}]
+ Given a variable index, returns the full name of the variable
+
+\item[CCTK\_GHExtension]
+ [\pageref{CCTK-GHExtension}]
+ Get the pointer to a registered extension to the Cactus GH structure
+
+\item[CCTK\_GHExtensionHandle]
+ [\pageref{CCTK-GHExtensionHandle}]
+ Get the handle associated with a extension to the Cactus GH structure
+
+\item[CCTK\_GroupbboxGI] [\pageref{CCTK-GroupbboxGI}]
+ Given a group index, return an array of the bounding box of the group for each face
+
+\item[CCTK\_GroupbboxGN] [\pageref{CCTK-GroupbboxGN}]
+ Given a group name, return an array of the bounding box of the group for each face
+
+\item[CCTK\_GroupbboxVI] [\pageref{CCTK-GroupbboxVI}]
+ Given a variable index, return an array of the bounding box of the variable for each face
+
+\item[CCTK\_GroupbboxVN] [\pageref{CCTK-GroupbboxVN}]
+ Given a variable name, return an array of the bounding box of the variable for each face
+
+\item[CCTK\_GroupData]
+ [\pageref{CCTK-GroupData}]
+ Given a group index, returns information about the variables held in the group
+
+\item[CCTK\_GroupDynamicData]
+ [\pageref{CCTK-GroupDynamicData}]
+ Given a group index, returns information about the variables held in the group
+
+\item[CCTK\_GroupgshGI] [\pageref{CCTK-GroupgshGI}]
+ Given a group index, return an array of the global size of the group in each dimension
+
+\item[CCTK\_GroupgshGN] [\pageref{CCTK-GroupgshGN}]
+ Given a group name, return an array of the global size of the group in each dimension
+
+\item[CCTK\_GroupgshVI] [\pageref{CCTK-GroupgshVI}]
+ Given a variable index, return an array of the global size of the variable in each dimension
+
+\item[CCTK\_GroupgshVN] [\pageref{CCTK-GroupgshVN}]
+ Given a variable name, return an array of the global size of the variable in each dimension
+
+\item[CCTK\_GroupIndex]
+ [\pageref{CCTK-GroupIndex}]
+ Get the index number for a group name
+
+\item[CCTK\_GroupIndexFromVar]
+ [\pageref{CCTK-GroupIndexFromVar}]
+ Given a variable name, returns the index of the associated group
+
+\item[CCTK\_GroupIndexFromVarI]
+ [\pageref{CCTK-GroupIndexFromVarI}]
+ Given a variable index, returns the index of the associated group
+
+\item[CCTK\_GrouplbndGI] [\pageref{CCTK-GrouplbndGI}]
+ Given a group index, return an array of the lower bounds of the group in each dimension
+
+\item[CCTK\_GrouplbndGN] [\pageref{CCTK-GrouplbndGN}]
+ Given a group name, return an array of the lower bounds of the group in each dimension
+
+\item[CCTK\_GrouplbndVI] [\pageref{CCTK-GrouplbndVI}]
+ Given a variable index, return an array of the lower bounds of the variable in each dimension
+
+\item[CCTK\_GrouplbndVN] [\pageref{CCTK-GrouplbndVN}]
+ Given a variable name, return an array of the lower bounds of the variable in each dimension
+
+\item[CCTK\_GrouplshGI] [\pageref{CCTK-GrouplshGI}]
+ Given a group index, return an array of the local size of the group in each dimension
+
+\item[CCTK\_GrouplshGN] [\pageref{CCTK-GrouplshGN}]
+ Given a group name, return an array of the local size of the group in each dimension
+
+\item[CCTK\_GrouplshVI] [\pageref{CCTK-GrouplshVI}]
+ Given a variable index, return an array of the local size of the variable in each dimension
+
+\item[CCTK\_GrouplshVN] [\pageref{CCTK-GrouplshVN}]
+ Given a variable name, return an array of the local size of the variable in each dimension
+
+\item[CCTK\_GroupName]
+ [\pageref{CCTK-GroupName}]
+ Given a group index, returns the group name
+
+\item[CCTK\_GroupNameFromVarI]
+ [\pageref{CCTK-GroupNameFromVarI}]
+ Given a variable index, return the name of the associated group
+
+\item[CCTK\_GroupnghostzonesGI] [\pageref{CCTK-GroupnghostzonesGI}]
+ Given a group index, return an array with the number of ghostzones in each dimension of the group
+
+\item[CCTK\_GroupnghostzonesGN] [\pageref{CCTK-GroupnghostzonesGN}]
+ Given a group name, return an array with the number of ghostzones in each dimension of the group
+
+\item[CCTK\_GroupTypeFromVarI]
+ [\pageref{CCTK-GroupTypeFromVarI}]
+ Provides a group's group type index given a variable index
+
+\item[CCTK\_GroupTypeI]
+ [\pageref{CCTK-GroupTypeI}]
+ Provides a group's group type index given a group index
+
+\item[CCTK\_GroupubndGI] [\pageref{CCTK-GroupubndGI}]
+ Given a group index, return an array of the upper bounds of the group in each dimension
+
+\item[CCTK\_GroupubndGN] [\pageref{CCTK-GroupubndGN}]
+ Given a group name, return an array of the upper bounds of the group in each dimension
+
+\item[CCTK\_GroupubndVI] [\pageref{CCTK-GroupubndVI}]
+ Given a variable index, return an array of the upper bounds of the variable in each dimension
+
+\item[CCTK\_GroupubndVN] [\pageref{CCTK-GroupubndVN}]
+ Given a variable name, return an array of the upper bounds of the variable in each dimension
+
+\item[CCTK\_ImpFromVarI]
+ [\pageref{CCTK-ImpFromVarI}]
+ Given a variable index, returns the implementation name
+
+\item[CCTK\_INFO]
+ [\pageref{CCTK-INFO}]
+ Macro to print a single string as an information message to screen
+
+\item[CCTK\_InterpGridArrays]
+ [\pageref{CCTK-InterpGridArrays}]
+ Performs an interpolation on a list of CCTK grid arrays,
+ using a chosen external local interpolation operator
+
+\item[CCTK\_InterpGV]
+ [\pageref{CCTK-InterpGV}]
+ Performs an interpolation on a list of CCTK grid arrays,
+ using a chosen build-in local interpolation operator
+ (this function is being phased out;
+ it will eventually be replaced by \verb|CCTK_InterpGridArrays()|)
+
+\item[CCTK\_InterpHandle]
+ [\pageref{CCTK-InterpHandle}]
+ Returns the handle for a given interpolation operator
+
+\item[CCTK\_InterpLocal]
+ [\pageref{CCTK-InterpLocal}]
+ Performs an interpolation on a list of processor-local arrays,
+ using a chosen interpolation operator
+ (this function is being phased out; it will
+ eventually be replaced by \verb|CCTK_InterpLocalUniform()|,
+ \verb|CCTK_InterpLocalNonUniform()|, and \verb|CCTK_InterpLocalWarped()|.)
+
+%notyet \item[CCTK\_InterpLocalNonUniform]
+%notyet [\pageref{CCTK-InterpLocalNonUniform}]
+%notyet Interpolate a list of processor-local arrays
+%notyet which define a nonuniformly spaced data grid (not implemented yet)
+
+\item[CCTK\_InterpLocalUniform]
+ [\pageref{CCTK-InterpLocalUniform}]
+ Interpolate a list of processor-local arrays
+ which define a uniformly-spaced data grid
+
+%notyet \item[CCTK\_InterpLocalWarped]
+%notyet [\pageref{CCTK-InterpLocalWarped}]
+%notyet Interpolate a list of processor-local arrays
+%notyet which define a curvilinearly-warped data grid (not implemented yet)
+
+\item[CCTK\_InterpRegisterOperatorGV]
+ [\pageref{CCTK-InterpRegisterOperatorGV}]
+ Registers a routine as a \verb|CCTK_InterpGV()|
+ interpolation operator
+
+\item[CCTK\_InterpRegisterOperatorLocal]
+ [\pageref{CCTK-InterpRegisterOperatorLocal}]
+ Registers a routine as a \verb|CCTK_InterpLocal()|
+ interpolation operator
+
+%notyet \item[CCTK\_InterpRegisterOpLocalNonUniform]
+%notyet [\pageref{CCTK-InterpRegisterOpLocalNonUniform}]
+%notyet Registers a routine as a \verb|CCTK_InterpLocalNonUniform()|
+%notyet interpolation operator
+
+\item[CCTK\_InterpRegisterOpLocalUniform]
+ [\pageref{CCTK-InterpRegisterOpLocalUniform}]
+ Registers a routine as a \verb|CCTK_InterpLocalUniform()|
+ interpolation operator
+
+%notyet \item[CCTK\_InterpRegisterOpLocalWarped]
+%notyet [\pageref{CCTK-InterpRegisterOpLocalWarped}]
+%notyet Registers a routine as a \verb|CCTK_InterpLocalWarped()|
+%notyet interpolation operator
+
+\item[CCTK\_IsImplementationActive]
+ [\pageref{CCTK-IsImplementationActive}]
+ Reports whether an implementation was activated in a parameter file
+
+\item[CCTK\_IsImplementationCompiled]
+ [\pageref{CCTK-IsImplementationCompiled}]
+ Reports whether an implementation was compiled into a configuration
+
+\item[CCTK\_IsThornActive]
+ [\pageref{CCTK-IsThornActive}]
+ Reports whether a thorn was activated in a parameter file
+
+\item[CCTK\_IsThornCompiled]
+ [\pageref{CCTK-IsThornActive}]
+ Reports whether a thorn was activated in a parameter file
+
+\item[CCTK\_MaxDim]
+ [\pageref{CCTK-MaxDim}]
+ Get the maximum dimension of any grid variable
+
+\item[CCTK\_MaxTimeLevels]
+ [\pageref{CCTK-MaxTimeLevels}]
+ Gives the maximum number of timelevels for a group
+
+\item[CCTK\_MaxTimeLevelsGI]
+ [\pageref{CCTK-MaxTimeLevelsGI}]
+ Gives the maximum number of timelevels for a group
+
+\item[CCTK\_MaxTimeLevelsGN]
+ [\pageref{CCTK-MaxTimeLevelsGN}]
+ Gives the maximum number of timelevels for a group
+
+\item[CCTK\_MaxTimeLevelsVI]
+ [\pageref{CCTK-MaxTimeLevelsVarI}]
+ Gives the maximum number of timelevels for a variable
+
+\item[CCTK\_MaxTimeLevelsVN]
+ [\pageref{CCTK-MaxTimeLevelsVN}]
+ Gives the maximum number of timelevels for a variable
+
+\item[CCTK\_MyProc]
+ [\pageref{CCTK-MyProc}]
+ Get the local processor number
+
+\item[CCTK\_nProcs]
+ [\pageref{CCTK-nProcs}]
+ Get the total number of processors used
+
+\item[CCTK\_NullPointer]
+ [\pageref{CCTK-NullPointer}]
+ Returns a C-style NULL pointer value
+
+\item[CCTK\_NumGroups]
+ [\pageref{CCTK-NumGroups}]
+ Get the number of groups of variables compiled in the code
+
+\item[CCTK\_NumIOMethods]
+ [\pageref{CCTK-NumIOMethods}]
+ Returns the total number of I/O methods registered with the flesh
+
+\item[CCTK\_NumVars]
+ [\pageref{CCTK-NumVars}]
+ Get the number of grid variables compiled in the code
+
+\item[CCTK\_NumVarsInGroup]
+ [\pageref{CCTK-NumVarsInGroup}]
+ Provides the number of variables in a group from the group name
+
+\item[CCTK\_NumVarsInGroupI]
+ [\pageref{CCTK-NumVarsInGroupI}]
+ Provides the number of variables in a group from the group index
+
+\item[CCTK\_OutputGH]
+ [\pageref{CCTK-OutputGH}]
+ Conditional output of all variables on a GH by all I/O methods
+
+\item[CCTK\_OutputVar]
+ [\pageref{CCTK-OutputVar}]
+ Output of a single variable by all I/O methods
+
+\item[CCTK\_OutputVarAs]
+ [\pageref{CCTK-OutputVarAs}]
+ Output of a single variable as an alias by all I/O methods
+
+\item[CCTK\_OutputVarAsByMethod]
+ [\pageref{CCTK-OutputVarAsByMethod}]
+ Output of a single variable as an alias by a single I/O method
+
+\item[CCTK\_OutputVarByMethod]
+ [\pageref{CCTK-OutputVarByMethod}]
+ Output of a single variable by a single I/O method
+
+\item[CCTK\_ParallelInit]
+ [\pageref{CCTK-ParallelInit}]
+ Initializes the parallel subsystem
+
+\item[CCTK\_PARAMWARN]
+ [\pageref{CCTK-PARAMWARN}]
+ Prints a warning from parameter checking, and possibly stops the code
+
+\item[CCTK\_PointerTo]
+ [\pageref{CCTK-PointerTo}]
+ Returns the address of a variable passed in by reference from a fortran routine
+
+\item[CCTK\_PrintGroup]
+ [\pageref{CCTK-PrintGroup}]
+ Prints a group name from its index
+
+\item[CCTK\_PrintString]
+ [\pageref{CCTK-PrintString}]
+ Prints a Cactus string to screen (from Fortran)
+
+\item[CCTK\_PrintVar]
+ [\pageref{CCTK-PrintVar}]
+ Prints a variable name from its index
+
+\item[CCTK\_QueryGroupStorage]
+ [\pageref{CCTK-QueryGroupStorage}]
+ Queries storage for a group given by its group name
+
+\item[CCTK\_QueryGroupStorageB]
+ [\pageref{CCTK-QueryGroupStorageB}]
+
+
+\item[CCTK\_QueryGroupStorageI]
+ [\pageref{CCTK-QueryGroupStorageI}]
+ Queries storage for a group given by its group index
+
+
+%\item[CCTK\_Reduce]
+% [\pageref{CCTK-Reduce}]
+% Perform a reduction operation using a registered operator
+
+\item[CCTK\_ReductionHandle]
+ [\pageref{CCTK-ReductionHandle}]
+ Get the handle for a registered reduction operator
+
+\item[CCTK\_RegisterBanner]
+ [\pageref{CCTK-RegisterBanner}]
+ Register a banner for a thorn
+
+\item[CCTK\_RegisterGHExtension]
+ [\pageref{CCTK-RegisterGHExtension}]
+ Register the name of an extension to the Cactus GH.
+
+\item[CCTK\_RegisterGHExtensionInitGH]
+ [\pageref{CCTK-RegisterGHExtensionInitGH}]
+ Register a routine for providing initialisation for an extension to the Cactus GH
+
+\item[CCTK\_RegisterGHExtensionScheduleTraverseGH]
+ [\pageref{CCTK-RegisterGHExtensionScheduleTraverseGH}]
+ Register a GH extension schedule traversal routine
+
+\item[CCTK\_RegisterGHExtensionSetupGH]
+ [\pageref{CCTK-RegisterGHExtensionSetupGH}]
+ Register a routine for setting up an extension to the Cactus GH
+
+\item[CCTK\_RegisterIOMethod]
+ [\pageref{CCTK-RegisterIOMethod}]
+ Registers a new I/O method
+
+\item[CCTK\_RegisterIOMethodOutputGH]
+ [\pageref{CCTK-RegisterIOMethodOutputGH}]
+ Registers an I/O method's routine for conditional output
+
+\item[CCTK\_RegisterIOMethodOutputVarAs]
+ [\pageref{CCTK-RegisterIOMethodOutputVarAs}]
+ Registers an I/O method's routine for unconditional output
+
+\item[CCTK\_RegisterIOMethodTimeToOutput]
+ [\pageref{CCTK-RegisterIOMethodTimeToOutput}]
+ Register a routine for deciding if it is time to output for an IO method
+
+\item[CCTK\_RegisterIOMethodTriggerOutput]
+ [\pageref{CCTK-RegisterIOMethodTriggerOutput}]
+ Register a routine for dealing with trigger output for an IO method
+
+\item[CCTK\_RegisterReductionOperator]
+ [\pageref{CCTK-RegisterReductionOperator}]
+ Register a function as providing a reduction operation
+
+
+\item[CCTK\_SetupGH]
+ [\pageref{CCTK-SetupGH}]
+ Sets up a CCTK grid hierarchy
+
+\item[CCTK\_SyncGroup]
+ [\pageref{CCTK-SyncGroup}]
+ Synchronize the ghost zones for a group of variables
+
+
+\item[CCTK\_VarDataPtr]
+ [\pageref{CCTK-VarDataPtr}]
+ Returns the data pointer for a grid variable
+
+\item[CCTK\_VarDataPtrB]
+ [\pageref{CCTK-VarDataPtrB}]
+ Returns the data pointer for a grid variable from the variable index or name
+
+\item[CCTK\_VarDataPtrI]
+ [\pageref{CCTK-VarDataPtrI}]
+ Returns the data pointer for a grid variable from the variable index
+
+\item[CCTK\_VarIndex]
+ [\pageref{CCTK-VarIndex}]
+ Get the index for a variable
+
+\item[CCTK\_VarName]
+ [\pageref{CCTK-VarName}]
+ Given a variable index, returns the variable name
+
+\item[CCTK\_VarTypeI]
+ [\pageref{CCTK-VarTypeI}]
+ Provides variable type index from the variable index
+
+\item[CCTK\_VarTypeSize]
+ [\pageref{CCTK-VarTypeSize}]
+ Provides variable type size in bytes from the variable type index
+
+\item[CCTK\_VInfo]
+ [\pageref{CCTK-VInfo}]
+ Prints a formatted string with a variable argument list as an information
+ message to screen
+
+\item[CCTK\_VWarn]
+ [\pageref{CCTK-VWarn}]
+ Prints a formatted string with a variable argument list as a warning message
+ to standard error and possibly stops the code
+
+\item[CCTK\_WARN]
+ [\pageref{CCTK-WARN}]
+ Macro to print a single string as a warning message to standard error and
+ possibly stop the code
+
+\end{Lentry}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Full Description of Functions}
+
+%%%%%
+% AAA
+%%%%%
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_Abort}{Abnormal Cactus termination}
+\label{CCTK-Abort}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{int}{integer}{value}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{value}{the return code to abort with}
+\end{params}
+\begin{discussion}
+This routine causes an immediate, abnormal Cactus termination.
+It never returns to the caller.
+\end{discussion}
+\end{CCTKFunc}
+
+
+% cctk_GroupsOnGH.h
+\begin{FunctionDescription}{CCTK\_ActiveTimeLevels}{}
+\label{CCTK-ActiveTimeLevels}
+Returns the number of active time levels for a group.
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+int timelevels = CCTK_ActiveTimeLevels(const cGH *cctkGH,
+ const char *groupname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_ActiveTimeLevels(timelevels, cctkGH, groupname)
+
+integer timelevels
+CCTK_POINTER cctkGH
+character*(*) groupname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{NULL}
+The number of timelevels
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{GH ($\ne$ NULL)}
+Pointer to a valid Cactus grid hierarchy.
+\end{Parameter}
+\begin{Parameter}{groupname}
+Name of the group.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function returns the number of timelevels for which storage has been activated, which is always equal to or less than the maximum number of
+timelevels which may have storage provided by {\tt CCTK\_MaxTimeLevels}.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK-MaxTimeLevels}
+Return the maximum number of timelevels
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK-GroupStorageIncrease}
+Base function overloaded by driver which increase the number of timelevels
+with storage and also returns the number of active timelevels.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+%\begin{ErrorSection}
+%\end{ErrorSection}
+%\begin{ExampleSection}
+%\end{ExampleSection}
+\end{FunctionDescription}
+
+
+
+% cctk_Comm.h
+\begin{FunctionDescription}{CCTK\_ArrayGroupSize}{}
+\label{CCTK-ArrayGroupSize}
+Returns a pointer to the processor-local size for variables in a
+group, specified by its name, in a given dimension.
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+int *size = CCTK_ArrayGroupSize(const cGH *cctkGH,
+ int dir,
+ const char *groupname);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{NULL}
+A NULL pointer is returned if the group index or the dimension given are invalid.
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{GH ($\ne$ NULL)}
+Pointer to a valid Cactus grid hierarchy.
+\end{Parameter}
+\begin{Parameter}{dir ($\ge$ 0)}
+Which dimension of array to query.
+\end{Parameter}
+\begin{Parameter}{groupname}
+Name of the group.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+For a CCTK\_ARRAY or CCTK\_GF group, this routine returns a pointer to
+the processor-local size for variables in that group in a given
+direction. The direction is counted in C order (zero being the lowest
+dimension).
+
+This function returns a pointer to the result for technical reasons;
+so that it will efficiently interface with Fortran. This may change
+in the future. Consider using \texttt{CCTK\_GroupgshGN} instead.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupgshGN}
+Returns an array with the array size in all dimensions.
+\end{SeeAlso}
+\begin{SeeAlso}{...}
+There are many related functions which grab information from the GH,
+but many are not yet documented.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+%\begin{ErrorSection}
+%\end{ErrorSection}
+%\begin{ExampleSection}
+%\end{ExampleSection}
+\end{FunctionDescription}
+
+
+% cctk_Comm.h
+\begin{FunctionDescription}{CCTK\_ArrayGroupSizeI}{}
+\label{CCTK-ArrayGroupSizeI}
+Returns a pointer to the processor-local size for variables in a
+group, specified by its index, in a given dimension.
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+int *size = CCTK_ArrayGroupSizeI(const cGH *cctkGH,
+ int dir,
+ int groupi);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{NULL}
+A NULL pointer is returned if the group index or the dimension given are invalid.
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{GH ($\ne$ NULL)}
+Pointer to a valid Cactus grid hierarchy.
+\end{Parameter}
+\begin{Parameter}{dir ($\ge$ 0)}
+Which dimension of array to query.
+\end{Parameter}
+\begin{Parameter}{groupi}
+The group index.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+For a CCTK\_ARRAY or CCTK\_GF group, this routine returns a pointer to
+the processor-local size for variables in that group in a given
+direction. The direction is counted in C order (zero being the lowest
+dimension).
+
+This function returns a pointer to the result for technical reasons;
+so that it will efficiently interface with Fortran. This may change
+in the future. Consider using \texttt{CCTK\_GroupgshGI} instead.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupgshGI}
+Returns an array with the array size in all dimensions.
+\end{SeeAlso}
+\begin{SeeAlso}{...}
+There are many related functions which grab information from the GH,
+but many are not yet documented.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+%\begin{ErrorSection}
+%\end{ErrorSection}
+%\begin{ExampleSection}
+%\end{ExampleSection}
+\end{FunctionDescription}
+
+
+%%%%%
+% BBB
+%%%%%
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_Barrier}{Synchronizes all processors at a given execution point}
+\label{CCTK-Barrier}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{istat}{return code}
+\end{params}
+\begin{discussion}
+\end{discussion}
+This routine synchronizes all processors in a parallel job at a given point of
+execution. No processor will continue execution until all other processors
+have called {\t CCTK\_Barrier()}. Note that this is a collective operation --
+it must be called by all processors otherwise the code will hang.
+\end{CCTKFunc}
+
+
+%%%%%
+% CCC
+%%%%%
+
+\begin{CCTKFunc}{CCTK\_Cmplx}{Turns two real numbers into a complex number}
+\label{CCTK-Cmplx}
+\subroutine{CCTK\_COMPLEX}{}{cmpno}
+\argument{CCTK\_REAL}{}{realpart}
+\argument{CCTK\_REAL}{}{imagpart}
+\showcargs
+\begin{params}
+\parameter{cmpno}{The complex number}
+\parameter{realpart}{The real part of the complex number}
+\parameter{imagpart}{The imaginary part of the complex number}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t cmpno = CCTK\_Cmplx(re,im)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{CCTKFunc}{CCTK\_CmplxAbs}{Absolute value of a complex number}
+\label{CCTK-CmplxAbs}
+\subroutine{CCTK\_COMPLEX}{}{absval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{absval}{The computed absolute value}
+\parameter{realpart}{The complex number who absolute value is to be returned}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t absval = CCTK\_CmplxAbs(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{CCTKFunc}{CCTK\_CmplxAdd}{Sum of two complex numbers}
+\label{CCTK-CmplxAdd}
+\subroutine{CCTK\_COMPLEX}{}{addval}
+\argument{CCTK\_COMPLEX}{}{inval1}
+\argument{CCTK\_COMPLEX}{}{inval2}
+\showcargs
+\begin{params}
+\parameter{addval}{The computed added value}
+\parameter{inval1}{The first complex number to be summed}
+\parameter{inval2}{The second complex number to be summed}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t addval = CCTK\_CmplxAdd(inval1,inval2)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxConjg}{Complex conjugate of a complex number}
+\label{CCTK-CmplxConjg}
+\subroutine{CCTK\_COMPLEX}{}{conjgval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{conjval}{The computed conjugate}
+\parameter{inval}{The complex number to be conjugated}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t conjgval = CCTK\_CmplxConjg(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxCos}{Cosine of a complex number}
+\label{CCTK-CmplxCos}
+\subroutine{CCTK\_COMPLEX}{}{cosval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{cosval}{The computed cosine}
+\parameter{inval}{The complex number to be cosined}
+\end{params}
+\begin{discussion}
+{\bf NOT YET AVAILABLE}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t cosval = CCTK\_CmplxCos(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{CCTKFunc}{CCTK\_CmplxDiv}{Division of two complex numbers}
+\label{CCTK-CmplxDiv}
+\subroutine{CCTK\_COMPLEX}{}{divval}
+\argument{CCTK\_COMPLEX}{}{inval1}
+\argument{CCTK\_COMPLEX}{}{inval2}
+\showcargs
+\begin{params}
+\parameter{divval}{The divided value}
+\parameter{inval1}{The enumerator}
+\parameter{inval1}{The denominator}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t divval = CCTK\_CmplxDiv(inval1,inval2)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{CCTKFunc}{CCTK\_CmplxExp}{Exponent of a complex number}
+\label{CCTK-CmplxExp}
+\subroutine{CCTK\_COMPLEX}{}{expval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{expval}{The computed exponent}
+\parameter{inval}{The complex number to be exponented}
+\end{params}
+\begin{discussion}
+{\bf NOT YET AVAILABLE}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t expval = CCTK\_CmplxExp(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxImag}{Imaginary part of a complex number}
+\label{CCTK-CmplxImag}
+\subroutine{CCTK\_REAL}{}{imval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{imval}{The imaginary part}
+\parameter{inval}{The complex number}
+\end{params}
+\begin{discussion}
+The imaginary part of a complex number $z=a+bi$ is $b$.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t imval = CCTK\_CmplxImag(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxLog}{Logarithm of a complex number}
+\label{CCTK-CmplxLog}
+\subroutine{CCTK\_COMPLEX}{}{logval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{logval}{The computed logarithm}
+\parameter{inval}{The complex number}
+\end{params}
+\begin{discussion}
+{\bf NOT YET AVAILABLE}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t logval = CCTK\_CmplxLog(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxMul}{Multiplication of two complex numbers}
+\label{CCTK-CmplxMul}
+\subroutine{CCTK\_COMPLEX}{}{mulval}
+\argument{CCTK\_COMPLEX}{}{inval1}
+\argument{CCTK\_COMPLEX}{}{inval2}
+\showcargs
+\begin{params}
+\parameter{mulval}{The product}
+\parameter{inval1}{First complex number to be multiplied}
+\parameter{inval2}{Second complex number to be multiplied}
+\end{params}
+\begin{discussion}
+The product of two complex numbers $z_1=a_1+b_1 i$ and $z_2=a_2+b_2 i$ is
+$z=(a_1 a_2 - b_1 b_2) + (a_1 b_2 + a_2 b_1)i$.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t mulval = CCTK\_CmplxMul(inval1,inval2)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+\begin{CCTKFunc}{CCTK\_CmplxReal}{Real part of a complex number}
+\label{CCTK-CmplxReal}
+\subroutine{CCTK\_REAL}{}{reval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{reval}{The real part}
+\parameter{inval}{The complex number}
+\end{params}
+\begin{discussion}
+The real part of a complex number $z=a+bi$ is $a$.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t reval = CCTK\_CmplxReal(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxSin}{Sine of a complex number}
+\label{CCTK-CmplxSin}
+\subroutine{CCTK\_COMPLEX}{}{sinval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{sinval}{The computed sine}
+\parameter{inval}{The complex number to be Sined}
+\end{params}
+\begin{discussion}
+{\bf NOT YET AVAILABLE}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t sinval = CCTK\_CmplxSin(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxSqrt}{Square root of a complex number}
+\label{CCTK-CmplxSqrt}
+\subroutine{CCTK\_COMPLEX}{}{sqrtval}
+\argument{CCTK\_COMPLEX}{}{inval}
+\showcargs
+\begin{params}
+\parameter{expval}{The computed square root}
+\parameter{inval}{The complex number to be square rooted}
+\end{params}
+\begin{discussion}
+{\bf NOT YET AVAILABLE}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t sqrtval = CCTK\_CmplxSqrt(inval)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CmplxSub}{Subtraction of two complex numbers}
+\label{CCTK-CmplxSub}
+\subroutine{CCTK\_COMPLEX}{}{subval}
+\argument{CCTK\_COMPLEX}{}{inval1}
+\argument{CCTK\_COMPLEX}{}{inval2}
+\showcargs
+\begin{params}
+\parameter{addval}{The computed subtracted value}
+\parameter{inval1}{The complex number to be subtracted from}
+\parameter{inval2}{The complex number to subtract}
+\end{params}
+\begin{discussion}
+If $z_1=a_1 + b_1 i$ and $z_2 = a_2+ b_2 i$ then
+$$
+z_1-z_2 = (a_1-a_2)+ (b_1 - b_2)i
+$$
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t subval = CCTK\_CmplxSub(inval1,inval2)};
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CoordDir}{Give the direction for a given coordinate.}
+\label{CCTK-CoordDir}
+\subroutine{int}{integer}{dir}
+\argument{const char *}{character*(*)}{coordname}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{dir}{The direction of the coordinate}
+\parameter{coordname}{The name assigned to this coordinate}
+\parameter{systemname}{The name of the coordinate system}
+\end{params}
+\begin{discussion}
+The coordinate name is independent of the grid function name.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t direction = CCTK\_CoordDir("xdir","cart3d")};
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_COORDDIR(direction,"radius","spher3d")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CoordIndex}{Give the grid variable index for a given coordinate.}
+\label{CCTK-CoordIndex}
+\subroutine{int}{integer}{index}
+\argument{int}{integer}{direction}
+\argument{const char *}{character*(*)}{coordname}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{index}{The coordinates associated grid variable index}
+\parameter{direction}{The direction of the coordinate in this coordinate system}
+\parameter{coordname}{The name assigned to this coordinate}
+\parameter{systemname}{The coordinate system for this coordinate}
+\end{params}
+\begin{discussion}
+The coordinate name is independent of the grid variable name.
+To find the index, the coordinate system name must be given, and either
+the coordinate direction or the coordinate name. The coordinate name
+will be used if the coordinate direction is given as less than or equal to zero, otherwise the coordinate name will be used.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_CoordIndex(-1,"xdir","cart3d")};
+\\
+\hfill {\bf Fortran} && one = 1
+\\
+&& {\t call CCTK\_COORDINDEX(index,one,"radius","spher2d")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_CoordRange}{Return the global upper and lower bounds for a given coordinate}
+\label{CCTK-CoordRange}
+\subroutine{int}{integer}{ierr}
+\argument{const cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{CCTK\_REAL *}{CCTK\_REAL}{lower}
+\argument{CCTK\_REAL *}{CCTK\_REAL}{upper}
+\argument{int}{integer}{direction}
+\argument{const char *}{character*(*)}{coordname}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{ierr}{Error code}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{lower}{Global lower bound of the coordinate (POINTER in C)}
+\parameter{upper}{Global upper bound of the coordinate (POINTER in C)}
+\parameter{direction}{Direction of coordinate in coordinate system}
+\parameter{coordname}{Coordinate name}
+\parameter{systemname}{Coordinate system name}
+\end{params}
+\begin{discussion}
+The coordinate name is independent of the grid function name.
+The coordinate range is registered by {\t CCTK\_CoordRegisterRange}.
+To find the range, the coordinate system name must be given, and either
+the coordinate direction or the coordinate name. The coordinate direction
+will be used if is given as a positive value, otherwise the coordinate
+name will be used.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t ierr = CCTK\_CoordRange(cctkGH, \&xmin, \&xmax, -1, "xdir", "mysystem");}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_COORDRANGE(ierr, cctkGH, Rmin, Rmax, -1, "radius", "sphersystem")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_CoordRegisterData}{Define a coordinate in a given coordinate
+system.}
+\label{CCTK-CoordRegisterData}
+\subroutine{int}{integer}{ierr}
+\argument{int}{integer}{direction}
+\argument{const char *}{character*(*)}{gvname}
+\argument{const char *}{character*(*)}{coordname}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{ierr}{Error code}
+\parameter{direction}{Direction of coordinate in coordinate system}
+\parameter{gvname}{Name of grid variable associated with coordinate}
+\parameter{coordname}{Name of this coordinate}
+\parameter{systemname}{Name of this coordinate system}
+\end{params}
+\begin{discussion}
+There must already be a coordinate system registered,
+using {\tt CCTK\_CoordRegisterSystem}.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t ierr = CCTK\_CoordRegisterData(1,"coordthorn::myx","x2d","cart2d")};
+\\
+\hfill {\bf Fortran} && two = 2
+\\
+&&{\t call CCTK\_COORDREGISTERDATA(ierr,two,"coordthorn::mytheta","spher3d")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_CoordRegisterRange}{Assign the global maximum and minimum
+values of a coordinate on a given grid hierachy}
+\label{CCTK-CoordRegisterRange}
+\subroutine{int}{integer}{ierr}
+\argument{const cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{CCTK\_REAL}{CCTK\_REAL}{min}
+\argument{CCTK\_REAL}{CCTK\_REAL}{max}
+\argument{int}{integer}{direction}
+\argument{const char *}{character*(*)}{coordname}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{ierr}{Error code}
+\parameter{dimension}{Pointer to CCTK grid hierachy}
+\parameter{min}{Global minimum of coordinate}
+\parameter{max}{Global maximum of coordinate}
+\parameter{direction}{Direction of coordinate in coordinate system}
+\parameter{coordname}{Name of coordinate in coordinate system}
+\parameter{systemname}{Name of this coordinate system}
+\end{params}
+\begin{discussion}
+There must already
+be a coordinate registered with the given name, with {\t CCTK\_CoordRegisterData}.
+The coordinate range
+can be accessed by {\t CCTK\_CoordRange}.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t ierr = CCTK\_CoordRegisterRange(cctkGH,-1.0,1.0,1,"x2d","cart2d")};
+\\
+\hfill {\bf Fortran} && min = 0
+\\
+&& max = 3.1415d0/2.0d0
+\\
+&& two = 2
+\\
+&&{\t call CCTK\_COORDREGISTERRANGE(ierr,min,max,two,"coordthorn::mytheta","spher3d")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_CoordRegisterSystem}{Assigns a coordinate system with
+a chosen name and dimension}
+\label{CCTK-CoordRegisterSystem}
+\subroutine{int}{integer}{ierr}
+\argument{int}{integer}{dimension}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{ierr}{Error code}
+\parameter{dimension}{Dimension of coordinate system}
+\parameter{systemname}{Unique name assigned to coordinate system}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t ierr = CCTK\_CoordRegisterSystem(3,"cart3d")};
+\\
+\hfill {\bf Fortran} && three = 3
+\\
+&&{\t call CCTK\_COORDREGISTERSYSTEM(ierr,three,"sphersystem")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_CoordSystemDim}{Give the dimension for a given coordinate system.}
+\label{CCTK-CoordDim}
+\subroutine{int}{integer}{dim}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{dim}{The dimension of the coordinate system}
+\parameter{systemname}{The name of the coordinate system}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t dim = CCTK\_CoordSystemDim("cart3d")};
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_COORDSYSTEMDIM(dim,"spher3d")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_CoordSystemHandle}{Returns the handle associated with a registered coordinate system}
+\label{CCTK-CoordSystemHandle}
+\subroutine{int}{integer}{handle}
+\argument{const char *}{character*(*)}{systemname}
+\showargs
+\begin{params}
+\parameter{handle}{The coordinate system handle}
+\parameter{systemname}{Name of the coordinate system}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t handle = CCTK\_CoordSystemHandle("my coordinate system");}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_CoordSystemHandle(handle,"my coordinate system")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative return code indicates an invalid coordinate system name.
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_CoordSystemName}{Returns the name of a registered coordinate system}
+\label{CCTK-CoordSystemName}
+\subroutine{const char *}{integer}{systemname}
+\argument{int}{integer}{handle}
+\showcargs
+\begin{params}
+\parameter{handle}{The coordinate system handle}
+\parameter{systemname}{The coordinate system name}
+\end{params}
+\begin{discussion}
+No Fortran routine exists at the moment.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t systemname = CCTK\_CoordSystemName(handle);}
+\\
+\hfill && {\t handle = CCTK\_CoordSystemHandle(systemname);}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{l}
+A NULL pointer is returned if an invalid handle was given.
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_CreateDirectory}{Create a directory with required permissions}
+\label{CCTK-CreateDirectory}
+\subroutine{int}{integer}{ierr}
+\argument{const char *}{character*(*)}{pathname}
+\argument{int}{integer}{mode}
+\showargs
+\begin{params}
+\parameter{ierr}{Error code}
+\parameter{pathname}{Directory to create}
+\parameter{mode}{Permission mode for new directory as an octal number}
+\end{params}
+\begin{discussion}
+To create a directory readable by everyone, but writeable only by the user runnning the code, the permission mode would be 0755.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t ierr = CCTK\_CreateDirectory("Results/New",0755) };
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_CREATEDIRECTORY(ierr,"Results/New",0755)}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{ll}
+0 & Directory successfully created\\
+-1 & Memory allocation failed\\
+-2 & Failed to create directory\\
+-3 & pathname exists but is not a directory\\
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+%%%%%
+% DDD
+%%%%%
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_DecomposeName}{Given the full name of a variable/group, separates the name returning both the implementation and the variable/group}
+\label{CCTK-DecomposeName}
+\subroutine{int}{integer}{istat}
+\argument{const char *}{}{fullname}
+\argument{char **}{}{imp}
+\argument{char **}{}{name}
+\showcargs
+\begin{params}
+\parameter{istat}{Status flag returned by routine}
+\parameter{fullname}{The full name of the group/variable}
+\parameter{imp}{The implementation name}
+\parameter{name}{The group/variable name}
+\end{params}
+\begin{discussion}
+\fbox{The implementation name and the group/variable name must be
+explicitly freed after they have been used.}
+
+No Fortran routine exists at the moment.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t istat = CCTK\_DecomposeName("evolve::scalars",imp,name)}\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_DisableGroupComm}{Turn communications off for a group of grid variables}
+\label{CCTK-DisableGroupComm}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{const char *}{character*(*)}{group}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+Turning off communications means that ghost zones will not be
+communicated during a call to {\tt CCTK\_SyncGroup}. By default
+communications are all off.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_DisableGroupStorage}{Free the storage associated with a group of grid variables}
+\label{CCTK-DisableGroupStorage}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{const char *}{character*(*)}{group}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+%%%%%
+% EEE
+%%%%%
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_EnableGroupComm}{Turn communications on for a group of grid variables}
+\label{CCTK-EnableGroupComm}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{const char *}{character*(*)}{group}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+Grid variables with communication enabled will have their ghost zones communicated during a call
+to {\tt CCTK\_SyncGroup}. In general, this function does not need to be used, since communication
+is automatically enabled for grid variables who have assigned storage via the {\tt schedule.ccl}
+file.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_EnableGroupStorage}{Assign the storage for a group of grid variables}
+\label{CCTK-EnableGroupStorage}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{const char *}{character*(*)}{group}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+In general this function does not need to be used, since storage assignment is best handled by
+the Cactus scheduler via a thorn's {\tt schedule.ccl} file.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_Equals}{Checks a STRING or KEYWORD parameter for equality with a given string}
+\label{CCTK-Equals}
+\function{int}{integer}{istat}
+\argument{const char *}{CCTK\_POINTER}{param}
+\argument{const char *}{character*(*)}{value}
+\showargs
+\begin{params}
+\parameter{istat}{returns success or failure of equality}
+\parameter{param}{the STRING or KEYWORD parameter to check}
+\parameter{value}{the string value to compare against}
+\end{params}
+\begin{discussion}
+This function compares a Cactus parameter of type STRING or KEYWORD against a
+given string value. The comparison is performed case-independent,
+returning a non-zero value if the strings are the same, and zero if they differ.
+
+Note that in Fortran code, STRING or KEYWORD parameters are passed as C pointers,
+and can not be treated as normal Fortran strings. Thus {\t CCTK\_Equals()}
+should be used to check the value of such a parameter.
+\end{discussion}
+\end{CCTKFunc}
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_Exit}{Exit the code cleanly}
+\label{CCTK-Exit}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{int}{integer}{value}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{value}{the return code to abort with}
+\end{params}
+\begin{discussion}
+This routine causes an immediate, regular termination of Cactus.
+It never returns to the caller.
+\end{discussion}
+\end{CCTKFunc}
+
+
+
+
+%%%%%
+% FFF
+%%%%%
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_FirstVarIndex}{Given a group name returns the first variable index in the group}
+\label{CCTK-FirstVarIndex}
+\subroutine{int}{integer}{firstvar}
+\argument{const char *}{character*(*)}{group}
+\showargs
+\begin{params}
+\parameter{firstvar}{The first variable index in the given group}
+\parameter{group}{The group name}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t firstvar = CCTK\_FirstVarIndex("evolve::scalars") ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_GroupIndex(index,"evolve::scalars")}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{CCTKFunc}{CCTK\_FirstVarIndexI}{Given a group index returns the first variable index in the group}
+\label{CCTK-FirstVarIndexI}
+\subroutine{int}{integer}{firstvar}
+\argument{int}{integer}{group}
+\showargs
+\begin{params}
+\parameter{firstvar}{The first variable index in the given group}
+\parameter{group}{The group index}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_GroupIndex("evolve::scalars")}\\
+ &&{\t firstvar = CCTK\_FirstVarIndexI(index) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_GroupIndex(index,3)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{CCTKFunc}{CCTK\_FortranString}{Changes a C string into a Fortran string}
+\label{CCTK-FortranString}
+\subroutine{int}{integer}{nchar}
+\argument{const char *}{character*(*)}{strout}
+\argument{const char *}{CCTK\_STRING}{strin}
+\showargs
+\begin{params}
+\parameter{nchar}{The number of characters in the C string, not counting the null terminator}
+\parameter{strout}{The fortran string which on output contains the C string as the first nchar characters}
+\parameter{strin}{The (pointer to the) C string containing the null terminator}
+\end{params}
+\begin{discussion}
+String or keyword parameters in Cactus are passed into Fortran routines as
+pointers to C strings. This means that they cannot be directly used as Fortran
+strings. This routine allows a Fortran string to be created from such a C string. Note that the Fortran string must be defined to have at least the same expected length as the C string. This routine is only callable from Fortran.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf Fortran} && \\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_FullName}{Given a variable index, returns the full name of the variable}
+\label{CCTK-FullName}
+\subroutine{char *}{integer}{fullname}
+\argument{int}{integer}{index}
+\showcargs
+\begin{params}
+\parameter{implementation}{The full variable name}
+\parameter{index}{The variable index}
+\end{params}
+\begin{discussion}
+\fbox{The full variable name must be explicitly freed after it has been used.}
+
+No Fortran routine exists at the moment. The full variable name is in
+the form {\t <implementation>::<variable>}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_VarIndex("evolve::phi");}\\
+ && {\t name = CCTK\_FullName(index);}\\
+ && {\t printf ("Variable name: \%s", name);}\\
+ && {\t free (name);}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+%%%%%
+% GGG
+%%%%%
+
+% cctk_GHExtensions.h
+\begin{CCTKFunc}{CCTK\_GHExtension}{Get the pointer to a registered extension to the Cactus GH structure}
+\label{CCTK-GHExtension}
+\subroutine{void *}{CCTK\_POINTER}{extension}
+\argument{const GH *}{CCTK\_POINTER}{cctkGH}
+\argument{const char *}{character*(*)}{name}
+\showcargs
+\begin{params}
+\parameter{extension}{The pointer to the GH extension}
+\parameter{cctkGH}{The pointer to the CCTK grid hierarchy}
+\parameter{name}{The name of the GH extension}
+\end{params}
+\begin{discussion}
+No Fortran routine exists at the moment.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t void *extension = CCTK\_GHExtension(GH, "myExtension");}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+NULL & A NULL pointer is returned if an invalid extension name was given.
+\end{errorcodes}
+\end{CCTKFunc}
+
+% cctk_GHExtensions.h
+\begin{CCTKFunc}{CCTK\_GHExtensionHandle}{Get the handle associated with a extension to the Cactus GH structure}
+\label{CCTK-GHExtensionHandle}
+\subroutine{int}{integer}{handle}
+\argument{const char *}{character*(*)}{name}
+\showargs
+\begin{params}
+\parameter{handle}{The GH extension handle}
+\parameter{group}{The name of the GH extension}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t handle = CCTK\_GHExtension("myExtension") ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_GHExtension(handle,"myExtension")}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% GroupsOnGH.h
+\begin{FunctionDescription}{CCTK\_GroupbboxGI, CCTK\_GroupbboxGN}
+\label{CCTK-GroupbboxGI}
+\label{CCTK-GroupbboxGN}
+Given a group index or name, return an array of the bounding box of the group for each face
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupbboxGI(const cGH *cctkGH,
+ int dim,
+ int *bbox,
+ int groupindex);
+
+int status = CCTK_GroupbboxGN(const cGH *cctkGH,
+ int dim,
+ int *bbox,
+ const char *groupname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupbboxGI(status, cctkGH, dim, bbox, groupindex)
+
+call CCTK_GroupbboxGN(status, cctkGH, dim, bbox, groupname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer bbox(dim)
+integer groupindex
+character*(*) groupname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid group index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of group. \end{Parameter}
+\begin{Parameter}{bbox ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{groupindex} Group index. \end{Parameter}
+\begin{Parameter}{groupname} Group's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The bounding box for a given group is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupbboxVI, CCTK\_GroupbboxVN}
+Returns the lower bounds for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GroupbboxVI, CCTK\_GroupbboxVN}
+\label{CCTK-GroupbboxVI}
+\label{CCTK-GroupbboxVN}
+Given a variable index or name, return an array of the bounding box of the variable for each face
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupbboxVI(const cGH *cctkGH,
+ int dim,
+ int *bbox,
+ int varindex);
+
+int status = CCTK_GroupbboxVN(const cGH *cctkGH,
+ int dim,
+ int *bbox,
+ const char *varname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupbboxVI(status, cctkGH, dim, bbox, varindex)
+
+call CCTK_GroupbboxVN(status, cctkGH, dim, bbox, varname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer bbox(dim)
+integer varindex
+character*(*) varname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid variable index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of variable. \end{Parameter}
+\begin{Parameter}{bbox ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{varindex} Group index. \end{Parameter}
+\begin{Parameter}{varname} Group's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The bounding box for a given variable is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupbboxGI, CCTK\_GroupbboxGN}
+Returns the upper bounds for a given group.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupData}{Given a group index, returns information about the variables held in the group.}
+\label{CCTK-GroupData}
+\function{int}{}{ierr}
+\argument{int}{}{group}
+\argument{cGroup *}{}{pgroup}
+\showcargs
+\begin{params}
+\parameter{ierr}{0 for success, negative for failure}
+\parameter{group}{group index}
+\parameter{pgroup}{returns a pointer to a structure containing group information}
+\end{params}
+\begin{discussion}
+The cGroup structure contains the information
+\begin{itemize}
+\item grouptype: The group type
+\item vartype: The type of variables in the group
+\item stagtype: The type of grid staggering for arrays
+\item dim: The dimension of variables in the group
+\item numvars: The number of variables in the group
+\item ntimelevels: The number of timelevels for variables in the group
+\end{itemize}
+No Fortran routine exists at the moment.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t cGroup pgroup;}\\
+ && {\t index = CCTK\_GroupIndex("evolve::scalars");}\\
+ &&{\t ierr = CCTK\_GroupData(index,\&pgroup);}\\
+ && {\t vtype = pgroup.vartype;}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupDynamicData}{Given a group index, returns information about the variables held in the group.}
+\label{CCTK-GroupDynamicData}
+\function{int}{}{ierr}
+\argument{const cGH *}{}{cctkGH}
+\argument{int}{}{group}
+\argument{cGroupDynamicData *}{}{pdata}
+\showcargs
+\begin{params}
+\parameter{ierr}{0 for success, negative for failure}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{group}{group index}
+\parameter{pdata}{returns a pointer to a structure containing group information}
+\end{params}
+\begin{discussion}
+The cGroupDynamicData structure contains the information
+\begin{itemize}
+\item dim: The dimension of variables in the group
+\item gsh[dim]: The global size of the group in each dimension
+\item lsh[dim]: The local size of the group in each dimension
+\item lbnd[dim]: The lower bounds of the group in each dimension
+\item ubnd[dim]: The upper bounds of the group in each dimension
+\item bbox[2*dim]: The bounding box of the group for each face
+\item nghostzones[dim]: The number of ghostzones in each dimension of the group
+\end{itemize}
+No Fortran routine exists at the moment.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t cGroupDynamicData pdata;}\\
+ && {\t index = CCTK\_GroupIndex("evolve::scalars");}\\
+ &&{\t ierr = CCTK\_GroupDynamicData(cctkGH,index,\&pgroup);}\\
+ && {\t vdim = pdata.dim;}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{FunctionDescription}{CCTK\_GroupgshGI, CCTK\_GroupgshGN}
+\label{CCTK-GroupgshGI}
+\label{CCTK-GroupgshGN}
+Given a group index or name, return an array of the global size of the group in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupgshGI(const cGH *cctkGH,
+ int dim,
+ int *gsh,
+ int groupindex);
+
+int status = CCTK_GroupgshGN(const cGH *cctkGH,
+ int dim,
+ int *gsh,
+ const char *groupname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupgshGI(status, cctkGH, dim, gsh, groupindex)
+
+call CCTK_GroupgshGN(status, cctkGH, dim, gsh, groupname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer gsh(dim)
+integer groupindex
+character*(*) groupname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid group name \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of group. \end{Parameter}
+\begin{Parameter}{gsh ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{groupindex} Index of the group. \end{Parameter}
+\begin{Parameter}{groupname} Name of the group. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The global size in each dimension for a given group is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupgshVI, CCTK\_GroupgshVN}
+Returns the global size for a given variable.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplshGI, CCTK\_GrouplshGN}
+Returns the local size for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplshVI, CCTK\_GrouplshVN}
+Returns the local size for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GroupgshVI, CCTK\_GroupgshVN}
+\label{CCTK-GroupgshVI}
+\label{CCTK-GroupgshVN}
+Given a variable index or its full name, return an array of the global size of the variable in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupgshVI(const cGH *cctkGH,
+ int dim,
+ int *gsh,
+ int varindex);
+
+int status = CCTK_GroupgshVN(const cGH *cctkGH,
+ int dim,
+ int *gsh,
+ const char *varname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupgshVI(status, cctkGH, dim, gsh, varindex)
+
+call CCTK_GroupgshVN(status, cctkGH, dim, gsh, varname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer gsh(dim)
+integer varindex
+chararacter*(*) varname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid variable index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of variable. \end{Parameter}
+\begin{Parameter}{gsh ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{varindex} Variable index. \end{Parameter}
+\begin{Parameter}{varname} Variable's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The global size in each dimension for a given variable is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupgshGI, CCTK\_GroupgshGN}
+Returns the global size for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplshGI, CCTK\_GrouplshGN}
+Returns the local size for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplshVI, CCTK\_GrouplshVN}
+Returns the local size for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupIndex}{Get the index number for a group name}
+\label{CCTK-GroupIndex}
+\subroutine{int}{integer}{index}
+\argument{const char *}{character*(*)}{groupname}
+\showargs
+\begin{params}
+\parameter{groupname}{The name of the group}
+\end{params}
+\begin{discussion}
+The group name should be the given in its fully qualified form, that is {\t <implementation>::<group>} for a public or protected group, and {\t <thornname>::<group>} for a private group.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_GroupIndex("evolve::scalars") };
+\\
+\hfill {\bf Fortran} && call {\t CCTK\_GroupIndex(index,"evolve::scalars")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupIndexFromVar}{Given a variable name, returns the index of the associated group}
+\label{CCTK-GroupIndexFromVar}
+\subroutine{int}{integer}{groupindex}
+\argument{const char *}{character*(*)}{name}
+\showargs
+\begin{params}
+\parameter{groupindex}{The index of the group}
+\parameter{name}{The full name of the variable}
+\end{params}
+\begin{discussion}
+The variable name should be in the form {\t <implementation>::<variable>}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t groupindex = CCTK\_GroupIndexFromVar("evolve::phi") ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_GROUPINDEXFROMVAR(groupindex,"evolve::phi")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupIndexFromVarI}{Given a variable index, returns the index of the associated group}
+\label{CCTK-GroupIndexFromVarI}
+\subroutine{int}{integer}{groupindex}
+\argument{int}{integer}{varindex}
+\showargs
+\begin{params}
+\parameter{groupindex}{The index of the group}
+\parameter{varindex}{The index of the variable}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_VarIndex("evolve::phi");} \\
+ && {\t groupindex = CCTK\_GroupIndexFromVarI(index) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_VARINDEX("evolve::phi")}\\
+ &&call {\t CCTK\_GROUPINDEXFROMVARI(groupindex,index)}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{FunctionDescription}{CCTK\_GrouplbndGI, CCTK\_GrouplbndGN}
+\label{CCTK-GrouplbndGI}
+\label{CCTK-GrouplbndGN}
+Given a group index or name, return an array of the lower bounds of the group in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GrouplbndGI(const cGH *cctkGH,
+ int dim,
+ int *lbnd,
+ int groupindex);
+
+int status = CCTK_GrouplbndGN(const cGH *cctkGH,
+ int dim,
+ int *lbnd,
+ const char *groupname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GrouplbndGI(status, cctkGH, dim, lbnd, groupindex)
+
+call CCTK_GrouplbndGN(status, cctkGH, dim, lbnd, groupname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer lbnd(dim)
+integer groupindex
+character*(*) groupname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid group index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of group. \end{Parameter}
+\begin{Parameter}{lbnd ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{groupindex} Group index. \end{Parameter}
+\begin{Parameter}{groupname} Group's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The lower bounds in each dimension for a given group is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GrouplbndVI, CCTK\_GrouplbndVN}
+Returns the lower bounds for a given variable.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GroupubndGI, CCTK\_GroupubndGN}
+Returns the upper bounds for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GroupubndVI, CCTK\_GroupubndVN}
+Returns the upper bounds for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GrouplbndVI, CCTK\_GrouplbndVN}
+\label{CCTK-GrouplbndVI}
+\label{CCTK-GrouplbndVN}
+Given a variable index or name, return an array of the lower bounds of the variable in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GrouplbndVI(const cGH *cctkGH,
+ int dim,
+ int *lbnd,
+ int varindex);
+
+int status = CCTK_GrouplbndVN(const cGH *cctkGH,
+ int dim,
+ int *lbnd,
+ const char *varname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GrouplbndVI(status, cctkGH, dim, lbnd, varindex)
+
+call CCTK_GrouplbndVN(status, cctkGH, dim, lbnd, varname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer lbnd(dim)
+integer varindex
+character*(*) varname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid variable index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of variable. \end{Parameter}
+\begin{Parameter}{lbnd ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{varindex} Group index. \end{Parameter}
+\begin{Parameter}{varname} Group's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The lower bounds in each dimension for a given variable is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GrouplbndGI, CCTK\_GrouplbndGN}
+Returns the lower bounds for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GroupubndGI, CCTK\_GroupubndGN}
+Returns the upper bounds for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GroupubndVI, CCTK\_GroupubndVN}
+Returns the upper bounds for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GrouplshGI, CCTK\_GrouplshGN}
+\label{CCTK-GrouplshGI}
+\label{CCTK-GrouplshGN}
+Given a group index or name, return an array of the local size of the group in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GrouplshGI(const cGH *cctkGH,
+ int dim,
+ int *lsh,
+ int groupindex);
+
+int status = CCTK_GrouplshGN(const cGH *cctkGH,
+ int dim,
+ int *lsh,
+ const char *groupname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GrouplshGI(status, cctkGH, dim, lsh, groupindex)
+
+call CCTK_GrouplshGN(status, cctkGH, dim, lsh, groupname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer lsh(dim)
+integer groupindex
+character*(*) groupname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid group name \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of group. \end{Parameter}
+\begin{Parameter}{lsh ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{groupindex} Index of the group. \end{Parameter}
+\begin{Parameter}{groupname} Name of the group. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The local size in each dimension for a given group is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupgshVI, CCTK\_GroupgshVN}
+Returns the global size for a given variable.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplshGI, CCTK\_GrouplshGN}
+Returns the local size for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplshVI, CCTK\_GrouplshVN}
+Returns the local size for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GrouplshVI, CCTK\_GrouplshVN}
+\label{CCTK-GrouplshVI}
+\label{CCTK-GrouplshVN}
+Given a variable index or its full name, return an array of the local size of the variable in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GrouplshVI(const cGH *cctkGH,
+ int dim,
+ int *lsh,
+ int varindex);
+
+int status = CCTK_GrouplshVN(const cGH *cctkGH,
+ int dim,
+ int *lsh,
+ const char *varname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GrouplshVI(status, cctkGH, dim, lsh, varindex)
+
+call CCTK_GrouplshVN(status, cctkGH, dim, lsh, varname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer lsh(dim)
+integer varindex
+character*(*) varname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid variable index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of variable. \end{Parameter}
+\begin{Parameter}{lsh ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{varindex} Variable index. \end{Parameter}
+\begin{Parameter}{varname} Variable's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The local size in each dimension for a given variable is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupgshGI, CCTK\_GroupgshGN}
+Returns the global size for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GroupgshVI, CCTK\_GroupgshVN}
+Returns the global size for a given variable.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplshGI, CCTK\_GrouplshGN}
+Returns the local size for a given group.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupName}{Given a group index, returns the group name}
+\label{CCTK-GroupName}
+\subroutine{char *}{integer}{name}
+\argument{int}{integer}{index}
+\showcargs
+\begin{params}
+\parameter{name}{The group name}
+\parameter{index}{The group index}
+\end{params}
+\begin{discussion}
+\fbox{The group name must be explicitly freed after it has been used.}
+
+No Fortran routine exists at the moment.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_GroupIndex("evolve::scalars");}\\
+ && {\t name = CCTK\_GroupName(index);}\\
+ && {\t printf ("Group name: \%s", name);}\\
+ && {\t free (name);}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupNameFromVarI}{Given a variable index, return the name of the associated group}
+\label{CCTK-GroupNameFromVarI}
+\subroutine{char *}{character*(*)}{group}
+\argument{int}{integer}{varindex}
+\showcargs
+\begin{params}
+\parameter{group}{The name of the group}
+\parameter{varindex}{The index of the variable}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_VarIndex("evolve::phi");} \\
+ && {\t group = CCTK\_GroupNameFromVarI(index) ;}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+\begin{FunctionDescription}{CCTK\_GroupnghostzonesGI, CCTK\_GroupnghostzonesGN}
+\label{CCTK-GroupnghostzonesGI}
+\label{CCTK-GroupnghostzonesGN}
+ Given a group index or name, return an array with the number of ghostzones in each dimension of the group
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupnghostzonesGI(const cGH *cctkGH,
+ int dim,
+ int *nghostzones,
+ int groupindex)
+
+int status = CCTK_GroupnghostzonesGN(const cGH *cctkGH,
+ int dim,
+ int *nghostzones,
+ const char *groupname)
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupnghostzonesGI(status, cctkGH, dim, nghostzones, groupindex)
+
+call CCTK_GroupnghostzonesGN(status, cctkGH, dim, nghostzones, groupname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer nghostzones(dim)
+integer groupindex
+character*(*) groupname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of group. \end{Parameter}
+\begin{Parameter}{nghostzones ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{groupindex} Group index. \end{Parameter}
+\begin{Parameter}{groupname} Group name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The number of ghostzones in each dimension for a given group is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupnghostzonesVI, CCTK\_GroupnghostzonesVN}
+Returns the number of ghostzones for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GroupnghostzonesVI, CCTK\_GroupnghostzonesVN}
+\label{CCTK-GroupnghostzonesVI}
+\label{CCTK-GroupnghostzonesVN}
+ Given a variable index or its full name, return an array with the number of ghostzones in each dimension of the variable
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupnghostzonesVI(const cGH *cctkGH,
+ int dim,
+ int *nghostzones,
+ int varindex)
+
+int status = CCTK_GroupnghostzonesVN(const cGH *cctkGH,
+ int dim,
+ int *nghostzones,
+ const char *varname)
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupnghostzonesVI(status, cctkGH, dim, nghostzones, varindex)
+
+call CCTK_GroupnghostzonesVN(status, cctkGH, dim, nghostzones, varname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer nghostzones(dim)
+integer varindex
+character*(*) varname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of group. \end{Parameter}
+\begin{Parameter}{nghostzones ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{varindex} Variable index. \end{Parameter}
+\begin{Parameter}{varname} Variable's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The number of ghostzones in each dimension for a given variable is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupnghostzonesGI, CCTK\_GroupnghostzonesGN}
+Returns the number of ghostzones for a given group.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_GroupTypeFromVarI}{Provides a group's group type
+ index given a variable index}
+\label{CCTK-GroupTypeFromVarI}
+\subroutine{int}{integer}{type}
+\argument{int}{integer}{index}
+\showargs
+\begin{params}
+\parameter{type}{The group's group type index}
+\parameter{group}{The variable index}
+\end{params}
+\begin{discussion}
+The group's group type index indicates the type of variables in the group.
+Either scalars, grid functions or arrays. The group type can be checked
+with the Cactus provided macros for {\t CCTK\_SCALAR}, {\t CCTK\_GF}, {\t CCTK\_ARRAY}.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_GroupIndex("evolve::scalars")}\\
+ &&{\t array = (CCTK\_ARRAY == CCTK\_GroupTypeFromVarI(index)) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_GROUPTYPEFROMVARI(type,3)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{FunctionDescription}{CCTK\_GroupTypeI}{}
+\label{CCTK-GroupTypeI}
+Provides a group's group type index given a group index
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+int group_type = CCTK_GroupTypeI(int group);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{-1}
+-1 is returned if the given group index is invalid.
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{group}
+Group index.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+A group's group type index indicates the type of variables in the
+group. The three group types are scalars, grid functions, and grid
+arrays. The group type can be checked with the Cactus provided macros
+for {\t CCTK\_SCALAR}, {\t CCTK\_GF}, {\t CCTK\_ARRAY}.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GroupTypeFromVarI}
+This function takes a variable index rather than a group index as its argument.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+%\begin{ErrorSection}
+%\end{ErrorSection}
+%\begin{ExampleSection}
+%\end{ExampleSection}
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GroupubndGI, CCTK\_GroupubndGN}
+\label{CCTK-GroupubndGI}
+\label{CCTK-GroupubndGN}
+Given a group index or name, return an array of the upper bounds of the group in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupubndGI(const cGH *cctkGH,
+ int dim,
+ int *ubnd,
+ int groupindex);
+
+int status = CCTK_GroupubndGN(const cGH *cctkGH,
+ int dim,
+ int *ubnd,
+ const char *groupname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupubndGI(status, cctkGH, dim, ubnd, groupindex)
+
+call CCTK_GroupubndGN(status, cctkGH, dim, ubnd, groupname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer ubnd(dim)
+integer groupindex
+character*(*) groupname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid group index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of group. \end{Parameter}
+\begin{Parameter}{ubnd ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{groupindex} Group index. \end{Parameter}
+\begin{Parameter}{groupname} Group's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The upper bounds in each dimension for a given group is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GrouplbndGI, CCTK\_GrouplbndGN}
+Returns the lower bounds for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplbndVI, CCTK\_GrouplbndVN}
+Returns the lower bounds for a given variable.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GroupubndVI, CCTK\_GroupubndVN}
+Returns the upper bounds for a given variable.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_GroupubndVI, CCTK\_GroupubndVN}
+\label{CCTK-GroupubndVI}
+\label{CCTK-GroupubndVN}
+Given a variable index or name, return an array of the upper bounds of the variable in each dimension
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status = CCTK_GroupubndVI(const cGH *cctkGH,
+ int dim,
+ int *ubnd,
+ int varindex);
+
+int status = CCTK_GroupubndVN(const cGH *cctkGH,
+ int dim,
+ int *ubnd,
+ const char *varname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_GroupubndVI(status, cctkGH, dim, ubnd, varindex)
+
+call CCTK_GroupubndVN(status, cctkGH, dim, ubnd, varname)
+
+integer status
+CCTK_POINTER cctkGH
+integer dim
+integer ubnd(dim)
+integer varindex
+character*(*) varname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{\rm -1} incorrect dimension supplied \end{Result}
+\begin{Result}{\rm -2} data not available from driver \end{Result}
+\begin{Result}{\rm -3} called on a scalar group \end{Result}
+\begin{Result}{\rm -4} invalid variable index \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{status} Return value. \end{Parameter}
+\begin{Parameter}{cctkGH ($\ne$ NULL)} Pointer to a valid Cactus grid hierarchy. \end{Parameter}
+\begin{Parameter}{dim ($\ge 1$)} Number of dimensions of variable. \end{Parameter}
+\begin{Parameter}{ubnd ($\ne$ NULL)} Pointer to array which will hold the return values. \end{Parameter}
+\begin{Parameter}{varindex} Group index. \end{Parameter}
+\begin{Parameter}{varname} Group's full name. \end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The upper bounds in each dimension for a given variable is returned in a user-supplied array buffer.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_GrouplbndGI, CCTK\_GrouplbndGN}
+Returns the lower bounds for a given group.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GrouplbndVI, CCTK\_GrouplbndVN}
+Returns the lower bounds for a given variable.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_GroupubndGI, CCTK\_GroupubndGN}
+Returns the upper bounds for a given group.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\end{FunctionDescription}
+
+
+%%%%%
+% HHH
+%%%%%
+
+%%%%%
+% III
+%%%%%
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_ImpFromVarI}{Given a variable index, returns the implementation name}
+\label{CCTK-ImpFromVarI}
+\subroutine{char *}{integer}{implementation}
+\argument{int}{integer}{index}
+\showcargs
+\begin{params}
+\parameter{implementation}{The implementation name}
+\parameter{index}{The variable index}
+\end{params}
+\begin{discussion}
+No Fortran routine exists at the moment
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_VarIndex("evolve::phi");}\\
+ &&{\t implementation = CCTK\_ImpFromVarI(index);}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+
+% WarnLevel.c
+\begin{FunctionDescription}{CCTK\_INFO}
+\label{CCTK-INFO}
+Macro to print a single string as an information message to screen
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarnLevel.h"
+
+CCTK_INFO(const char *message);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+call CCTK_INFO(message)
+character*(*) message
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{message}
+The string to print as an info message
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This macro can be used by thorns to print a single string as an info message
+to screen.
+
+{\tt CCTK\_INFO(level, message)} expands to a call to the underlying function
+{\tt CCTK\_Info()}:
+
+\begin{verbatim}
+CCTK_Info(CCTK_THORNSTRING, message)
+\end{verbatim}
+
+So the macro automatically includes the name of the originating thorn in the
+info message. It is recommended that the macro {\tt CCTK\_INFO} is used
+to print a message rather than calling {\tt CCTK\_Info()} directly.
+
+To include variables in an info message from C, you can use the routine
+{\tt CCTK\_VInfo()} which accepts a variable argument list.
+To include variables from Fortran, a string must be constructed and passed
+in a {\tt CCTK\_INFO} macro.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_VInfo()}
+prints a formatted string with a variable argument list as an info message to
+screen
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarningLevel.h"
+
+CCTK_INFO("Output is disabled");
+\end{verbatim}
+\end{Example}
+\begin{Example}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+integer myint
+real myreal
+character*200 message
+
+write(message, '(A32, G12.7, A5, I8)')
+& 'Your info message, including ', myreal, ' and ', myint
+call CCTK_INFO(message)
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{CCTK\_InterpGridArrays}
+\label{CCTK-InterpGridArrays}
+Interpolate a list of distributed grid arrays
+
+(This function will eventually replace \verb|CCTK_InterpGV()|;
+see the Cactus web pages ``Development'' section for further details.)
+
+The computation is optimized for the case of interpolating a
+number of grid arrays at a time; in this case all the interprocessor
+communication can be done together, and the same interpolation
+coefficients can be used for all the arrays.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int status =
+ CCTK_InterpGridArrays(const cGH *cctkGH,
+ int N_dims,
+ int local_interp_handle, int param_table_handle,
+ int coord_system_handle,
+ int N_interp_points,
+ const int interp_coords_type_code,
+ const void *const interp_coords[],
+ int N_input_arrays,
+ const CCTK_INT input_array_variable_indices[],
+ int N_output_arrays,
+ const CCTK_INT output_array_type_codes[],
+ void *const output_arrays[]);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_InterpGridArrays(status,
+. cctkGH,
+. N_dims,
+. local_interp_handle, param_table_handle,
+. coord_system_handle,
+. N_interp_points,
+. interp_coords_type_code, interp_coords,
+. N_input_arrays, input_array_variable_indices,
+. N_output_arrays, output_array_type_codes,
+. output_arrays)
+integer status
+CCTK_POINTER cctkGH
+integer local_interp_handle, param_table_handle, coord_system_handle
+integer N_dims, N_interp_points, N_input_arrays, N_output_arrays
+CCTK_POINTER interp_coords(N_dims)
+integer interp_coords_type_code
+CCTK_INT input_array_variable_indices(N_input_arrays)
+CCTK_INT output_array_type_codes(N_output_arrays)
+CCTK_POINTER output_arrays(N_output_arrays)
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0} success \end{Result}
+\begin{Result}{$< 0$} indicates an error condition (see {\bf Errors}) \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{cctkGH ($\ne$ NULL)}
+Pointer to a valid Cactus grid hierarchy.
+\end{Parameter}
+\begin{Parameter}{N\_dims ($\ge 1$)}
+Number of dimensions in which to interpolate.
+This must be $\leq$ the dimensionality of the coordinate system defined
+by \verb|coord_system_handle|. The default case is that it's $=$; see
+the discussion of the \verb|interpolation_hyperslab_handle| parameter-table
+entry for the $<$ case.
+\end{Parameter}
+\begin{Parameter}{local\_interp\_handle ($\ge 0$)}
+Handle to the local interpolation operator as returned by
+\verb|CCTK_InterpHandle()|.
+\end{Parameter}
+\begin{Parameter}{param\_table\_handle ($\ge 0$)}
+Handle to a key-value table containing zero or more additional parameters
+for the interpolation operation. The table is allowed to be modified by the
+local and/or global interpolation routine(s).
+\end{Parameter}
+\begin{Parameter}{coord\_system\_handle ($\ge 0$)}
+Cactus coordinate system handle defining the mapping between
+(usually floating-point) coordinates and integer grid subscripts, as returned by
+\verb|CCTK_CoordSystemHandle()|.
+\end{Parameter}
+\begin{Parameter}{N\_interp\_points ($\ge 0$)}
+The number of interpolation points requested by this processor.
+\end{Parameter}
+\begin{Parameter}{interp\_coords\_type\_code}
+One of the \verb|CCTK_VARIABLE_|* type codes, giving the data type of the
+interpolation-point coordinate arrays pointed to by \verb|interp_coords[]|.
+All interpolation-point coordinate arrays must be of the same data type.
+\end{Parameter}
+\begin{Parameter}{interp\_coords ($\ne$ NULL)}
+(Pointer to) an array of \verb|N_dims| pointers to 1-D arrays giving the
+coordinates of the interpolation points requested by this processor.
+These coordinates are with respect to the coordinate system defined by
+\verb|coord_system_handle|.
+\end{Parameter}
+\begin{Parameter}{N\_input\_arrays ($\ge 0$)}
+The number of input arrays to be interpolated.
+If {\tt N\_input\_arrays} is zero then no interpolation is done; such a call
+may be useful for setup, interpolator querying, etc.
+Note that if the parameter table entry \verb|operand_indices| is used to specify
+a nontrivial (eg. 1-to-many) mapping of input arrays to output arrays, only the
+unique set of input arrays should be given here.
+\end{Parameter}
+\begin{Parameter}{input\_array\_variable\_indices ($\ne$ NULL)}
+(Pointer to) an array of \verb|N_input_arrays| CCTK grid array indices (as
+returned by \verb|CCTK_VarIndex()|) specifying the input grid arrays for the
+interpolation. For any element with an index value of -1 in the grid array
+indices array, that interpolation is skipped. This may be useful if the main
+purpose of the call is eg. to do some query or setup computation.
+\end{Parameter}
+\begin{Parameter}{N\_output\_arrays ($\ge 0$)}
+The number of output arrays to be returned from the interpolation.
+If {\tt N\_output\_arrays} is zero then no interpolation is done; such a call
+may be useful for setup, interpolator querying, etc.
+Note that {\tt N\_output\_arrays} may differ from {\tt N\_input\_arrays}, eg.
+if the {\tt operand\_indices} parameter-table entry is used to specify a
+nontrivial (eg. many-to-1) mapping of input arrays to output arrays.
+If such a mapping is specified, only the unique set of output arrays
+should be given in the {\tt output\_arrays} argument.
+\end{Parameter}
+\begin{Parameter}{output\_array\_type\_codes ($\ne$ NULL)}
+(Pointer to) an array of \verb|N_output_arrays| \verb|CCTK_VARIABLE_|*
+type codes giving the data types of the 1-D output arrays pointed to by
+\verb|output_arrays[]|.
+\end{Parameter}
+\begin{Parameter}{output\_arrays ($\ne$ NULL)}
+(Pointer to) an array of \verb|N_output_arrays| pointers to the
+(user-supplied) 1-D output arrays for the interpolation.
+If any of the pointers in the {\tt output\_arrays} array is NULL, then that
+interpolation is skipped. This may be useful if the main purpose of the call
+is eg. to do some query or setup computation.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function interpolates a list of CCTK grid arrays (in a multiprocessor run
+these are generally distributed over processors) on a list of interpolation
+points. The grid topology and coordinates are implicitly specified via a Cactus
+coordinate system.
+The interpolation points may be anywhere in the global Cactus grid.
+In a multiprocessor run they may vary from processor to processor;
+each processor will get whatever interpolated data it asks for.
+The routine {\tt CCTK\_InterpGridArrays()} does not do the actual interpolation
+itself but rather takes care of whatever interprocessor communication may be
+necessary, and -- for each processor's local patch of the domain-decomposed grid
+arrays -- calls {\tt CCTK\_InterpLocalUniform()} to invoke an external
+local interpolation operator (as identified by an interpolation handle).
+
+Additional parameters for the interpolation operation of both
+{\tt CCTK\_InterpGridArrays()} and {\tt CCTK\_InterpLocalUniform()} can be
+passed in via a handle to a key/value options table.
+All interpolation operators should check for a parameter table entry with the
+key \verb|"suppress_warnings"| which -- if present -- indicates that the
+caller wants the interpolator to be silent in case of an error condition and
+only return an appropriate error code.
+One common parameter-table option, which a number of interpolation
+operators are likely to support, is \verb|order|, a \verb|CCTK_INT|
+specifying the order of the (presumably polynomial) interpolation
+(1=linear, 2=quadratic, 3=cubic, etc).
+As another example, a table might be used to specify that the local interpolator
+should take derivatives, by specifying
+\begin{verbatim}
+const CCTK_INT operand_indices[N_output_arrays];
+const CCTK_INT operation_codes[N_output_arrays];
+\end{verbatim}
+Also, the global interpolator will typically need to specify some options
+of its own for the local interpolator.\footnote{
+It is the caller's responsibility to ensure that the specified local
+interpolator supports any optional parameter-table entries that
+{\tt CCTK\_InterpGridArrays()} passes to it. Each thorn providing a
+{\tt CCTK\_InterpLocalUniform()} interpolator should document what options it
+requires from the global interpolator.
+}
+These will overwrite any entries
+with the same keys in the \verb|param_table_handle| table.
+Finally, the parameter table can be used to pass back arbitrary information by the local
+and/or global interpolation routine(s) by adding/modifying appropriate
+key/value pairs.
+
+Note that {\tt CCTK\_InterpGridArrays()} is a collective operation, so in the
+multiprocessor case you {\em must\/} call this function in parallel on
+{\em each\/} processor, passing identical arguments except for the number of
+interpolation points, the interpolation coordinates, and the output array pointers.
+You may (and typically will) specify a different set of
+interpolation points on each processor's call -- you may even specify
+an empty set on some processors. The interpolation points may be
+``owned'' by any processors (this function takes care of all
+interprocessor-communication issues), though it may be more efficient
+to have most or all of the interpolation points ``owned'' by the
+current processor.
+
+The semantics of {\tt CCTK\_InterpGridArrays()} are mostly independent of
+which Cactus driver is being used, but an implementation will most likely depend
+on, and make use of, driver-specific internals. For that reason,
+{\tt CCTK\_InterpGridArrays()} is made an overloadable function. The Cactus
+flesh will supply only a dummy routine for it which -- if called -- does nothing
+but print a warning message saying that it wasn't overloaded by another thorn,
+and stop the code. So one will always need to compile in and activate
+a driver-specific thorn which provides an interpolation routine for CCTK grid
+arrays and properly overloads {\tt CCTK\_InterpGridArrays()} with it at startup.
+
+Details of the operation performed, and what (if any) inputs and/or
+outputs are specified in the parameter table, depend on which driver-specific
+interpolation thorn and interpolation operator (provided by a local
+interpolation thorn) you use. See the documentation on individual interpolator
+thorns (eg. {\tt PUGHInterp} in the {\tt CactusPUGH} arrangement,
+{\tt LocalInterp} in the {\tt CactusBase} arrangement, and/or
+{\tt AEILocalInterp} in the {\tt AEIThorns} arrangement) for details.
+
+Note that in a multiprocessor Cactus run, it's the user's responsibility
+to choose the interprocessor ghost-zone size (\verb|driver::ghost_size|)
+large enough so that the local interpolator never has to off-center
+its molecules near interprocessor boundaries. (This ensures that the
+interpolation results are independent of the interprocessor decomposition,
+at least up to floating-point roundoff errors.)
+If the ghost-zone size is too small, the interpolator should return
+the \verb|CCTK_ERROR_INTERP_GHOST_SIZE_TOO_SMALL| error code.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_InterpHandle()}
+Get the interpolator handle for a given character-string name.
+\end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpLocalNonUniform()}
+%notyet Interpolate a list of processor-local arrays
+%notyet which define a nonuniformly spaced data grid (not implemented yet)
+%notyet \end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpLocalUniform()}
+Interpolate a list of processor-local arrays
+which define a uniformly-spaced data grid
+\end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpLocalWarped()}
+%notyet Interpolate a list of processor-local arrays
+%notyet which define a curvilinearly-warped data grid (not implemented yet)
+%notyet \end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpGV()}
+Older API to interpolate a list of Cactus grid arrays.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpLocal()}
+Older API to interpolate a list of processor-local arrays.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{}
+The following list of error
+codes indicates specific error conditions. For the complete list of possible
+error return codes you should refer to the ThornGuide's chapter of the
+corresponding interpolation thorn(s) you are using. To find the numerical
+values of the error codes (or more commonly, to find which error code
+corresponds to a given numerical value), look in the files
+\verb|cctk_Interp.h|, \verb|util_ErrorCodes.h|, and/or \verb|util_Table.h|
+in the \verb|src/include/| directory in the Cactus flesh.
+\end{Error}
+\begin{Error}{CCTK\_ERROR\_INTERP\_POINT\_OUTSIDE}
+one or more of the interpolation points is out of range
+(in this case additional information about the out-of-range point
+may be reported through the parameter table; see the Thorn Guide for
+whatever thorn provides the local interpolation operator for further
+details)
+\end{Error}
+\begin{Error}{CCTK\_ERROR\_INTERP\_GRID\_TOO\_SMALL}
+one or more of the dimensions of the input arrays is/are smaller than
+the molecule size chosen by the interpolator (based on the parameter-table
+options, e.g.\ the interpolation order)
+\end{Error}
+\begin{Error}{CCTK\_ERROR\_INTERP\_GHOST\_SIZE\_TOO\_SMALL}
+for a multi-processor run, the size of the interprocessor boundaries (the {\em ghostzone} size) is smaller than the molecule size chosen by the interpolator
+(based on the parameter-table options, e.g.\ the interpolation order).\\
+This error code is also returned if a processor's chunk of the global grid
+is smaller than the actual molecule size.
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+one or more of the input arguments is invalid (eg.~\verb|NULL| pointer)
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+parameter table handle is invalid
+\end{Error}
+\begin{Error}{other error codes}
+this function may also return any error codes returned by the
+\verb|Util_Table*()| routines used to get parameters from
+(and/or set results in) the parameter table
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+Here's a simple example to do quartic 3-D interpolation of a real
+and a complex grid array, at 1000 interpolation points:
+\begin{verbatim}
+#include "cctk.h"
+#include "util_Table.h"
+
+#define N_DIMS 3
+#define N_INTERP_POINTS 1000
+#define N_INPUT_ARRAYS 2
+#define N_OUTPUT_ARRAYS 2
+
+const cGH *GH;
+int operator_handle, coord_system_handle;
+
+/* interpolation points */
+CCTK_REAL interp_x[N_INTERP_POINTS],
+ interp_y[N_INTERP_POINTS],
+ interp_z[N_INTERP_POINTS];
+static const CCTK_INT interp_coord_type_codes[N_DIMS]
+ = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL };
+const void *interp_coords[N_DIMS];
+
+/* input and output arrays */
+CCTK_INT input_array_variable_indices[N_INPUT_ARRAYS];
+static const CCTK_INT output_array_type_codes[N_OUTPUT_ARRAYS]
+ = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_COMPLEX };
+void *output_arrays[N_OUTPUT_ARRAYS];
+CCTK_REAL output_for_real_array [N_INTERP_POINTS];
+CCTK_COMPLEX output_for_complex_array[N_INTERP_POINTS];
+
+operator_handle = CCTK_InterpHandle("generalized polynomial interpolation");
+if (operator_handle < 0)
+{
+ CCTK_WARN(-1, "can't get operator handle!");
+}
+
+coord_system_handle = CCTK_CoordSystemHandle("cart3d");
+if (coord_system_handle < 0)
+{
+ CCTK_WARN(-1, "can't get coordinate-system handle!");
+}
+
+interp_coords[0] = (const void *) interp_x;
+interp_coords[1] = (const void *) interp_y;
+interp_coords[2] = (const void *) interp_z;
+input_array_variable_indices[0] = CCTK_VarIndex("my_thorn::real_array");
+input_array_variable_indices[1] = CCTK_VarIndex("my_thorn::complex_array");
+output_arrays[0] = (void *) output_for_real_array;
+output_arrays[1] = (void *) output_for_complex_array;
+
+if (CCTK_InterpGridArrays(GH, N_DIMS,
+ operator_handle,
+ Util_TableCreateFromString("order=4"),
+ coord_system_handle,
+ N_INTERP_POINTS, interp_coord_type_codes,
+ interp_coords,
+ N_INPUT_ARRAYS, input_array_variable_indices,
+ N_OUTPUT_ARRAYS, output_array_type_codes,
+ output_arrays) < 0)
+{
+ CCTK_WARN(-1, "error return from interpolator!");
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Interp.c
+\begin{CCTKFunc}{CCTK\_InterpGV}%%%
+{Perform an interpolation on a list of distributed CCTK grid variables,
+using a chosen interpolation operator
+\\[\baselineskip]
+This function is being phased out; it will eventually be replaced by
+{\t CCTK\_InterpGridArrays()}.}
+\label{CCTK-InterpGV}
+\subroutine{int}{integer}{ierr}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{int}{integer}{operator\_handle}
+\argument{int}{integer}{coord\_system\_handle}
+\argument{int}{integer}{num\_points}
+\argument{int}{integer}{num\_in\_array\_indices}
+\argument{int}{integer}{num\_out\_arrays}
+\argument{...}{...}{}
+\argument{{\it num\_dims} * void *}{{\it num\_dims} * CCTK\_POINTER}{interp\_coord\_arrays}
+\argument{{\it num\_dims} * int}{{\it num\_dims} * integer}{interp\_coord\_array\_types}
+\argument{{\it num\_array\_indices} * int}{{\it num\_array\_indices} * integer}{in\_array\_indices}
+\argument{{\it num\_out\_arrays} * void *}{{\it num\_out\_arrays} * CCTK\_POINTER}{out\_arrays}
+\argument{{\it num\_out\_arrays} * int}{{\it num\_out\_arrays} * integer}{out\_array\_types}
+\showargs
+\begin{params}
+\parameter{cctkGH}{Pointer to the CCTK grid hierarchy}
+\parameter{operator\_handle}{Handle for the interpolation operator}
+\parameter{coord\_system\_handle}{Handle for the coordinate system.\newline
+This handle denotes the coordinate system to use for locating the points to
+interpolate at.}
+\parameter{num\_points}{Number of points to be interpolated on this processor}
+\parameter{num\_in\_array\_indices}{Number of passed input array indices}
+\parameter{num\_out\_arrays}{Number of passed output arrays}
+\parameter{...}{Variable argument list, with arguments as following}
+\parameter{interp\_coord\_arrays}{List of coordinate arrays for points to interpolate at ({\it num\_dims} is the number of dimensions of the coordinate system)}
+\parameter{interp\_coord\_array\_types}{List of CCTK datatypes for coordinate arrays}
+\parameter{in\_array\_indices}{List of CCTK grid variables to interpolate (given by their indices)}
+\parameter{out\_arrays}{List of output arrays}
+\parameter{out\_array\_types}{List of CCTK datatypes for output arrays}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t
+int interp\_handle, coord\_system\_handle;
+CCTK\_REAL coord\_x[NUM\_POINTS], coord\_y[NUM\_POINTS];
+int my\_grid\_fn1, my\_grid\_fn2;
+CCTK\_REAL my\_out\_array1[NUM\_POINTS];
+CCTK\_COMPLEX my\_out\_array2[NUM\_POINTS];\linebreak
+interp\_handle =\vfill
+\hspace{2ex} CCTK\_InterpHandle("my interpolation operator");
+coord\_system\_handle =\vfill
+\hspace{2ex} CCTK\_CoordSystemHandle("my 2D coordinate system");
+my\_grid\_fn1 = CCTK\_VarIndex("myThorn::myGF1");
+my\_grid\_fn2 = CCTK\_VarIndex("myThorn::myGF2");\linebreak
+ierr = CCTK\_InterpGV(cctkGH,\vfill
+\hspace{2ex} interp\_handle, coord\_system\_handle,\vfill
+\hspace{2ex} NUM\_POINTS, 2, 2,\vfill
+\hspace{2ex} coord\_x, coord\_y,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_REAL,\vfill
+\hspace{2ex} my\_grid\_fn1, my\_grid\_fn2,\vfill
+\hspace{2ex} my\_out\_array1, my\_out\_array2,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_COMPLEX);
+}
+\\
+\hfill {\bf Fortran} && {\t
+integer interp\_handle, coord\_system\_handle
+CCTK\_REAL coord(NUM\_POINTS)
+integer my\_grid\_fn1, my\_grid\_fn2, my\_grid\_fn3
+CCTK\_REAL my\_out\_array1(NUM\_POINTS)
+CCTK\_COMPLEX my\_out\_array2(NUM\_POINTS)
+CCTK\_INT my\_out\_array3(NUM\_POINTS)\linebreak
+call CCTK\_InterpHandle(interp\_handle,\vfill\hspace{2ex}"my interpolation operator")
+call CCTK\_CoordSystemHandle(coord\_system\_handle,\vfill\hspace{2ex}"my 1D coordinate system")
+call CCTK\_VarIndex(my\_grid\_fn1, "myThorn::myGF1")
+call CCTK\_VarIndex(my\_grid\_fn2, "myThorn::myGF2")
+call CCTK\_VarIndex(my\_grid\_fn2, "myThorn::myGF3")\linebreak
+call CCTK\_InterpGV(ierr, cctkGH,\vfill
+\hspace{2ex} interp\_handle, coord\_system\_handle,\vfill
+\hspace{2ex} NUM\_POINTS, 3, 3,\vfill
+\hspace{2ex} coord,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL,\vfill
+\hspace{2ex} my\_grid\_fn1, my\_grid\_fn2, my\_grid\_fn3,\vfill
+\hspace{2ex} my\_out\_array1, my\_out\_array2, my\_out\_array3,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_COMPLEX, CCTK\_VARIABLE\_INT)
+}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative return code indicates an error condition:
+\end{tabular}
+\begin{tabular}{ll}
+-1 & Invalid interpolation operator handle passed\\
+-2 & Invalid coordinate system handle passed\\
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Interp.c
+\begin{CCTKFunc}{CCTK\_InterpHandle}{Return the handle for a given interpolation operator}
+\label{CCTK-InterpHandle}
+\subroutine{int}{integer}{handle}
+\argument{const char *}{character*(*)}{operator}
+\showargs
+\begin{params}
+\parameter{handle}{Handle for the interpolation operator}
+\parameter{operator}{Name of interpolation operator}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t handle = CCTK\_InterpHandle("my interpolation operator");}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_InterpHandle(handle,"my interpolation operator")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative value is returned for invalid/unregistered interpolation operator names.
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Interp.c
+\begin{CCTKFunc}{CCTK\_InterpLocal}%%%
+{Perform an interpolation on a list of processor-local arrays,
+using a chosen interpolation operator
+\\[\baselineskip]
+This function is being phased out; it will eventually be replaced by
+{\t CCTK\_InterpLocalUniform()} et al.}
+\label{CCTK-InterpLocal}
+\subroutine{int}{integer}{ierr}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{int}{integer}{operator\_handle}
+\argument{int}{integer}{num\_points}
+\argument{int}{integer}{num\_dims}
+\argument{int}{integer}{num\_in\_arrays}
+\argument{int}{integer}{num\_out\_arrays}
+\argument{...}{...}{}
+\argument{{\it num\_dims} * int}{{\it num\_dims} * integer}{dims}
+\argument{{\it num\_dims} * void *}{{\it num\_dims} * CCTK\_POINTER}{coord\_arrays}
+\argument{{\it num\_dims} * int}{{\it num\_dims} * integer}{coord\_array\_types}
+\argument{{\it num\_dims} * void *}{{\it num\_dims} * CCTK\_POINTER}{interp\_coord\_arrays}
+\argument{{\it num\_dims} * int}{{\it num\_dims} * integer}{interp\_coord\_array\_types}
+\argument{{\it num\_in\_arrays} * void *}{{\it num\_in\_arrays} * CCTK\_POINTER}{in\_arrays}
+\argument{{\it num\_in\_arrays} * int}{{\it num\_in\_arrays} * integer}{in\_array\_types}
+\argument{{\it num\_out\_arrays} * void *}{{\it num\_out\_arrays} * CCTK\_POINTER}{out\_arrays}
+\argument{{\it num\_out\_arrays} * int}{{\it num\_out\_arrays} * integer}{out\_array\_types}
+\showargs
+\begin{params}
+\parameter{cctkGH}{Pointer to the CCTK grid hierarchy}
+\parameter{operator\_handle}{Handle for the interpolation operator}
+\parameter{num\_points}{Number of points to be interpolated on this processor}
+\parameter{num\_dims}{Number of dimensions of the coordinate system}
+\parameter{num\_in\_arrays}{Number of passed input arrays}
+\parameter{num\_out\_arrays}{Number of passed output arrays}
+\parameter{...}{Variable argument list, with arguments as following}
+\parameter{dims}{Dimensions of the underlying coordinate system}
+\parameter{coord\_arrays}{List of coordinate arrays describing the coordinate system}
+\parameter{coord\_array\_types}{List of CCTK datatypes for coordinate arrays}
+\parameter{interp\_coord\_arrays}{List of interpolation coordinate arrays}
+\parameter{interp\_coord\_array\_types}{List of CCTK datatypes for interpolation coordinate arrays}
+\parameter{in\_arrays}{List of input arrays to interpolate}
+\parameter{in\_array\_types}{List of CCTK datatypes for input arrays}
+\parameter{out\_arrays}{List of output arrays}
+\parameter{out\_array\_types}{List of CCTK datatypes for output arrays}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t
+int interp\_handle;
+CCTK\_REAL coord\_x[XDIM], coord\_y[YDIM];
+CCTK\_REAL interp\_coord\_x[NUM\_POINTS], interp\_coord\_y[NUM\_POINTS];
+CCTK\_REAL my\_in\_array1[NUM\_POINTS];
+CCTK\_COMPLEX my\_in\_array2[NUM\_POINTS];
+CCTK\_REAL my\_out\_array1[NUM\_POINTS];
+CCTK\_COMPLEX my\_out\_array2[NUM\_POINTS];\linebreak
+interp\_handle =\vfill
+\hspace{2ex} CCTK\_InterpHandle("my interpolation operator");
+ierr = CCTK\_InterpLocal(cctkGH,\vfill
+\hspace{2ex} interp\_handle, NUM\_POINTS, 2, 2, 2,\vfill
+\hspace{2ex} XDIM, YDIM, coord\_x, coord\_y,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_REAL,\vfill
+\hspace{2ex} interp\_coord\_x, interp\_coord\_y,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_REAL,\vfill
+\hspace{2ex} my\_in\_array1, my\_in\_array2,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_COMPLEX);
+\hspace{2ex} my\_out\_array1, my\_out\_array2,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_COMPLEX);
+}
+\\
+\hfill {\bf Fortran} && {\t
+integer interp\_handle
+CCTK\_REAL coord(XDIM)
+CCTK\_REAL interp\_coord(NUM\_POINTS)
+CCTK\_REAL my\_in\_array1(NUM\_POINTS), my\_out\_array1(NUM\_POINTS)
+CCTK\_COMPLEX my\_in\_array2(NUM\_POINTS), my\_out\_array2(NUM\_POINTS)
+CCTK\_INT my\_in\_array3(NUM\_POINTS), my\_out\_array3(NUM\_POINTS)\linebreak
+call CCTK\_InterpHandle(interp\_handle,\vfill\hspace{2ex}"my interpolation operator")
+call CCTK\_InterpLocal(ierr, cctkGH,\vfill
+\hspace{2ex} interp\_handle, NUM\_POINTS, 1, 3, 3,\vfill
+\hspace{2ex} XDIM, coord,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL,\vfill
+\hspace{2ex} interp\_coord,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL,\vfill
+\hspace{2ex} my\_in\_array1, my\_in\_array2, my\_in\_array3,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_COMPLEX,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_INT,\vfill
+\hspace{2ex} my\_out\_array1, my\_out\_array2, my\_out\_array3,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_REAL, CCTK\_VARIABLE\_COMPLEX,\vfill
+\hspace{2ex} CCTK\_VARIABLE\_INT)
+}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative return code indicates an error condition:
+\end{tabular}
+\begin{tabular}{ll}
+-1 & Invalid interpolation operator handle passed\\
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%notyet % Interp.c
+%notyet \begin{FunctionDescription}{CCTK\_InterpLocalNonUniform}
+%notyet \label{CCTK-InterpLocalNonUniform}
+%notyet Interpolate a list of processor-local arrays
+%notyet which define a nonuniformly spaced data grid (not implemented yet)
+%notyet
+%notyet (\verb|CCTK_InterpLocalNonUniform()|, \verb|CCTK_InterpLocalUniform()|,
+%notyet and \verb|CCTK_InterpLocalWarped()| will eventually replace
+%notyet \verb|CCTK_InterpLocal()|.)
+%notyet
+%notyet The computation is optimized for the case of interpolating a
+%notyet number of arrays at a time; in this case the same interpolation
+%notyet coefficients can be used for all the arrays.
+%notyet
+%notyet \begin{SynopsisSection}
+%notyet \begin{Synopsis}{C}
+%notyet \begin{verbatim}
+%notyet #include "util_ErrorCodes.h"
+%notyet #include "cctk.h"
+%notyet int status
+%notyet = CCTK_InterpLocalNonUniform(int N_dims,
+%notyet int operator_handle,
+%notyet int param_table_handle,
+%notyet int coord_arrays_type_code,
+%notyet const CCTK_INT coord_array_dims[],
+%notyet const void *const coord_arrays[],
+%notyet int N_interp_points,
+%notyet int interp_coords_type_code,
+%notyet const void *const interp_coords[],
+%notyet int N_input_arrays,
+%notyet const CCTK_INT input_array_dims[],
+%notyet const CCTK_INT input_array_type_codes[],
+%notyet const void *const input_arrays[],
+%notyet int N_output_arrays,
+%notyet const CCTK_INT output_array_type_codes[],
+%notyet void *const output_arrays[]);
+%notyet \end{verbatim}
+%notyet \end{Synopsis}
+%notyet \end{SynopsisSection}
+%notyet
+%notyet \begin{ResultSection}
+%notyet \begin{Result}{\rm 0}
+%notyet success
+%notyet \end{Result}
+%notyet \end{ResultSection}
+%notyet
+%notyet \begin{ParameterSection}
+%notyet \begin{Parameter}{N\_dims ($\ge 1$)}
+%notyet Number of dimensions in which to interpolate.
+%notyet Note that this may be less than the number of dimensions of the
+%notyet input arrays if the storage is set up appropriately. For example,
+%notyet we might want to interpolate along 1-D lines or in 2-D planes of a
+%notyet 3-D input array; here \verb|N_dims| would be 1 or 2 respectively.
+%notyet For details, see the section on ``Non-Contiguous Input Arrays''
+%notyet in the Thorn Guide for thorn AEILocalInterp.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{operator\_handle ($\ge 0$)}
+%notyet \hbox{}
+%notyet Handle to the interpolation operator as returned by
+%notyet \verb|CCTK_InterpHandle()|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{param\_table\_handle ($\ge 0$)}
+%notyet
+%notyet Handle to a key-value table containing additional parameters for
+%notyet the interpolator.
+%notyet
+%notyet One common parameter-table option, which a number of interpolation
+%notyet operators are likely to support, is \verb|order|, a \verb|CCTK_INT|
+%notyet specifying the order of the (presumably polynomial) interpolation
+%notyet (1=linear, 2=quadratic, 3=cubic, etc).
+%notyet
+%notyet See the Thorn Guide for the AEILocalInterp thorn for other parameters.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{coord\_arrays\_type\_code}
+%notyet \hbox{}
+%notyet One of the \verb|CCTK_VARIABLE_|* type codes, giving the data type of the
+%notyet 1-D coordinate arrays pointed to by \verb|coord_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{coord\_array\_dims ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| integers giving the dimensions
+%notyet of the corresponding 1-D coordinate arrays.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{coord\_arrays ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| pointers to 1-D arrays giving the
+%notyet coordinates of the interpolation points. See the ``Discussion'' section
+%notyet below for more on the semantics of this.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{N\_interp\_points ($\ge 0$)}
+%notyet \hbox{}
+%notyet The number of points at which interpolation is to be done.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{interp\_coords\_type\_code}
+%notyet \hbox{}
+%notyet One of the \verb|CCTK_VARIABLE_|* type codes, giving the data type
+%notyet of the 1-D interpolation-point-coordinate arrays pointed to by
+%notyet \verb|interp_coords[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{interp\_coords ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| pointers to 1-D arrays giving the
+%notyet coordinates of the interpolation points. These coordinates are with
+%notyet respect to the coordinate system defined by \verb|coord_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{N\_input\_arrays ($\ge 0$)}
+%notyet \hbox{}
+%notyet The number of input arrays to be interpolated.
+%notyet Note that if the parameter table entry \verb|operand_indices|
+%notyet is used to specify a 1-to-many mapping of input arrays to output arrays,
+%notyet only the unique set of input arrays should be given here.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{input\_array\_dims ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| integers giving the dimensions
+%notyet of the \verb|N_dims|-D input arrays. By default all the input arrays
+%notyet are taken to have these dimensions, with \verb|[0]| the most contiguous
+%notyet axis and \verb|[N_dims-1]| the least contiguous axis, and array subscripts
+%notyet in the range \verb|0 <= subscript < input_array_dims[axis]|. See the
+%notyet discussion of the \verb|input_array_strides| optional parameter (passed
+%notyet in the parameter table) for details of how this can be overridden.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{input\_array\_type\_codes ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_input_arrays| \verb|CCTK_VARIABLE_|*
+%notyet type codes giving the data types of the \verb|N_dims|-D input arrays
+%notyet pointed to by \verb|input_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{input\_arrays ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_input_arrays| pointers to the
+%notyet \verb|N_dims|-D input arrays for the interpolation.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{N\_output\_arrays ($\ge 0$)}
+%notyet \hbox{}
+%notyet The number of output arrays to be returned from the interpolation.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{output\_array\_type\_codes ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_output_arrays| \verb|CCTK_VARIABLE_|*
+%notyet type codes giving the data types of the 1-D output arrays pointed to by
+%notyet \verb|output_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{output\_arrays ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_output_arrays| pointers to the
+%notyet (user-supplied) 1-D output arrays for the interpolation.
+%notyet \end{Parameter}
+%notyet \end{ParameterSection}
+%notyet
+%notyet \begin{Discussion}
+%notyet \verb|CCTK_InterpLocalNonUniform()| is a generic API for interpolating
+%notyet processor-local arrays when the data points' coordinates~$xyz$ are
+%notyet {\em nonlinear\/} (but still single-variable) functions of the integer
+%notyet array subscripts~\verb|ijk| (we're describing this for 3-D, but the
+%notyet generalization to other numbers of dimensions should be obvious),
+%notyet \begin{flushleft}
+%notyet $x = x(\verb|i|)$ \\
+%notyet $y = y(\verb|j|)$ \\
+%notyet $z = z(\verb|k|)$ %%%\\
+%notyet \end{flushleft}
+%notyet These nonlinear functions are specified by setting up 1-D arrays
+%notyet giving their (the coordinates) values at the grid points, then passing
+%notyet pointers to these 1-D arrays in the \verb|coord_arrays[]| argument:
+%notyet \begin{flushleft}
+%notyet $x = \verb|coord_arrays[0][i]|$ \\
+%notyet $y = \verb|coord_arrays[1][j]|$ \\
+%notyet $z = \verb|coord_arrays[2][k]|$ \\
+%notyet \end{flushleft}
+%notyet
+%notyet [If these nonlinear functions are known analytically, then it's
+%notyet probably more efficient to analytically transform to coordinates
+%notyet which are linear functions of the subscripts, then use
+%notyet \verb|CCTK_InterpLocalUniform()|.]
+%notyet
+%notyet The $(x,y,z)$ coordinates are used for the interpolation
+%notyet (\ie{}~the interpolator may internally use polynomials in these
+%notyet coordinates); \verb|interp_coords[]| specifies coordinates in this
+%notyet same coordinate system.
+%notyet
+%notyet Details of the operation performed, and what (if any) inputs and/or
+%notyet outputs are specified in the parameter table, depend on which interpolation
+%notyet operator you use. See the Thorn Guide for the AEILocalInterp thorn for
+%notyet further discussion.
+%notyet \end{Discussion}
+%notyet
+%notyet \begin{SeeAlsoSection}
+%notyet \begin{SeeAlso}{CCTK\_InterpHandle()}
+%notyet Get the interpolator handle for a given character-string name.
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpGV()}
+%notyet Interpolate a list of Cactus grid arrays.
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpLocal()}
+%notyet Older API to interpolate a list of processor-local arrays.
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpLocalUniform()}
+%notyet Interpolate a list of processor-local arrays,
+%notyet with uniformly spaced data points
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpRegisterOpLocalNonUniform()}
+%notyet \hbox{}
+%notyet Register a \verb|CCTK_InterpLocalNonUniform()| interpolation operator.
+%notyet \end{SeeAlso}
+%notyet \end{SeeAlsoSection}
+%notyet
+%notyet \begin{ErrorSection}
+%notyet \begin{Error}{}
+%notyet To find the numerical
+%notyet values of the error codes (or more commonly, to find which error code
+%notyet corresponds to a given numerical value), look in the files
+%notyet \verb|cctk_Interp.h|, \verb|util_ErrorCodes.h|, and/or \verb|util_Table.h|
+in the \verb|src/include/| directory in the Cactus flesh.
+%notyet \end{Error}
+%notyet \begin{Error}{CCTK\_ERROR\_INTERP\_POINT\_OUTSIDE}
+%notyet one or more of the interpolation points is out of range
+%notyet (in this case additional information about the out-of-range point
+%notyet may be reported through the parameter table; see the Thorn Guide for
+%notyet the AEILocalInterp thorn for further details)
+%notyet \end{Error}
+%notyet \begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+%notyet one or more of the inputs is invalid (eg.~\verb|NULL| pointer)
+%notyet \end{Error}
+%notyet \begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+%notyet unable to allocate memory
+%notyet \end{Error}
+%notyet \begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+%notyet parameter table handle is invalid
+%notyet \end{Error}
+%notyet \begin{Error}{other error codes}
+%notyet this function may also return any error codes returned by the
+%notyet \verb|Util_Table*()| routines used to get parameters from
+%notyet (and/or set results in) the parameter table
+%notyet \end{Error}
+%notyet \end{ErrorSection}
+%notyet
+%notyet \begin{ExampleSection}
+%notyet \begin{Example}{C}
+%notyet Here's a simple example of interpolating a \verb|CCTK_REAL| and a
+%notyet \verb|CCTK_COMPLEX| $10 \times 20$ 2-D array, at 5 interpolation points,
+%notyet using cubic interpolation.
+%notyet
+%notyet \begin{verbatim}
+%notyet #define N_DIMS 2
+%notyet #define N_INTERP_POINTS 5
+%notyet #define N_INPUT_ARRAYS 2
+%notyet #define N_OUTPUT_ARRAYS 2
+%notyet
+%notyet /* (x,y) coordinates of data grid points */
+%notyet #define NX 10
+%notyet #define NY 20
+%notyet const CCTK_REAL x_coords[NX];
+%notyet const CCTK_REAL y_coords[NY];
+%notyet const void *const coord_arrays[N_DIMS]
+%notyet = { (const void *) x_coords, (const void *) y_coords };
+%notyet
+%notyet /* (x,y) coordinates of interpolation points */
+%notyet const CCTK_REAL interp_x[N_INTERP_POINTS];
+%notyet const CCTK_REAL interp_y[N_INTERP_POINTS];
+%notyet const void *const interp_coords[N_DIMS]
+%notyet = { (const void *) interp_x, (const void *) interp_y };
+%notyet
+%notyet /* input arrays */
+%notyet /* ... note Cactus uses Fortran storage ordering, i.e.\ X is contiguous */
+%notyet const CCTK_REAL input_real [NY][NX];
+%notyet const CCTK_COMPLEX input_complex[NY][NX];
+%notyet const CCTK_INT input_array_dims[N_DIMS] = { NX, NY };
+%notyet const CCTK_INT input_array_type_codes[N_INPUT_ARRAYS]
+%notyet = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_COMPLEX };
+%notyet const void *const input_arrays[N_INPUT_ARRAYS]
+%notyet = { (const void *) input_real, (const void *) input_complex };
+%notyet
+%notyet /* output arrays */
+%notyet CCTK_REAL output_real [N_INTERP_POINTS];
+%notyet CCTK_COMPLEX output_complex[N_INTERP_POINTS];
+%notyet const CCTK_INT output_array_type_codes[N_OUTPUT_ARRAYS]
+%notyet = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_COMPLEX };
+%notyet void *const output_arrays[N_OUTPUT_ARRAYS]
+%notyet = { (void *) output_real, (void *) output_complex };
+%notyet
+%notyet int operator_handle, param_table_handle;
+%notyet operator_handle = CCTK_InterpHandle("my interpolation operator");
+%notyet if (operator_handle < 0)
+%notyet CCTK_WARN(-1, "can't get interpolation handle!");
+%notyet param_table_handle = Util_TableCreateFromString("order=3");
+%notyet if (param_table_handle < 0)
+%notyet CCTK_WARN(-1, "can't create parameter table!");
+%notyet if (CCTK_InterpLocalNonUniform(N_DIMS,
+%notyet operator_handle, param_table_handle,
+%notyet CCTK_VARIABLE_REAL, coord_arrays,
+%notyet N_INTERP_POINTS,
+%notyet CCTK_VARIABLE_REAL,
+%notyet interp_coords,
+%notyet N_INPUT_ARRAYS,
+%notyet input_array_dims,
+%notyet input_array_type_codes,
+%notyet input_arrays,
+%notyet N_OUTPUT_ARRAYS,
+%notyet output_array_type_codes,
+%notyet output_arrays) < 0)
+%notyet CCTK_WARN(-1, "error return from interpolator!");
+%notyet \end{verbatim}
+%notyet \end{Example}
+%notyet \end{ExampleSection}
+%notyet \end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Interp.c
+\begin{FunctionDescription}{CCTK\_InterpLocalUniform}
+\label{CCTK-InterpLocalUniform}
+Interpolate a list of processor-local arrays
+which define a uniformly-spaced data grid
+
+(\verb|CCTK_InterpLocalNonUniform()|, \verb|CCTK_InterpLocalUniform()|,
+and \verb|CCTK_InterpLocalWarped()| will eventually replace
+\verb|CCTK_InterpLocal()|.)
+
+The computation is optimized for the case of interpolating a
+number of arrays at a time; in this case the same interpolation
+coefficients can be used for all the arrays.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "cctk.h"
+int status
+ = CCTK_InterpLocalUniform(int N_dims,
+ int operator_handle,
+ int param_table_handle,
+ const CCTK_REAL coord_origin[],
+ const CCTK_REAL coord_delta[],
+ int N_interp_points,
+ int interp_coords_type_code,
+ const void *const interp_coords[],
+ int N_input_arrays,
+ const CCTK_INT input_array_dims[],
+ const CCTK_INT input_array_type_codes[],
+ const void *const input_arrays[],
+ int N_output_arrays,
+ const CCTK_INT output_array_type_codes[],
+ void *const output_arrays[]);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0}
+success
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{N\_dims ($\ge 1$)}
+Number of dimensions in which to interpolate.
+Note that this may be less than the number of dimensions of the
+input arrays if the storage is set up appropriately. For example,
+we might want to interpolate along 1-D lines or in 2-D planes of a
+3-D input array; here \verb|N_dims| would be 1 or 2 respectively.
+For details, see the section on ``Non-Contiguous Input Arrays''
+in the Thorn Guide for thorn AEILocalInterp.
+\end{Parameter}
+\begin{Parameter}{operator\_handle ($\ge 0$)}
+\hbox{}
+Handle to the interpolation operator as returned by
+\verb|CCTK_InterpHandle()|.
+\end{Parameter}
+\begin{Parameter}{param\_table\_handle ($\ge 0$)}
+Handle to a key-value table containing additional parameters for
+the interpolator.
+
+One common parameter-table option, which a number of interpolation
+operators are likely to support, is \verb|order|, a \verb|CCTK_INT|
+specifying the order of the (presumably polynomial) interpolation
+(1=linear, 2=quadratic, 3=cubic, etc).
+
+See the Thorn Guide for the AEILocalInterp thorn for other parameters.
+\end{Parameter}
+\begin{Parameter}{coord\_origin ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array giving the coordinates of the data point with
+integer array subscripts 0, 0, \dots, 0, or more generally (if the actual
+array bounds don't include the all-zeros-subscript point) the coordinates
+which this data point would have if it existed. See the ``Discussion''
+section below for more on how \verb|coord_origin[]| is actually used.
+\end{Parameter}
+\begin{Parameter}{coord\_delta ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array giving the coordinate spacing of the data arrays.
+See the ``Discussion'' section below for more on how \verb|coord_delta[]|
+is actually used.
+\end{Parameter}
+\begin{Parameter}{N\_interp\_points ($\ge 0$)}
+\hbox{}
+The number of points at which interpolation is to be done.
+\end{Parameter}
+\begin{Parameter}{interp\_coords\_type\_code}
+\hbox{}
+One of the \verb|CCTK_VARIABLE_|* type codes, giving the data type
+of the 1-D interpolation-point-coordinate arrays pointed to by
+\verb|interp_coords[]|.
+\end{Parameter}
+\begin{Parameter}{interp\_coords ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array of \verb|N_dims| pointers to 1-D arrays giving the
+coordinates of the interpolation points. These coordinates are with
+respect to the coordinate system defined by \verb|coord_origin[]| and
+\verb|coord_delta[]|.
+\end{Parameter}
+\begin{Parameter}{N\_input\_arrays ($\ge 0$)}
+\hbox{}
+The number of input arrays to be interpolated.
+Note that if the parameter table entry \verb|operand_indices|
+is used to specify a 1-to-many mapping of input arrays to output arrays,
+only the unique set of input arrays should be given here.
+\end{Parameter}
+\begin{Parameter}{input\_array\_dims ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array of \verb|N_dims| integers giving the dimensions
+of the \verb|N_dims|-D input arrays. By default all the input arrays
+are taken to have these dimensions, with \verb|[0]| the most contiguous
+axis and \verb|[N_dims-1]| the least contiguous axis, and array subscripts
+in the range \verb|0 <= subscript < input_array_dims[axis]|. See the
+discussion of the \verb|input_array_strides| optional parameter (passed
+in the parameter table) for details of how this can be overridden.
+\end{Parameter}
+\begin{Parameter}{input\_array\_type\_codes ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array of \verb|N_input_arrays| \verb|CCTK_VARIABLE_|*
+type codes giving the data types of the \verb|N_dims|-D input arrays
+pointed to by \verb|input_arrays[]|.
+\end{Parameter}
+\begin{Parameter}{input\_arrays ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array of \verb|N_input_arrays| pointers to the
+\verb|N_dims|-D input arrays for the interpolation. If any
+\verb|input_arrays[in]| pointer is NULL, that interpolation is skipped.
+\end{Parameter}
+\begin{Parameter}{N\_output\_arrays ($\ge 0$)}
+\hbox{}
+The number of output arrays to be returned from the interpolation.
+\end{Parameter}
+\begin{Parameter}{output\_array\_type\_codes ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array of \verb|N_output_arrays| \verb|CCTK_VARIABLE_|*
+type codes giving the data types of the 1-D output arrays pointed to by
+\verb|output_arrays[]|.
+\end{Parameter}
+\begin{Parameter}{output\_arrays ($\ne$ NULL)}
+\hbox{}
+(Pointer to) an array of \verb|N_output_arrays| pointers to the
+(user-supplied) 1-D output arrays for the interpolation. If any
+\verb|output_arrays[out]| pointer is NULL, that interpolation is skipped.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+\verb|CCTK_InterpLocalUniform()| is a generic API for interpolating
+processor-local arrays when the data points'~$xyz$ coordinates are
+{\em linear\/} functions of the integer array subscripts~\verb|ijk|
+(we're describing this for 3-D, but the generalization to other numbers
+of dimensions should be obvious). The \verb|coord_origin[]| and
+\verb|coord_delta[]| arguments specify these linear functions:
+\begin{flushleft}
+$x = \verb|coord_origin[0] + i*coord_delta[0]|$ \\
+$y = \verb|coord_origin[1] + j*coord_delta[1]|$ \\
+$z = \verb|coord_origin[2] + k*coord_delta[2]|$ %%%\\
+\end{flushleft}
+The $(x,y,z)$ coordinates are used for the interpolation
+(\ie{}~the interpolator may internally use polynomials in these
+coordinates); \verb|interp_coords[]| specifies coordinates in this
+same coordinate system.
+
+Details of the operation performed, and what (if any) inputs and/or
+outputs are specified in the parameter table, depend on which interpolation
+operator you use. See the Thorn Guide for the AEILocalInterp thorn for
+further discussion.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_InterpHandle()}
+Get the interpolator handle for a given character-string name.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpGridArrays()}
+Interpolate a list of Cactus grid arrays
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpGV()}
+Older API to Interpolate a list of Cactus grid arrays
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpLocal()}
+Older API to interpolate a list of processor-local arrays
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpRegisterOpLocalUniform()}
+\hbox{}
+Register a \verb|CCTK_InterpLocalUniform()| interpolation operator
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpLocalNonUniform()}
+Interpolate a list of processor-local arrays,
+with non-uniformly spaced data points.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{}
+To find the numerical
+values of the error codes (or more commonly, to find which error code
+corresponds to a given numerical value), look in the files
+\verb|cctk_Interp.h|, \verb|util_ErrorCodes.h|, and/or \verb|util_Table.h|
+in the \verb|src/include/| directory in the Cactus flesh.
+\end{Error}
+\begin{Error}{CCTK\_ERROR\_INTERP\_POINT\_OUTSIDE}
+one or more of the interpolation points is out of range
+(in this case additional information about the out-of-range point
+may be reported through the parameter table; see the Thorn Guide for
+the AEILocalInterp thorn for further details)
+\end{Error}
+\begin{Error}{CCTK\_ERROR\_INTERP\_GRID\_TOO\_SMALL}
+one or more of the dimensions of the input arrays is/are smaller than
+the molecule size chosen by the interpolator (based on the parameter-table
+options, e.g.\ the interpolation order)
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+one or more of the inputs is invalid (eg.~\verb|NULL| pointer)
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+parameter table handle is invalid
+\end{Error}
+\begin{Error}{other error codes}
+this function may also return any error codes returned by the
+\verb|Util_Table*()| routines used to get parameters from
+(and/or set results in) the parameter table
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+Here's a simple example of interpolating a \verb|CCTK_REAL| and a
+\verb|CCTK_COMPLEX| $10 \times 20$ 2-D array, at 5 interpolation points,
+using cubic interpolation.
+
+Note that since C allows arrays to be initialized only if the
+initializer values are compile-time constants, we have to declare the
+\verb|interp_coords[]|, \verb|input_arrays[]|, and \verb|output_arrays[]|
+arrays as non-\verb|const|, and set their values with ordinary (run-time)
+assignment statements. In \Cplusplus, there's no restriction on
+initializer values, so we could declare the arrays \verb|const| and
+initialize them as part of their declarations.
+
+\begin{verbatim}
+#define N_DIMS 2
+#define N_INTERP_POINTS 5
+#define N_INPUT_ARRAYS 2
+#define N_OUTPUT_ARRAYS 2
+
+/* (x,y) coordinates of data grid points */
+#define X_ORIGIN ...
+#define X_DELTA ...
+#define Y_ORIGIN ...
+#define Y_DELTA ...
+const CCTK_REAL origin[N_DIMS] = { X_ORIGIN, Y_ORIGIN };
+const CCTK_REAL delta [N_DIMS] = { X_DELTA, Y_DELTA };
+
+/* (x,y) coordinates of interpolation points */
+const CCTK_REAL interp_x[N_INTERP_POINTS];
+const CCTK_REAL interp_y[N_INTERP_POINTS];
+const void *interp_coords[N_DIMS]; /* see note above */
+
+/* input arrays */
+/* ... note Cactus uses Fortran storage ordering, i.e.\ X is contiguous */
+#define NX 10
+#define NY 20
+const CCTK_REAL input_real [NY][NX];
+const CCTK_COMPLEX input_complex[NY][NX];
+const CCTK_INT input_array_dims[N_DIMS] = { NX, NY };
+const CCTK_INT input_array_type_codes[N_INPUT_ARRAYS]
+ = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_COMPLEX };
+const void *input_arrays[N_INPUT_ARRAYS]; /* see note above */
+
+/* output arrays */
+CCTK_REAL output_real [N_INTERP_POINTS];
+CCTK_COMPLEX output_complex[N_INTERP_POINTS];
+const CCTK_INT output_array_type_codes[N_OUTPUT_ARRAYS]
+ = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_COMPLEX };
+void *const output_arrays[N_OUTPUT_ARRAYS]; /* see note above */
+
+int operator_handle, param_table_handle;
+operator_handle = CCTK_InterpHandle("my interpolation operator");
+if (operator_handle < 0)
+ CCTK_WARN(-1, "can't get interpolation handle!");
+param_table_handle = Util_TableCreateFromString("order=3");
+if (param_table_handle < 0)
+ CCTK_WARN(-1, "can't create parameter table!");
+
+/* initialize the rest of the parameter arrays */
+interp_coords[0] = (const void *) interp_x;
+interp_coords[1] = (const void *) interp_y;
+input_arrays[0] = (const void *) input_real;
+input_arrays[1] = (const void *) input_complex;
+output_arrays[0] = (void *) output_real;
+output_arrays[1] = (void *) output_complex;
+
+/* do the actual interpolation, and check for error returns */
+if (CCTK_InterpLocalUniform(N_DIMS,
+ operator_handle, param_table_handle,
+ origin, delta,
+ N_INTERP_POINTS,
+ CCTK_VARIABLE_REAL,
+ interp_coords,
+ N_INPUT_ARRAYS,
+ input_array_dims,
+ input_array_type_codes,
+ input_arrays,
+ N_OUTPUT_ARRAYS,
+ output_array_type_codes,
+ output_arrays) < 0)
+ CCTK_WARN(-1, "error return from interpolator!");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%notyet % Interp.c
+%notyet \begin{FunctionDescription}{CCTK\_InterpLocalWarped}
+%notyet \label{CCTK-InterpLocalWarped}
+%notyet Interpolate a list of processor-local arrays
+%notyet which define a curvilinearly-warped data grid
+%notyet
+%notyet (\verb|CCTK_InterpLocalWarped()|, \verb|CCTK_InterpLocalUniform()|,
+%notyet and \verb|CCTK_InterpLocalWarped()| will eventually replace
+%notyet \verb|CCTK_InterpLocal()|.)
+%notyet
+%notyet The computation is optimized for the case of interpolating a
+%notyet number of arrays at a time; in this case the same interpolation
+%notyet coefficients can be used for all the arrays.
+%notyet
+%notyet \begin{SynopsisSection}
+%notyet \begin{Synopsis}{C}
+%notyet \begin{verbatim}
+%notyet #include "util_ErrorCodes.h"
+%notyet #include "cctk.h"
+%notyet int status = CCTK_InterpLocalWarped(int N_dims,
+%notyet int operator_handle,
+%notyet int param_table_handle,
+%notyet int coord_arrays_type_code,
+%notyet const CCTK_INT coord_array_dims[],
+%notyet const void *const coord_arrays[],
+%notyet int N_interp_points,
+%notyet int interp_coords_type_code,
+%notyet const void *const interp_coords[],
+%notyet int N_input_arrays,
+%notyet const CCTK_INT input_array_dims[],
+%notyet const CCTK_INT input_array_type_codes[],
+%notyet const void *const input_arrays[],
+%notyet int N_output_arrays,
+%notyet const CCTK_INT output_array_type_codes[],
+%notyet void *const output_arrays[]);
+%notyet \end{verbatim}
+%notyet \end{Synopsis}
+%notyet \end{SynopsisSection}
+%notyet
+%notyet \begin{ResultSection}
+%notyet \begin{Result}{\rm 0}
+%notyet success
+%notyet \end{Result}
+%notyet \end{ResultSection}
+%notyet
+%notyet \begin{ParameterSection}
+%notyet \begin{Parameter}{N\_dims ($\ge 1$)}
+%notyet Number of dimensions in which to interpolate.
+%notyet Note that this may be less than the number of dimensions of the
+%notyet input arrays if the storage is set up appropriately. For example,
+%notyet we might want to interpolate along 1-D lines or in 2-D planes of a
+%notyet 3-D input array; here \verb|N_dims| would be 1 or 2 respectively.
+%notyet For details, see the section on ``Non-Contiguous Input Arrays''
+%notyet in the Thorn Guide for thorn AEILocalInterp.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{operator\_handle ($\ge 0$)}
+%notyet \hbox{}
+%notyet Handle to the interpolation operator as returned by
+%notyet \verb|CCTK_InterpHandle()|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{param\_table\_handle ($\ge 0$)}
+%notyet
+%notyet Handle to a key-value table containing additional parameters for
+%notyet the interpolator.
+%notyet
+%notyet One common parameter-table option, which a number of interpolation
+%notyet operators are likely to support, is \verb|order|, a \verb|CCTK_INT|
+%notyet specifying the order of the (presumably polynomial) interpolation
+%notyet (1=linear, 2=quadratic, 3=cubic, etc).
+%notyet
+%notyet See the Thorn Guide for the AEILocalInterp thorn for other parameters.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{coord\_arrays\_type\_code}
+%notyet \hbox{}
+%notyet One of the \verb|CCTK_VARIABLE_|* type codes, giving the data type of the
+%notyet \verb|N_dims|-D coordinate arrays pointed to by \verb|coord_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{coord\_array\_dims ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| integers giving the dimensions
+%notyet of the coordinate arrays. All the coordinate arrays are taken to have
+%notyet these dimensions, with (by default) \verb|[0]| the most contiguous axis
+%notyet and \verb|[N_dims-1]| the least contiguous axis, and array subscripts
+%notyet in the range \verb|0 <= subscript < coord_array_dims[axis]|. See the
+%notyet discussion of the \verb|coord_array_strides| optional parameter (passed
+%notyet in the parameter table) for details of how this can be overridden.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{coord\_arrays ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| pointers to \verb|N_dims|-D arrays
+%notyet giving the coordinates of the interpolation points. See the ``Discussion''
+%notyet section below for more on the semantics of this.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{N\_interp\_points ($\ge 0$)}
+%notyet \hbox{}
+%notyet The number of points at which interpolation is to be done.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{interp\_coords\_type\_code}
+%notyet \hbox{}
+%notyet One of the \verb|CCTK_VARIABLE_|* type codes, giving the data type
+%notyet of the 1-D interpolation-point-coordinate arrays pointed to by
+%notyet \verb|interp_coords[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{interp\_coords ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| pointers to \verb|N_dims|-D arrays
+%notyet giving the coordinates of the interpolation points. These coordinates are
+%notyet with respect to the coordinate system defined by \verb|coord_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{N\_input\_arrays ($\ge 0$)}
+%notyet \hbox{}
+%notyet The number of input arrays to be interpolated.
+%notyet Note that if the parameter table entry \verb|operand_indices|
+%notyet is used to specify a 1-to-many mapping of input arrays to output arrays,
+%notyet only the unique set of input arrays should be given here.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{input\_array\_dims ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_dims| integers giving the dimensions
+%notyet of the input arrays. By default all the input arrays are taken to have
+%notyet these dimensions, with \verb|[0]| the most contiguous axis and
+%notyet \verb|[N_dims-1]| the least contiguous axis, and array subscripts in the
+%notyet range \verb|0 <= subscript < input_array_dims[axis]|. See the discussion
+%notyet of the \verb|input_array_strides| optional parameter (passed in the
+%notyet parameter table) for details of how this can be overridden.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{input\_array\_type\_codes ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_input_arrays| \verb|CCTK_VARIABLE_|*
+%notyet type codes giving the data types of the \verb|N_dims|-D input arrays
+%notyet pointed to by \verb|input_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{input\_arrays ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_input_arrays| pointers to the
+%notyet \verb|N_dims|-D input arrays for the interpolation.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{N\_output\_arrays ($\ge 0$)}
+%notyet \hbox{}
+%notyet The number of output arrays to be returned from the interpolation.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{output\_array\_type\_codes ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_output_arrays| \verb|CCTK_VARIABLE_|*
+%notyet type codes giving the data types of the 1-D output arrays pointed to by
+%notyet \verb|output_arrays[]|.
+%notyet \end{Parameter}
+%notyet \begin{Parameter}{output\_arrays ($\ne$ NULL)}
+%notyet \hbox{}
+%notyet (Pointer to) an array of \verb|N_output_arrays| pointers to the
+%notyet (user-supplied) 1-D output arrays for the interpolation.
+%notyet \end{Parameter}
+%notyet \end{ParameterSection}
+%notyet
+%notyet \begin{Discussion}
+%notyet This function is a generic API for interpolating processor-local arrays
+%notyet when the data points' coordinates~$xyz$ are generic {\em multivariable
+%notyet nonlinear\/} functions of the integer array subscripts~\verb|ijk|
+%notyet (we're describing this for 3-D, but the generalization to other
+%notyet numbers of dimensions should be obvious),
+%notyet \begin{flushleft}
+%notyet $x = x(\verb|i|, \verb|j|, \verb|k|)$ \\
+%notyet $y = y(\verb|i|, \verb|j|, \verb|k|)$ \\
+%notyet $z = z(\verb|i|, \verb|j|, \verb|k|)$ %%%\\
+%notyet \end{flushleft}
+%notyet These nonlinear functions are specified by setting up 3-D arrays
+%notyet giving their (the coordinates) values at the grid points, then passing
+%notyet pointers to these 3-D arrays in the \verb|coord_arrays| argument:
+%notyet \begin{flushleft}
+%notyet $x = \verb|coord_arrays[0][i,j,k]|$ \\
+%notyet $y = \verb|coord_arrays[1][i,j,k]|$ \\
+%notyet $z = \verb|coord_arrays[2][i,j,k]|$ \\
+%notyet \end{flushleft}
+%notyet where \verb|[i,j,k]| refers to \verb|N_dims|-D array subscripting.
+%notyet
+%notyet [If these nonlinear functions are known analytically, then it's
+%notyet probably more efficient to analytically transform to coordinates
+%notyet which are linear functions of the subscripts, then use
+%notyet \verb|CCTK_InterpLocalUniform()|.]
+%notyet
+%notyet The $(x,y,z)$ coordinates are used for the interpolation
+%notyet (\ie{}~the interpolator may internally use polynomials in these
+%notyet coordinates); \verb|interp_coords| specifies coordinates in this
+%notyet same coordinate system.
+%notyet
+%notyet Details of the operation performed, and what (if any) inputs and/or
+%notyet outputs are specified in the parameter table, depend on which interpolation
+%notyet operator you use. See the Thorn Guide for the AEILocalInterp thorn for
+%notyet further discussion.
+%notyet \end{Discussion}
+%notyet
+%notyet \begin{SeeAlsoSection}
+%notyet \begin{SeeAlso}{CCTK\_InterpHandle()}
+%notyet Get the interpolator handle for a given character-string name.
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpGV()}
+%notyet Interpolate a list of Cactus grid arrays.
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpLocal()}
+%notyet Older API to interpolate a list of processor-local arrays.
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpLocalUniform()}
+%notyet Interpolate a list of processor-local arrays,
+%notyet with uniformly spaced data points
+%notyet \end{SeeAlso}
+%notyet \begin{SeeAlso}{CCTK\_InterpRegisterOpLocalWarped()}
+%notyet \hbox{}
+%notyet Register a \verb|CCTK_InterpLocalWarped()| interpolation operator.
+%notyet \end{SeeAlso}
+%notyet \end{SeeAlsoSection}
+%notyet
+%notyet \begin{ErrorSection}
+%notyet \begin{Error}{}
+%notyet To find the numerical
+%notyet values of the error codes (or more commonly, to find which error code
+%notyet corresponds to a given numerical value), look in the files
+%notyet \verb|cctk_Interp.h|, \verb|util_ErrorCodes.h|, and/or \verb|util_Table.h|
+in the \verb|src/include/| directory in the Cactus flesh.
+%notyet \end{Error}
+%notyet \begin{Error}{CCTK\_ERROR\_INTERP\_POINT\_OUTSIDE}
+%notyet one or more of the interpolation points is out of range
+%notyet (in this case additional information about the out-of-range point
+%notyet may be reported through the parameter table; see the Thorn Guide for
+%notyet the AEILocalInterp thorn for further details)
+%notyet \end{Error}
+%notyet \begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+%notyet one or more of the inputs is invalid (eg.~\verb|NULL| pointer)
+%notyet \end{Error}
+%notyet \begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+%notyet unable to allocate memory
+%notyet \end{Error}
+%notyet \begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+%notyet parameter table handle is invalid
+%notyet \end{Error}
+%notyet \begin{Error}{other error codes}
+%notyet this function may also return any error codes returned by the
+%notyet \verb|Util_Table*()| routines used to get parameters from
+%notyet (and/or set results in) the parameter table
+%notyet \end{Error}
+%notyet \end{ErrorSection}
+%notyet
+%notyet \begin{ExampleSection}
+%notyet \begin{Example}{C}
+%notyet Here's a simple example of interpolating a \verb|CCTK_REAL| and a
+%notyet \verb|CCTK_COMPLEX| $10 \times 20$ 2-D array, at 5 interpolation points,
+%notyet using cubic interpolation.
+%notyet
+%notyet \begin{verbatim}
+%notyet #define N_DIMS 2
+%notyet #define N_INTERP_POINTS 5
+%notyet #define N_INPUT_ARRAYS 2
+%notyet #define N_OUTPUT_ARRAYS 2
+%notyet
+%notyet /* (x,y) coordinates of data grid points */
+%notyet /* ... note Cactus uses Fortran storage ordering, i.e.\ X is contiguous */
+%notyet #define NX 10
+%notyet #define NY 20
+%notyet const CCTK_INT coord_array_dims[N_DIMS] = { NX, NY };
+%notyet const CCTK_REAL x_coords[NY][NX];
+%notyet const CCTK_REAL y_coords[NY][NX];
+%notyet const void *const coord_arrays[N_DIMS]
+%notyet = { (const void *) x_coords, (const void *) y_coords };
+%notyet
+%notyet /* (x,y) coordinates of interpolation points */
+%notyet const CCTK_REAL interp_x[N_INTERP_POINTS];
+%notyet const CCTK_REAL interp_y[N_INTERP_POINTS];
+%notyet const void *const interp_coords[N_DIMS]
+%notyet = { (const void *) interp_x, (const void *) interp_y };
+%notyet
+%notyet /* input arrays */
+%notyet /* ... note Cactus uses Fortran storage ordering, i.e.\ X is contiguous */
+%notyet const CCTK_REAL input_real [NY][NX];
+%notyet const CCTK_COMPLEX input_complex[NY][NX];
+%notyet const CCTK_INT input_array_dims[N_DIMS] = { NX, NY };
+%notyet const CCTK_INT input_array_type_codes[N_INPUT_ARRAYS]
+%notyet = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_COMPLEX };
+%notyet const void *const input_arrays[N_INPUT_ARRAYS]
+%notyet = { (const void *) input_real, (const void *) input_complex };
+%notyet
+%notyet /* output arrays */
+%notyet CCTK_REAL output_real [N_INTERP_POINTS];
+%notyet CCTK_COMPLEX output_complex[N_INTERP_POINTS];
+%notyet const CCTK_INT output_array_type_codes[N_OUTPUT_ARRAYS]
+%notyet = { CCTK_VARIABLE_REAL, CCTK_VARIABLE_COMPLEX };
+%notyet void *const output_arrays[N_OUTPUT_ARRAYS]
+%notyet = { (void *) output_real, (void *) output_complex };
+%notyet
+%notyet int operator_handle, param_table_handle;
+%notyet operator_handle = CCTK_InterpHandle("my interpolation operator");
+%notyet if (operator_handle < 0)
+%notyet CCTK_WARN(-1, "can't get interpolation handle!");
+%notyet param_table_handle = Util_TableCreateFromString("order=3");
+%notyet if (param_table_handle < 0)
+%notyet CCTK_WARN(-1, "can't create parameter table!");
+%notyet if (CCTK_InterpLocalWarped(N_DIMS,
+%notyet operator_handle, param_table_handle,
+%notyet CCTK_VARIABLE_REAL,
+%notyet coord_array_dims,
+%notyet coord_arrays,
+%notyet N_INTERP_POINTS,
+%notyet CCTK_VARIABLE_REAL,
+%notyet interp_coords,
+%notyet N_INPUT_ARRAYS,
+%notyet input_array_dims,
+%notyet input_array_type_codes,
+%notyet input_arrays,
+%notyet N_OUTPUT_ARRAYS,
+%notyet output_array_type_codes,
+%notyet output_arrays) < 0)
+%notyet CCTK_WARN(-1, "error return from interpolator!");
+%notyet \end{verbatim}
+%notyet \end{Example}
+%notyet \end{ExampleSection}
+%notyet \end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Interp.c
+\begin{CCTKFunc}{CCTK\_InterpRegisterOperatorGV}%%%
+{Register a routine as a {\tt CCTK\_InterpGV()} interpolation operator}
+\label{CCTK-InterpRegisterOperatorGV}
+\subroutine{int}{}{ierr}
+\argument{cInterpOperatorGV}{}{operator}
+\argument{const char *}{}{name}
+\showcargs
+\begin{params}
+\parameter{operator}{Routine to be registered as the interpolation operator}
+\parameter{name}{Name of interpolation operator}
+\end{params}
+\begin{discussion}
+Only C routines can be registered as interpolation operators.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t
+extern int my\_operator (cGH *GH,\vfill
+\hspace{29ex}const char *coord\_system,\vfill
+\hspace{29ex}int num\_points,\vfill
+\hspace{29ex}int num\_in\_array\_indices,\vfill
+\hspace{29ex}int num\_out\_arrays,\vfill
+\hspace{29ex}void *interp\_coord\_arrays[],\vfill
+\hspace{29ex}int interp\_coord\_array\_types[],\vfill
+\hspace{29ex}int in\_array\_indices[],\vfill
+\hspace{29ex}void *out\_arrays[],\vfill
+\hspace{29ex}int out\_array\_types[]);\linebreak
+ierr = CCTK\_InterpRegisterOperatorGV(my\_operator,\vfill
+\hspace{2ex}"my interpolation operator");}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative return code indicates an error condition:
+\end{tabular}
+\begin{tabular}{ll}
+-1 & NULL pointer was passed as interpolation operator routine\\
+-2 & interpolation handle could not be allocated\\
+-3 & Interpolation operator with this name already exists\\
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Interp.c
+\begin{CCTKFunc}{CCTK\_InterpRegisterOperatorLocal}%%%
+{Register a routine as a {\tt CCTK\_InterpLocal()} interpolation operator}
+\label{CCTK-InterpRegisterOperatorLocal}
+\subroutine{int}{}{ierr}
+\argument{cInterpOperatorLocal}{}{operator}
+\argument{const char *}{}{name}
+\showcargs
+\begin{params}
+\parameter{operator}{Routine to be registered as the interpolation operator}
+\parameter{name}{Name of interpolation operator}
+\end{params}
+\begin{discussion}
+Only C routines can be registered as interpolation operators.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t
+extern int my\_operator (cGH *GH,\vfill
+\hspace{29ex}int num\_points,\vfill
+\hspace{29ex}int num\_dims,\vfill
+\hspace{29ex}int num\_in\_arrays,\vfill
+\hspace{29ex}int num\_out\_arrays,\vfill
+\hspace{29ex}int coord\_dims[],\vfill
+\hspace{29ex}void *coord\_arrays[],\vfill
+\hspace{29ex}int coord\_array\_types[],\vfill
+\hspace{29ex}void *interp\_coord\_arrays[],\vfill
+\hspace{29ex}int interp\_coord\_array\_types[],\vfill
+\hspace{29ex}void *in\_arrays[],\vfill
+\hspace{29ex}int in\_array\_types[],\vfill
+\hspace{29ex}void *out\_arrays[],\vfill
+\hspace{29ex}int out\_array\_types[]);\linebreak
+ierr = CCTK\_InterpRegisterOperatorLocal(my\_operator,\vfill
+\hspace{2ex}"my interpolation operator");}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative return code indicates an error condition:
+\end{tabular}
+\begin{tabular}{ll}
+-1 & NULL pointer was passed as interpolation operator routine\\
+-2 & interpolation handle could not be allocated\\
+-3 & Interpolation operator with this name already exists\\
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% here should be CCTK\_InterpRegisterOpLocalNonUniform
+
+% Interp.c
+\begin{FunctionDescription}{CCTK\_InterpRegisterOpLocalUniform}
+\label{CCTK-InterpRegisterOpLocalUniform}
+Register a \verb|CCTK_InterpLocalUniform()| interpolation operator.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+int CCTK_InterpRegisterOpLocalUniform(cInterpOpLocalUniform operator_ptr,
+ const char *operator_name,
+ const char *thorn_name);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{handle ($\ge 0$)}
+A cactus handle to refer to all interpolation operators registered
+under this operator name.
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{operator\_ptr ($\ne$ NULL)}
+\hbox{}
+Pointer to the \verb|CCTK_InterpLocalUniform()| interpolation operator.
+This argument must be a C function pointer of the appropriate type;
+the typedef can be found in \verb|src/include/cctk_Interp.h| in the
+Cactus source code.
+\end{Parameter}
+\begin{Parameter}{operator\_name ($\ne$ NULL)}
+\hbox{}
+(Pointer to) a (C-style null-terminated) character string giving
+the name under which to register the operator.
+\end{Parameter}
+\begin{Parameter}{thorn\_name ($\ne$ NULL)}
+\hbox{}
+(Pointer to) a (C-style null-terminated) character string giving
+the name of the thorn which provides the interpolation operator.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Only C functions (or other routines with C-compatible calling sequences)
+can be registered as interpolation operators.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_InterpHandle()}
+Get the interpolator handle for a given character-string name.
+\end{SeeAlso}
+\begin{SeeAlso}{CCTK\_InterpLocalUniform()}
+Interpolate a list of processor-local arrays, with uniformly spaced
+data points.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{-1}
+NULL pointer was passed as interpolation operator routine
+\end{Error}
+\begin{Error}{-2}
+interpolation handle could not be allocated
+\end{Error}
+\begin{Error}{-3}
+Interpolation operator with this name already exists
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+/* prototype for function we want to register */
+int AEILocalInterp_InterpLocalUniform(int N_dims,
+ int param_table_handle,
+ /***** coordinate system *****/
+ const CCTK_REAL coord_origin[],
+ const CCTK_REAL coord_delta[],
+ /***** interpolation points *****/
+ int N_interp_points,
+ int interp_coords_type_code,
+ const void *const interp_coords[],
+ /***** input arrays *****/
+ int N_input_arrays,
+ const CCTK_INT input_array_dims[],
+ const CCTK_INT input_array_type_codes[],
+ const void *const input_arrays[],
+ /***** output arrays *****/
+ int N_output_arrays,
+ const CCTK_INT output_array_type_codes[],
+ void *const output_arrays[]);
+
+/* register it! */
+CCTK_InterpRegisterOpLocalUniform(AEILocalInterp_InterpLocalUniform,
+ "generalized polynomial interpolation",
+ CCTK_THORNSTRING);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% CCTK\_InterpRegisterOpLocalWarped here
+
+% ActiveThorns.c
+\begin{CCTKFunc}{CCTK\_IsImplementationActive}{Reports whether an implementation was activated in a parameter file}
+\label{CCTK-IsImplementationActive}
+\function{int}{integer}{istat}
+\argument{const char *}{character*(*)}{implementationname}
+\showargs
+\begin{params}
+\parameter{istat}{the return status}
+\parameter{implementationname}{the name of the implementation to check}
+\end{params}
+\begin{discussion}
+This function returns a non-zero value if the implementation given by
+{\tt implementationname} was activated in a parameter file, and zero
+otherwise.
+\end{discussion}
+\end{CCTKFunc}
+
+% ActiveThorns.c
+\begin{CCTKFunc}{CCTK\_IsImplementationCompiled}{Reports whether an
+implementation was compiled into the configuration}
+\label{CCTK-IsImplementationCompiled}
+\function{int}{integer}{istat}
+\argument{const char *}{character*(*)}{implementationname}
+\showargs
+\begin{params}
+\parameter{istat}{the return status}
+\parameter{implementationname}{the name of the implementation to check}
+\end{params}
+\begin{discussion}
+This function returns a non-zero value if the implementation given by
+{\tt implementationname} was compiled into the configuration, and zero
+otherwise.
+\end{discussion}
+\end{CCTKFunc}
+
+% ActiveThorns.c
+\begin{CCTKFunc}{CCTK\_IsThornActive}{Reports whether a thorn was activated in a parameter file}
+\label{CCTK-IsThornActive}
+\function{int}{integer}{istat}
+\argument{const char *}{character*(*)}{thornname}
+\showargs
+\begin{params}
+\parameter{istat}{the return status}
+\parameter{thorname}{the name of the thorn to check}
+\end{params}
+\begin{discussion}
+This function returns a non-zero value if the thorn given by {\tt thornname}
+was activated in a parameter file, and zero otherwise.
+\end{discussion}
+\end{CCTKFunc}
+
+% ActiveThorns.c
+\begin{CCTKFunc}{CCTK\_IsThornCompiled}{Reports whether a thorn was activated in a parameter file}
+\label{CCTK-IsThornCompiled}
+\function{int}{integer}{istat}
+\argument{const char *}{character*(*)}{thornname}
+\showargs
+\begin{params}
+\parameter{istat}{the return status}
+\parameter{thorname}{the name of the thorn to check}
+\end{params}
+\begin{discussion}
+This function returns a non-zero value if the implementation given by
+{\tt thornname} was compiled into the configuration, and zero
+otherwise.
+\end{discussion}
+\end{CCTKFunc}
+
+
+%%%%%
+% JJJ
+%%%%%
+
+%%%%%
+% KKK
+%%%%%
+
+%%%%%
+% LLL
+%%%%%
+
+%%%%%
+% MMM
+%%%%%
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_MaxDim}{Get the maximum dimension of any grid variable }
+\label{CCTK-MaxDim}
+\subroutine{int}{integer}{dim}
+\showargs
+\begin{params}
+\parameter{dim}{The maximum dimension}
+\end{params}
+\begin{discussion}
+Note that the maximum dimension will depend on the compiled thorn list,
+and not the active thorn list.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t dim = CCTK\_MaxDim() };
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_MaxDim(dim)}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_MyProc}{Returns the number of the local processor for a parallel run}
+\label{CCTK-MyProc}
+\function{int}{integer}{myproc}
+\argument{const cGH *}{CCTK\_POINTER}{cctkGH}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+For a single processor run this call will return zero. For multiprocessor
+runs, this call will return $0\leq myproc < {\t CCTK\_nProcs(cctkGH)}$.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+\begin{CCTKFunc}{CCTK\_MaxTimeLevels}{Gives the number of timelevels for a group}
+\label{CCTK-MaxTimeLevels}
+\subroutine{int}{integer}{numlevels}
+\argument{const char *}{character*(*)}{name}
+\showargs
+\begin{params}
+\parameter{name}{The full group name}
+\parameter{numlevels}{The number of timelevels}
+\end{params}
+\begin{discussion}
+The group name should be in the form {\t <implementation>::<group>}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t numlevels = CCTK\_MaxTimeLevels("evolve::phivars") ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_MAXTIMELEVELS(numlevels,"evolve::phivars")}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_MaxTimeLevelsVN}{Gives the number of timelevels for a variable}
+\label{CCTK-MaxTimeLevelsVN}
+\subroutine{int}{integer}{numlevels}
+\argument{const char *}{character*(*)}{name}
+\showargs
+\begin{params}
+\parameter{name}{The full variable name}
+\parameter{numlevels}{The number of timelevels}
+\end{params}
+\begin{discussion}
+The variable name should be in the form {\t <implementation>::<variable>}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t numlevels = CCTK\_MaxTimeLevelsVN("evolve::phi") ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_MAXTIMELEVELSVN(numlevels,"evolve::phi")}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_MaxTimeLevelsVI}{Gives the number of timelevels for a variable}
+\label{CCTK-MaxTimeLevelsVI}
+\subroutine{int}{integer}{numlevels}
+\argument{int}{integer}{index}
+\showargs
+\begin{params}
+\parameter{numlevels}{The number of timelevels}
+\parameter{index}{The variable index}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_VarIndex("evolve::phi")}\\
+ &&{\t numlevels = CCTK\_MaxTimeLevelsVI(index) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_MAXTIMELEVELSVI(numlevels,3)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_MaxTimeLevelsGI}{Gives the number of timelevels for a group}
+\label{CCTK-MaxTimeLevelsGI}
+\subroutine{int}{integer}{numlevels}
+\argument{int}{integer}{index}
+\showargs
+\begin{params}
+\parameter{numlevels}{The number of timelevels}
+\parameter{index}{The group index}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_GroupIndex("evolve::phivars")}\\
+ &&{\t numlevels = CCTK\_MaxTimeLevelsGI(index) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_MAXTIMELEVELSGI(numlevels,3)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+%%%%%
+% NNN
+%%%%%
+
+
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_nProcs}{Returns the number of processors being used for a parallel run}
+\label{CCTK-nProcs}
+\function{int}{integer}{nprocs}
+\argument{const cGH *}{CCTK\_POINTER}{cctkGH}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+For a single processor run this call will return one.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% util/Misc.c
+\begin{FunctionDescription}{CCTK\_NullPointer}%%%
+\label{CCTK-NullPointer}
+Returns a C-style NULL pointer value.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+CCTK_POINTER pointer_var
+
+pointer_var = CCTK_NullPointer()
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{pointer\_var}
+a CCTK\_POINTER type variable which is initialized with a C-style NULL pointer
+\end{Result}
+\end{ResultSection}
+
+\begin{Discussion}
+Fortran doesn't know the concept of pointers so problems arise when a C function
+is to be called which expects a pointer as one (or more) of it(s) argument(s).
+
+In order to pass a NULL pointer from fortran to C, a local CCTK\_POINTER variable should be used which has been initialized before with {\t CCTK\_NullPointer()}.
+
+Note that there is only a fortran wrapper available for {\t CCTK\_NullPointer()}.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_PointerTo()}
+Returns the address of a variable passed in by reference from a fortran routine.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+integer ierror, table_handle
+CCTK_POINTER pointer_var
+
+pointer_var = CCTK_NullPointer()
+
+call Util_TableCreate(table_handle, 0)
+call Util_TableSetPointer(ierror, table_handle, pointer_var, "NULL pointer")
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_NumGroups}{Get the number of groups of variables compiled in the code}
+\label{CCTK-NumGroups}
+\subroutine{int}{integer}{number}
+\showargs
+\begin{params}
+\parameter{number}{The number of groups compiled from the thorns {\t interface.ccl} files}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t number = CCTK\_NumGroups() };
+\\
+\hfill {\bf Fortran} && call {\t CCTK\_NumGroups(number)};
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{CCTK\_NumIOMethods}
+\label{CCTK-NumIOMethods}
+Find the total number of I/O methods registered with the flesh
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+int num_methods = CCTK_NumIOMethods (void);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_NumIOMethods (num_methods)
+integer num_methods
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{num\_methods}number of registered IO methods\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Returns the total number of IO methods registered with the flesh.
+\end{Discussion}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Groups.c
+
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_NumVars}{Get the number of grid variables compiled in the code}
+\label{CCTK-NumVars}
+\subroutine{int}{integer}{number}
+\showargs
+\begin{params}
+\parameter{number}{The number of grid variables compiled from the thorn's {\t interface.ccl} files}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t number = CCTK\_NumVars() };
+\\
+\hfill {\bf Fortran} && call {\t CCTK\_NumVars(number)}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_NumVarsInGroup}{Provides the number of variables in a group from the group name}
+\label{CCTK-NumVarsInGroup}
+\subroutine{int}{integer}{num}
+\argument{const char *}{character*(*)}{name}
+\showargs
+\begin{params}
+\parameter{num}{The number of variables in the group}
+\parameter{group}{The full group name}
+\end{params}
+\begin{discussion}
+The group name should be given in the form {\t <implementation>::<group>}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t numvars = CCTK\_NumVarsInGroup("evolve::scalars") ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_NUMVARSINGROUP(numvars,"evolve::scalars")}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_NumVarsInGroupI}{Provides the number of variables in a group from the group index}
+\label{CCTK-NumVarsInGroupI}
+\subroutine{int}{integer}{num}
+\argument{int}{integer}{index}
+\showargs
+\begin{params}
+\parameter{num}{The number of variables in the group}
+\parameter{group}{The group index}
+\end{params}
+\begin{discussion}
+
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_GroupIndex("evolve::scalars")}\\
+ &&{\t firstvar = CCTK\_NumVarsInGroupI(index) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_NUMVARSINGROUPI(firstvar,3)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+
+
+%%%%%
+% OOO
+%%%%%
+
+
+% IOOverloadables.h
+\begin{FunctionDescription}{CCTK\_OutputGH}
+\label{CCTK-OutputGH}
+Output all variables living on the GH looping over all registered IO methods.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+int istat = CCTK_OutputGH (const cGH *cctkGH);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_OutputGH (istat, cctkGH)
+integer istat
+CCTK_POINTER cctkGH
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{istat}
+total number of variables for which output was done by all IO methods
+\end{Parameter}
+\begin{Parameter}{cctkGH}
+pointer to CCTK grid hierarchy
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The IO methods decide themselfes whether it is time to do output now or not.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{\rm 0}
+it wasn't time to output anything yet by any IO method
+\end{Error}
+\begin{Error}{-1}
+if no IO methods were registered
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IOOverloadables.h
+\begin{FunctionDescription}{CCTK\_OutputVar}
+Output a single variable by all I/O methods
+\label{CCTK-OutputVar}
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+int istat = CCTK_OutputVar (const cGH *cctkGH,
+ const char *variable);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_OutputVar (istat, cctkGH, variable)
+integer istat
+CCTK_POINTER cctkGH
+character*(*) variable
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{istat}return status\end{Parameter}
+\begin{Parameter}{cctkGH}pointer to CCTK grid hierarchy\end{Parameter}
+\begin{Parameter}{variable}full name of variable to output\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The output should take place if at all possible.
+If the appropriate file exists the data is appended, otherwise a new
+file is created.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{\rm 0}
+for success
+\end{Error}
+\begin{Error}{negative}
+for some error condition (eg. IO method is not registered)
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IOOverloadables.h
+\begin{FunctionDescription}{CCTK\_OutputVarAs}
+Output a single variable as an alias by all I/O methods
+\label{CCTK-OutputVarAs}
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+int istat = CCTK_OutputVarAs (const cGH *cctkGH,
+ const char *variable,
+ const char *alias);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_OutputVarAsByMethod (istat, cctkGH, variable, alias)
+integer istat
+CCTK_POINTER cctkGH
+character*(*) variable
+character*(*) alias
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{istat}return status\end{Parameter}
+\begin{Parameter}{cctkGH}pointer to CCTK grid hierarchy\end{Parameter}
+\begin{Parameter}{variable}full name of variable to output\end{Parameter}
+\begin{Parameter}{alias}alias name to base the output filename on\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The output should take place if at all possible.
+If the appropriate file exists the data is appended, otherwise a new
+file is created. Uses {\t alias} as the name of the variable for the purpose
+of constructing a filename.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{positive}the number of IO methods which did output of {\t variable}\end{Error}
+\begin{Error}{\rm 0}for success\end{Error}
+\begin{Error}{negative}if no IO methods were registered\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IOOverloadables.h
+\begin{FunctionDescription}{CCTK\_OutputVarAsByMethod}
+\label{CCTK-OutputVarAsByMethod}
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+int istat = CCTK_OutputVarAsByMethod (const cGH *cctkGH,
+ const char *variable,
+ const char *method,
+ const char *alias);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_OutputVarAsByMethod (istat, cctkGH, variable, method, alias)
+integer istat
+CCTK_POINTER cctkGH
+character*(*) variable
+character*(*) method
+character*(*) alias
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{istat}return status\end{Parameter}
+\begin{Parameter}{cctkGH}pointer to CCTK grid hierarchy\end{Parameter}
+\begin{Parameter}{variable}full name of variable to output\end{Parameter}
+\begin{Parameter}{method}method to use for output\end{Parameter}
+\begin{Parameter}{alias}alias name to base the output filename on\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Output a variable {\t variable} using the method {\t method} if it is
+registered. Uses {\t alias} as the name of the variable for the purpose
+of constructing a filename. The output should take place if at all possible.
+If the appropriate file exists the data is appended, otherwise a new
+file is created.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{\rm 0}for success\end{Error}
+\begin{Error}{negative}indicating some error (eg. IO method is not registered)\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% IOOverloadables.h
+\begin{FunctionDescription}{CCTK\_OutputVarByMethod}
+\label{CCTK-OutputVarByMethod}
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+int istat = CCTK_OutputVarByMethod (const cGH *cctkGH,
+ const char *variable,
+ const char *method);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_OutputVarByMethod (istat, cctkGH, variable, method)
+integer istat
+CCTK_POINTER cctkGH
+character*(*) variable
+character*(*) method
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{istat}return status\end{Parameter}
+\begin{Parameter}{cctkGH}pointer to CCTK grid hierarchy\end{Parameter}
+\begin{Parameter}{variable}full name of variable to output\end{Parameter}
+\begin{Parameter}{method}method to use for output\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Output a variable {\t variable} using the IO method {\t method} if it is
+registered. The output should take place if at all possible.
+if the appropriate file exists the data is appended, otherwise a new
+file is created.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{\rm 0}for success\end{Error}
+\begin{Error}{negative}indicating some error (eg. IO method is not registered)\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+
+
+%%%%%
+% PPP
+%%%%%
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_ParallelInit}{Initialize the parallel subsystem}
+\label{CCTK-ParallelInit}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+Initializes the parallel subsystem.
+\end{discussion}
+\end{CCTKFunc}
+
+
+% WarnLevel.c
+\begin{CCTKFunc}{CCTK\_PARAMWARN}{Prints a warning from parameter checking, and possibly stops the code}
+\label{CCTK-PARAMWARN}
+\subroutine{}{}{}
+\argument{const char *}{character*(*)}{message}
+\showargs
+\begin{params}
+\parameter{message}{The warning message}
+\end{params}
+\begin{discussion}
+The call should be used in routines registered at the schedule point {\t CCTK\_PARAMCHECK}
+to indicate that there is parameter error or conflict and the code should
+terminate. The code will terminate only after all the parameters have been
+checked.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t CCTK\_PARAMWARN("Mass cannot be negative") };
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_PARAMWARN("Inside interpolator")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% util/Misc.c
+\begin{FunctionDescription}{CCTK\_PointerTo}%%%
+\label{CCTK-PointerTo}
+Returns the address of a variable passed in by reference from a fortran routine.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+CCTK_POINTER addr, var
+
+addr = CCTK_PointerTo(var)
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{addr}
+the address of variable {\it var}
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{var}
+variable in the fortran context from which to take the address
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Fortran doesn't know the concept of pointers so problems arise when a C function
+is to be called which expects a pointer as one (or more) of it(s) argument(s).
+
+To obtain the pointer to a variable in fortran, one can use {\t CCTK\_PointerTo()} which takes the variable itself as a single argument and returns the
+pointer to it.
+
+Note that there is only a fortran wrapper available for {\t CCTK\_PointerTo()}.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_NullPointer()}
+Returns a C-style NULL pointer value.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+integer ierror, table_handle
+CCTK_POINTER addr, var
+
+addr = CCTK_PointerTo(var)
+
+call Util_TableCreate(table_handle, 0)
+call Util_TableSetPointer(ierror, table_handle, addr, "variable")
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_PrintGroup}{Prints a group name from its index}
+\label{CCTK-PrintGroup}
+\subroutine{}{}{}
+\argument{int}{integer}{index}
+\showargs
+\begin{params}
+\parameter{index}{The group index}
+\end{params}
+\begin{discussion}
+This routine is for debugging purposes for Fortran programmers.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t CCTK\_PrintGroup(1) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_PRINTGROUP(1)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_PrintString}{Prints a Cactus string}
+\label{CCTK-PrintString}
+\subroutine{}{}{}
+\argument{char *}{CCTK\_STRING}{string}
+\showargs
+\begin{params}
+\parameter{string}{The string to print}
+\end{params}
+\begin{discussion}
+This routine can be used to print Cactus string variables and parameters
+from Fortran.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t CCTK\_PrintString(string\_param) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_PRINTSTRING(string\_param)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_PrintVar}{Prints a variable name from its index}
+\label{CCTK-PrintVar}
+\subroutine{}{}{}
+\argument{int}{integer}{index}
+\showargs
+\begin{params}
+\parameter{index}{The variable index}
+\end{params}
+\begin{discussion}
+This routine is for debugging purposes for Fortran programmers.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t CCTK\_PrintVar(1) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_PRINTVAR(1)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+
+%%%%%
+% QQQ
+%%%%%
+
+
+% cctk_Comm.h
+\begin{CCTKFunc}{CCTK\_QueryGroupStorage}{Query storage for a group given by its group name}
+\label{CCTK-QueryGroupStorage}
+\subroutine{int}{integer}{istat}
+\argument{const cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{const char *}{character*(*)}{groupname}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{groupname}{the group to query, given by its full name}
+\parameter{istat}{the return code}
+\end{params}
+\begin{discussion}
+This routine queries whether the variables in a group have storage assigned.
+If so it returns true (a non-zero value), otherwise false (zero).
+\end{discussion}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative error code is returned for an invalid group name.
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% CommOverloadables.h
+\begin{CCTKFunc}{CCTK\_QueryGroupStorageB}{}
+\label{CCTK-QueryGroupStorageB}
+\subroutine{int}{}{storage}
+\argument{const cGH *}{}{cctkGH}
+\argument{int}{}{groupindex}
+\argument{const char *}{}{groupname}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% cctk_Comm.h
+\begin{CCTKFunc}{CCTK\_QueryGroupStorageI}{Query storage for a group given by its group index}
+\label{CCTK-QueryGroupStorageI}
+\subroutine{int}{integer}{istat}
+\argument{const cGH *}{}{cctkGH}
+\argument{int}{integer}{groupindex}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{groupindex}{the group to query, given by its index}
+\parameter{istat}{the return code}
+\end{params}
+\begin{discussion}
+This routine queries whether the variables in a group have storage assigned.
+If so it returns true (a non-zero value), otherwise false (zero).
+\end{discussion}
+\begin{errorcodes}
+\begin{tabular}{l}
+A negative error code is returned for an invalid group name.
+\end{tabular}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+%%%%%
+% RRR
+%%%%%
+
+% CCTK\_Reduce here
+
+
+\begin{CCTKFunc}{CCTK\_ReductionHandle}{Handle for given reduction method}
+\label{CCTK-ReductionHandle}
+\function{int}{integer}{handle}
+% This gives the wrong Fortran binding!!
+\argument{const char *}{character*(*)}{reduction}
+\showargs
+\begin{params}
+\parameter{handle}{handle returned for this method}
+\parameter{name}{name of the reduction method required}
+\end{params}
+\begin{discussion}
+Reduction methods should be registered at {\t CCTK\_STARTUP}. Note that
+integer reduction handles are used to call {\t CCTK\_Reduce} to avoid
+problems with passing Fortran strings. Note that the name of the reduction
+operator is case dependent.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t handle = CCTK\_ReductionHandle("maximum") };
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_ReductionHandle(handle,"maximum")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% Coord.c
+\begin{CCTKFunc}{CCTK\_RegisterBanner}{Register a banner for a thorn}
+\label{CCTK-RegisterBanner}
+\subroutine{void}{}{}
+\argument{const char *}{character*(*)}{message}
+\showargs
+\begin{params}
+\parameter{message}{String which will be displayed as a banner}
+\end{params}
+\begin{discussion}
+The banner must be registered during {\t CCTK\_STARTUP}. The banners are
+displayed in the order in which they are registered.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t CCTK\_RegisterBanner("My Thorn: Does Something Useful")};
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_REGISTERBANNER("*** MY THORN ***")}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% cctk_GHExtensions.h
+\begin{CCTKFunc}{CCTK\_RegisterGHExtension}{Register an extension to the CactusGH}
+\label{CCTK-RegisterGHExtension}
+\function{int}{}{istat}
+\argument{const char *}{}{name}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% cctk_GHExtensions.h
+\begin{CCTKFunc}{CCTK\_RegisterGHExtensionInitGH}{Register a function which will initialise a given extension to the Cactus GH}
+\label{CCTK-RegisterGHExtensionInitGH}
+\function{int}{}{istat}
+\argument{int}{}{handle}
+\argument{void *}{}{(*func)(cGH *)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% cctk_GHExtensions.h
+\begin{CCTKFunc}{CCTK\_RegisterGHExtensionScheduleTraverseGH}{Register a GH extension schedule traversal routine}
+\label{CCTK-RegisterGHExtensionScheduleTraverseGH}
+\function{int}{}{istat}
+\argument{int}{}{handle}
+\argument{int}{}{(*func)(cGH *,const char *)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% cctk_GHExtensions.h
+\begin{CCTKFunc}{CCTK\_RegisterGHExtensionSetupGH}{Register a function which will set up a given extension to the Cactus GH}
+\label{CCTK-RegisterGHExtensionSetupGH}
+\function{int}{}{istat}
+\argument{int}{}{handle}
+\argument{void *}{}{(*func)(tFleshConfig *, int, cGH *)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_RegisterIOMethod}{Register a new I/O method}
+\label{CCTK-RegisterIOMethod}
+\function{int}{integer}{handle}
+\argument{const char *}{}{name}
+\showargs
+\begin{params}
+\parameter{handle}{handle returned by registration}
+\parameter{name}{name of the I/O method}
+\end{params}
+\begin{discussion}
+IO methods should be registered at {\t CCTK\_STARTUP}.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% cctk_IOMethods.h
+\begin{CCTKFunc}{CCTK\_RegisterIOMethodOutputGH}{Register a routine for an I/O method which will be called from {\tt CCTK\_OutputGH}.}
+\label{CCTK-RegisterIOMethodOutputGH}
+\function{int}{integer}{istat}
+\argument{int}{}{handle}
+\argument{int}{}{(* func)(const cGH *)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% cctk_IOMethods.h
+\begin{CCTKFunc}{CCTK\_RegisterIOMethodOutputVarAs}{Register a routine for an I/O method which will provide aliased variable output}
+\label{CCTK-RegisterIOMethodOutputVarAs}
+\function{int}{integer}{istat}
+\argument{int}{}{handle}
+\argument{int}{}{(* func)(const cGH *,const char*, const char *)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% cctk_IOMethods.h
+\begin{CCTKFunc}{CCTK\_RegisterIOMethodTimeToOutput}{Register a routine for an I/O method which will decide if it is time for the method to output.}
+\label{CCTK-RegisterIOMethodTimeToOutput}
+\function{int}{integer}{istat}
+\argument{int}{}{handle}
+\argument{int}{}{(* func)(const cGH *,int)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+% cctk_IOMethods.h
+\begin{CCTKFunc}{CCTK\_RegisterIOMethodTriggerOutput}{Register a routine for an I/O method which will handle trigger output}
+\label{CCTK-RegisterIOMethodTriggerOutput}
+\function{int}{integer}{istat}
+\argument{int}{}{handle}
+\argument{int}{}{(* func)(const cGH *,int)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_RegisterReductionOperator}{}
+\label{CCTK-RegisterReductionOperator}
+%\function{int}{integer}{istat}
+%\argument{int}{}{handle}
+%\argument{int}{}{(* func)(const cGH *,int)}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+%%%%%
+% SSS
+%%%%%
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_SetupGH}{Setup a new GH}
+\label{CCTK-SetupGH}
+\subroutine{cGH *}{}{cctkGH}
+\argument{tFleshConfig}{}{config}
+\argument{int}{}{convlevel}
+\showcargs
+\begin{params}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+
+% CommOverloadables.c
+\begin{CCTKFunc}{CCTK\_SyncGroup}{Synchronise the ghostzones for a group of grid variables}
+\label{CCTK-SyncGroup}
+\subroutine{int}{integer}{istat}
+\argument{cGH *}{CCTK\_POINTER}{cctkGH}
+\argument{const char *}{character*(*)}{group}
+\showargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\end{params}
+\begin{discussion}
+Only those grid variables which have communication enabled
+will be synchronised. This is usually equivalent to the variables
+which have storage assigned, unless communication has been explicitly
+turned off with a call to {\tt CCTK\_DisableGroupComm}.
+
+Note that an alternative to calling {\tt CCTK\_SyncGroup} explicitly
+from within a thorn, is to use the {\tt SYNC} keyword in a thorns
+{\tt schedule.ccl} file to indicate which groups of variables need
+to be synchronised on exit from the routine. This latter method is
+the preferred method from synchronising variables.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+
+%%%%%
+% TTT
+%%%%%
+
+%%%%%
+% UUU
+%%%%%
+
+%%%%%
+% VVV
+%%%%%
+
+\begin{CCTKFunc}{CCTK\_VarDataPtr}{Returns the data pointer for a grid variable}
+\label{CCTK-VarDataPtr}
+\subroutine{void *}{}{ptr}
+\argument{const cGH *}{}{cctkGH}
+\argument{int}{}{timelevel}
+\argument{char *}{}{name}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{pointer to CCTK grid hierarchy}
+\parameter{timelevel}{The timelevel of the grid variable}
+\parameter{name}{The full name of the variable}
+\end{params}
+\begin{discussion}
+The variable name should be in the form {\t <implementation>::<variable>}.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t myVar = (CCTK\_REAL *)(CCTK\_VarDataPtr(GH,0,"imp::realvar"))}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{CCTKFunc}{CCTK\_VarDataPtrB}{Returns the data pointer for a grid variable from the variable index or the variable name}
+\label{CCTK-VarDataPtrB}
+\subroutine{void *}{}{ptr}
+\argument{const cGH *}{}{cctkGH}
+\argument{int}{}{timelevel}
+\argument{int}{}{index}
+\argument{char *}{}{name}
+\showcargs
+\begin{params}
+\parameter{ptr}{a void pointer to the grid variable data}
+\parameter{cctkGH}{}
+\parameter{timelevel}{The timelevel of the grid variable}
+\parameter{index}{The index of the variable}
+\parameter{name}{The full name of the variable}
+\end{params}
+\begin{discussion}
+If the name if {\t NULL} the index will be used, if the index is negative the name will be used.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t myVar = (CCTK\_REAL *)(CCTK\_VarDataPtrB(GH,0,CCTK\_VarIndex("imp::realvar"),NULL))}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+\begin{CCTKFunc}{CCTK\_VarDataPtrI}{Returns the data pointer for a grid variable from the variable index}
+\label{CCTK-VarDataPtrI}
+\subroutine{void *}{}{ptr}
+\argument{const cGH *}{}{cctkGH}
+\argument{int}{}{timelevel}
+\argument{int}{}{index}
+\showcargs
+\begin{params}
+\parameter{cctkGH}{}
+\parameter{timelevel}{The timelevel of the grid variable}
+\parameter{index}{The index of the variable}
+\end{params}
+\begin{discussion}
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t myVar = (CCTK\_REAL *)(CCTK\_VarDataPtr(GH,0,CCTK\_VarIndex("imp::realvar")))}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Groups.c
+\begin{FunctionDescription}{CCTK\_VarIndex}{}
+\label{CCTK-VarIndex}
+Get the index for a variable.
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+int index = CCTK_VarIndex(const char *varname);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call CCTK_VarIndex(index, varname)
+ integer index
+ character*(*) varname
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{varname}
+The name of the variable.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The variable name should be the given in its fully qualified form,
+that is\\ {\t <implementation>::<variable>} for a public or protected
+variable, and\\ {\t <thornname>::<variable>} for a private variable.
+\end{Discussion}
+
+%\begin{SeeAlsoSection}
+%\end{SeeAlsoSection}
+\begin{ErrorSection}
+\begin{Error}{-1}
+no variable of this name exists
+\end{Error}
+\begin{Error}{-2}
+failed to catch error code from \texttt{Util\_SplitString}
+\end{Error}
+\begin{Error}{-3}
+given full name is in wrong format
+\end{Error}
+\begin{Error}{-4}
+memory allocation failed
+\end{Error}
+\end{ErrorSection}
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+index = CCTK_VarIndex("evolve::phi");
+\end{verbatim}
+\end{Example}
+\begin{Example}{Fortran}
+\begin{verbatim}
+call CCTK_VarIndex(index,"evolve::phi")
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_VarName}{Given a variable index, returns the variable name}
+\label{CCTK-VarName}
+\subroutine{const char *}{integer}{name}
+\argument{int}{integer}{index}
+\showcargs
+\begin{params}
+\parameter{name}{The variable name}
+\parameter{index}{The variable index}
+\end{params}
+\begin{discussion}
+No Fortran routine exists at the moment.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_VarIndex("evolve::phi");}\\
+ && {\t name = CCTK\_VarName(index);}
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+
+% Groups.c
+\begin{CCTKFunc}{CCTK\_VarTypeI}{Provides variable type index from the variable index}
+\label{CCTK-VarTypeI}
+\subroutine{int}{integer}{type}
+\argument{int}{integer}{index}
+\showargs
+\begin{params}
+\parameter{type}{The variable type index}
+\parameter{group}{The variable index}
+\end{params}
+\begin{discussion}
+The variable type index indicates the type of the variable.
+Either character, int, complex or real. The group type can be checked
+with the Cactus provided macros for {\t CCTK\_VARIABLE\_INT}, {\t CCTK\_VARIABLE\_REAL}, {\t CCTK\_VARIABLE\_COMPLEX} or {\t CCTK\_VARIABLE\_CHAR}.
+\end{discussion}
+\begin{examples}
+\begin{tabular}{@{}p{3cm}cp{11cm}}
+\hfill {\bf C} && {\t index = CCTK\_VarIndex("evolve::phi")}\\
+ &&{\t real = (CCTK\_VARIABLE\_REAL == CCTK\_VarTypeI(index)) ;}
+\\
+\hfill {\bf Fortran} && {\t call CCTK\_VARTYPEI(type,3)}\\
+\\
+\end{tabular}
+\end{examples}
+\begin{errorcodes}
+\end{errorcodes}
+\end{CCTKFunc}
+
+\begin{FunctionDescription}{CCTK\_VarTypeSize}
+\label{CCTK-VarTypeSize}
+Provides variable type size in bytes from the variable type index
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+
+int CCTK_VarTypeSize (int vtype);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{vtype}
+Variable type index.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function returns the size in bytes of any of the Cactus variable
+types {\t CCTK\_INT}, {\t CCTK\_REAL}, {\t CCTK\_COMPLEX}, etc.
+\end{Discussion}
+
+%\begin{SeeAlsoSection}
+%\end{SeeAlsoSection}
+
+%\begin{ExampleSection}
+%\begin{Example}{C}
+%\end{Example}
+%\end{ExampleSection}
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_VInfo}
+\label{CCTK-VInfo}
+Prints a formatted string with a variable argument list as an info message
+to sceen
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarnLevel.h"
+
+int status = CCTK_VInfo(const char *thorn,
+ const char *format,
+ ...);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{0} ok \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{thorn}
+The name of the thorn printing this info message. You can use the
+{\t CCTK\_THORNSTRING} macro here (defined in {\t cctk.h}).
+\end{Parameter}
+\begin{Parameter}{format}
+The {\t fprintf(3)}-like format string to use for printing the info message.
+\end{Parameter}
+\begin{Parameter}{...}
+The variable argument list.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This routine can be used by thorns to print a formatted string with a variable
+argument list as an info message to screen.
+The message will include the name of the originating thorn, otherwise its
+semantics is equivalent to {\t fprintf(3)}.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_INFO}
+macro to print an info message with a single string argument
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarningLevel.h"
+
+const char *outdir;
+
+CCTK_VInfo(CCTK_THORNSTRING, "Output files will go to '%s'", outdir);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{CCTK\_VWarn}
+\label{CCTK-VWarn}
+Prints a formatted string with a variable argument list as warning message and
+possibly stops the code
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarnLevel.h"
+
+int status = CCTK_VWarn(int level,
+ int line,
+ const char *file,
+ const char *thorn,
+ const char *format,
+ ...);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{0} ok \end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{level ($\ge 0$)}
+The warning level for the message to print, with level 0 being the severest
+level.
+\end{Parameter}
+\begin{Parameter}{line}
+The line number in the originating source file where the {\t CCTK\_VWarn()} call
+occured. You can use the standardized {\t \_\_LINE\_\_} preprocessor macro here.
+\end{Parameter}
+\begin{Parameter}{file}
+The file name of the originating source file where the {\t CCTK\_VWarn()} call
+occured. You can use the standardized {\t \_\_FILE\_\_} preprocessor macro here.
+\end{Parameter}
+\begin{Parameter}{thorn}
+The thorn name of the originating source file where the {\t CCTK\_VWarn()} call occured. You can use the {\t CCTK\_THORNSTRING} macro here (defined in {\t cctk.h}).
+\end{Parameter}
+\begin{Parameter}{format}
+The {\t fprintf(3)}-like format string to use for printing the warning message.
+\end{Parameter}
+\begin{Parameter}{...}
+The variable argument list.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This routine can be used by thorns to print a formatted string followed by
+a variable argument list as a warning message to {\t stderr}.
+
+By default Cactus prints any warning with warning levels $\le 1$ to standard
+error, and would stop the code on a level 0 warning.
+This behaviour can be changed on the command line using
+the flags {\t -W} and {\t -E} (see the Users' Guide for full details).
+
+The boolean flesh parameter {\tt cctk\_full\_warnings} determines whether all
+the details about the warning origin (processor ID, line number, source file,
+source thorn) are shown. The default is to omit the line number and name of the
+source file.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_WARN}
+macro to print a warning message with a single string argument
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarningLevel.h"
+
+const char *outdir;
+
+CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Output directory '%s' could not be created", outdir);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%%%%%
+% WWW
+%%%%%
+
+
+
+% WarnLevel.c
+\begin{FunctionDescription}{CCTK\_WARN}
+\label{CCTK-WARN}
+Macro to print a single string as a warning message and possibly stop the code
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarnLevel.h"
+
+CCTK_WARN(int level, const char *message);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+call CCTK_WARN(level, message)
+integer level
+character*(*) message
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{level}
+The warning level to use
+\end{Parameter}
+\begin{Parameter}{message}
+The warning message to print
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This macro can be used by thorns to print a single string as a warning message
+to {\t stderr}.
+
+{\tt CCTK\_WARN(level, message)} expands to a call to the underlying function
+{\tt CCTK\_Warn()}:
+
+\begin{verbatim}
+CCTK_Warn(level, __LINE__, __FILE__, CCTK_THORNSTRING, message)
+\end{verbatim}
+
+So the macro automatically includes details about the origin of the warning
+(the thorn name, the source code file name and the line number where the macro
+occurs). It is recommended that the macro {\tt CCTK\_WARN} is used
+to print a warning message rather than calling {\tt CCTK\_Warn()} directly.
+
+To include variables in a warning message from C, you can use the routine
+{\tt CCTK\_VWarn()} which accepts a variable argument list.
+To include variables from Fortran, a string must be constructed and passed
+in a {\tt CCTK\_WARN} macro.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{CCTK\_VWarn()}
+prints a warning message with a variable argument list
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_WarningLevel.h"
+
+CCTK_WARN(0, "Divide by 0");
+\end{verbatim}
+\end{Example}
+\begin{Example}{Fortran}
+\begin{verbatim}
+#include "cctk.h"
+
+integer myint
+real myreal
+character*200 message
+
+write(message, '(A32, G12.7, A5, I8)')
+& 'Your warning message, including ', myreal, ' and ', myint
+call CCTK_WARN(1, message)
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Utility Functions}
+\label{sect-FunctionReference/UtilityFunctions}
+
+In this section all \hbox{{\tt Util\_}*} Cactus utility functions are
+described. These are low-level functions mainly for more complicated
+programming, which are used by the rest of Cactus, but don't depend
+heavily on it. Some of them are callable from Fortran or C, but
+many are C-only.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Functions Alphabetically}
+
+Here the functions are listed alphabetically within each section.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% comment this whole section out until it's non-empty
+%%\subsection{Miscellaneous Functions}
+%%
+%%\begin{Lentry}
+
+%%\item[Util\_asprintf]
+%% [\pageref{Util-asprintf}]
+
+%%\item[Util\_BinTreeFindNode]
+%% [\pageref{Util-BinTreeFindNode}]
+
+%%\item[Util\_BinTreePrintNodes]
+%% [\pageref{Util-BinTreePrintNodes}]
+
+%%\item[Util\_BinTreeStoreData]
+%% [\pageref{Util-BinTreeStoreData}]
+
+%%\item[Util\_BinTreeTraverseInorder]
+%% [\pageref{Util-BinTreeTraverseInorder}]
+
+%%\item[Util\_BinTreeTraversePostorder]
+%% [\pageref{Util-BinTreeTraversePostorder}]
+
+%%\item[Util\_BinTreeTraversePreorder]
+%% [\pageref{Util-BinTreeTraversePreorder}]
+
+%%\item[Util\_CacheMalloc]
+%% [\pageref{Util-CacheMalloc}]
+
+%%\item[Util\_CurrentDate]
+%% [\pageref{Util-CurrentDate}]
+
+%%\item[Util\_CurrentTime]
+%% [\pageref{Util-CurrentTime}]
+
+%%\item[Util\_DeleteHandle]
+%% [\pageref{Util-DeleteHandle}]
+
+%%\item[Util\_DoubleInRange]
+%% [\pageref{Util-DoubleInRange}]
+
+%%\item[Util\_DoubleInRangeList]
+%% [\pageref{Util-DoubleInRangeList}]
+
+%%\item[Util\_GetHandle]
+%% [\pageref{Util-GetHandle}]
+
+%%\item[Util\_GetHandleName]
+%% [\pageref{Util-GetHandleName}]
+
+%%\item[Util\_GetHandledData]
+%% [\pageref{Util-GetHandledData}]
+
+%%\item[Util\_GetHostName]
+%% [\pageref{Util-GetHostName}]
+
+%%\item[Util\_HashAdd]
+%% [\pageref{Util-HashAdd}]
+
+%%\item[Util\_HashCreate]
+%% [\pageref{Util-HashCreate}]
+
+%%\item[Util\_HashData]
+%% [\pageref{Util-HashData}]
+
+%%\item[Util\_HashDelete]
+%% [\pageref{Util-HashDelete}]
+
+%%\item[Util\_HashDestroy]
+%% [\pageref{Util-HashDestroy}]
+
+%%\item[Util\_HashHash]
+%% [\pageref{Util-HashHash}]
+
+%%\item[Util\_HashStore]
+%% [\pageref{Util-HashStore}]
+
+%%\item[Util\_InList]
+%% [\pageref{Util-InList}]
+
+%%\item[Util\_IntInRange]
+%% [\pageref{Util-IntInRange}]
+
+%%\item[Util\_IntInRangeList]
+%% [\pageref{Util-IntInRangeList}]
+
+%%\item[Util\_NewHandle]
+%% [\pageref{Util-NewHandle}]
+
+%%\item[Util\_NullTerminateString]
+%% [\pageref{Util-NullTerminateString}]
+
+%%\item[Util\_SplitFilename]
+%% [\pageref{Util-SplitFilename}]
+
+%%\item[Util\_SplitString]
+%% [\pageref{Util-SplitString}]
+
+%%\item[Util\_StringListAdd]
+%% [\pageref{Util-StringListAdd}]
+
+%%\item[Util\_StringListCreate]
+%% [\pageref{Util-StringListCreate}]
+
+%%\item[Util\_StringListDestroy]
+%% [\pageref{Util-StringListDestroy}]
+
+%%\item[Util\_StringListNext]
+%% [\pageref{Util-StringListNext}]
+
+%%\end{Lentry}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsection{String Functions}
+
+\begin{Lentry}
+
+\item[Util\_StrCmpi]
+ [\pageref{Util-StrCmpi}]
+Compare two strings, ignoring upper/lower case.
+
+\item[Util\_Strdup]
+ [\pageref{Util-Strdup}]
+``Duplicate'' a string,
+\ie{} copy it to a newly--\verb|malloc|ed buffer.
+
+\item[Util\_Strlcat]
+ [\pageref{Util-Strlcat}]
+Concatenate two strings safely.
+
+\item[Util\_Strlcpy]
+ [\pageref{Util-Strlcpy}]
+Copy a string safely.
+
+\end{Lentry}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsection{Table Functions}
+
+\begin{Lentry}
+
+\item[Util\_TableClone]
+ [\pageref{Util-TableClone}]
+Create a new table which is a ``clone'' (exact copy) of an existing
+table
+
+\item[Util\_TableCreate]
+ [\pageref{Util-TableCreate}]
+Create a new (empty) table
+
+\item[Util\_TableCreateFromString]
+ [\pageref{Util-TableCreateFromString}]
+Create a new table (with the case-insensitive flag set) and sets
+values in it based on a string argument (interpreted with
+``parameter-file'' semantics)
+
+\item[Util\_TableDeleteKey]
+ [\pageref{Util-TableDeleteKey}]
+Delete a specified key/value entry from a table
+
+\item[Util\_TableDestroy]
+ [\pageref{Util-TableDestroy}]
+Destroy a table
+
+\item[Util\_TableGet*]
+ [\pageref{Util-TableGet*}]
+This is a family of functions, one for each Cactus data type,
+to get the single (1-element array) value, or more generally the
+first array element of the value, associated with a specified key
+in a key/value table.
+
+\item[Util\_TableGet*Array]
+ [\pageref{Util-TableGet*Array}]
+This is a family of functions, one for each Cactus data type,
+to get a copy of the value associated with a specified key, and store
+it (more accurately, as much of it as will fit) in a specified array
+
+\item[Util\_TableGetGeneric]
+ [\pageref{Util-TableGetGeneric}]
+Get the single (1-element array) value, or more generally the
+first array element of the value, associated with a specified key
+in a key/value table; the value's data type is generic
+
+\item[Util\_TableGetGenericArray]
+ [\pageref{Util-TableGetGenericArray}]
+Get a copy of the value associated with a specified key, and store
+it (more accurately, as much of it as will fit) in a specified array;
+the array's data type is generic
+
+\item[Util\_TableGetString]
+ [\pageref{Util-TableGetString}]
+Gets a copy of the character-string value associated with a specified
+key in a table, and stores it (more accurately, as much of it as will fit)
+in a specified character string
+
+\item[Util\_TableItAdvance]
+ [\pageref{Util-TableItAdvance}]
+Advance a table iterator to the next entry in the table
+
+\item[Util\_TableItClone]
+ [\pageref{Util-TableItClone}]
+Creates a new table iterator which is a ``clone'' (exact copy) of an
+existing table iterator
+
+\item[Util\_TableItCreate]
+ [\pageref{Util-TableItCreate}]
+Create a new table iterator
+
+\item[Util\_TableItDestroy]
+ [\pageref{Util-TableItDestroy}]
+Destroy a table iterator
+
+\item[Util\_TableItQueryIsNonNull]
+ [\pageref{Util-TableItQueryIsNonNull}]
+Query whether a table iterator is {\em not\/} in the ``null-pointer'' state
+
+\item[Util\_TableItQueryIsNull]
+ [\pageref{Util-TableItQueryIsNull}]
+Query whether a table iterator is in the ``null-pointer'' state
+
+\item[Util\_TableItQueryKeyValueInfo]
+ [\pageref{Util-TableItQueryKeyValueInfo}]
+Query the key and the type and number of elements of the value
+corresponding to that key, of the table entry to which an iterator points
+
+\item[Util\_TableItQueryTableHandle]
+ [\pageref{Util-TableItQueryTableHandle}]
+Query what table a table iterator iterates over
+
+\item[Util\_TableItResetToStart]
+ [\pageref{Util-TableItResetToStart}]
+Reset a table iterator to point to the starting table entry
+
+\item[Util\_TableItSetToKey]
+ [\pageref{Util-TableItSetToKey}]
+Set a key/value iterator to point to a specified entry in the table.
+
+\item[Util\_TableItSetToNull]
+ [\pageref{Util-TableItSetToNull}]
+Set a key/value iterator to the ``null-pointer'' state.
+
+\item[Util\_TableQueryFlags]
+ [\pageref{Util-TableQueryFlags}]
+Query a table's flags word
+
+\item[Util\_TableQueryValueInfo]
+ [\pageref{Util-TableQueryValueInfo}]
+Query whether or not a specified key is in the table, and optionally
+the type and/or number of elements of the value corresponding to this key
+
+\item[Util\_TableQueryMaxKeyLength]
+ [\pageref{Util-TableQueryMaxKeyLength}]
+Query the maximum key length in a table
+
+\item[Util\_TableQueryNKeys]
+ [\pageref{Util-TableQueryNKeys}]
+Query the number of key/value entries in a table
+
+\item[Util\_TableSet*]
+ [\pageref{Util-TableSet*}]
+This is a family of functions, one for each Cactus data type,
+to set the value associated with a specified key to be a specified
+single (1-element array) value
+
+\item[Util\_TableSet*Array]
+ [\pageref{Util-TableSet*Array}]
+This is a family of functions, one for each Cactus data type,
+to set the value associated with a specified key to be a copy
+of a specified array
+
+\item[Util\_TableSetFromString]
+ [\pageref{Util-TableSetFromString}]
+Sets values in a table based on a string argument (interpreted with
+``parameter-file'' semantics)
+
+\item[Util\_TableSetGeneric]
+ [\pageref{Util-TableSetGeneric}]
+Set the value associated with a specified key to be a specified
+single (1-element array) value, whose data type is generic
+
+\item[Util\_TableSetGenericArray]
+ [\pageref{Util-TableSetGenericArray}]
+Set the value associated with a specified key to be a copy of a
+specified array, whose data type is generic
+
+\item[Util\_TableSetString]
+ [\pageref{Util-TableSetString}]
+Sets the value associated with a specified key in a table, to be
+a copy of a specified C-style null-terminated character string
+
+\end{Lentry}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Full Descriptions of String Functions}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_StrCmpi}
+\label{Util-StrCmpi}
+Compare two strings, ignoring upper/lower case.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_String.h"
+int cmp = Util_StrCmpi(const char *str1, const char *str2);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{cmp}
+An integer which is:\\
+\begin{tabular}{@{}rl}
+$<0$ & if $\verb|str1| < \verb|str2|$ in lexicographic order
+ ignoring upper/lower case distinctions \\
+$0$ & if $\verb|str1| = \verb|str2|$
+ ignoring upper/lower case distinctions \\
+$>0$ & if $\verb|str1| > \verb|str2|$ in lexicographic order
+ ignoring upper/lower case distinctions %%%\\
+\end{tabular}
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{str1}
+A non-NULL pointer to a (C-style NUL-terminated) string to be compared.
+\end{Parameter}
+\begin{Parameter}{str2}
+A non-NULL pointer to a (C-style NUL-terminated) string to be compared.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The standard C library \verb|strcmp()| function does a {\em case-sensitive\/}
+string comparison, \ie{} \verb|strcmp("cactus", "Cactus")| will find the
+two strings not equal. Sometimes it's useful to do {\em case-insensitive\/}
+string comparison, where upper/lower case distinctions are ignored.
+Many systems provide a \verb|strcasecmp()| or \verb|strcmpi()|
+function to do this, but some systems don't, and even on those that do,
+the name isn't standardised. So, Cactus provides its own version,
+\verb|Util_StrCmpi()|.
+
+Notice that the return value of \verb|Util_StrCmpi()|, like that of
+\verb|strcmp()|, is zero (logical ``false'' in C) for equal strings,
+and nonzero (logcla ``true'' in C) for non-equal strings.
+Code of the form
+\begin{verbatim}
+if (Util_StrCmpi(str1, str2))
+ { /* strings differ */ }
+\end{verbatim}
+or
+\begin{verbatim}
+if (!Util_StrCmpi(str1, str2))
+ { /* strings are identical apart from case distinctions */ }
+\end{verbatim}
+may be confusing to readers, because the sense of the comparison
+isn't immediately obvious. Writing an explicit comparison against zero
+make make things clearer:
+\begin{verbatim}
+if (Util_StrCmpi(str1, str2) != 0)
+ { /* strings differ */ }
+\end{verbatim}
+or
+\begin{verbatim}
+if (Util_StrCmpi(str1, str2) == 0)
+ { /* strings are identical apart from case distinctions */ }
+\end{verbatim}
+
+Unfortunately, the basic concept of ``case-insensitive'' string
+operations doesn't generalize well to non-English character sets,%%%
+\footnote{%%%
+ Hawaiian and Swahili are apparently the only
+ other living languages that use solely the
+ 26-letter ``English'' Latin alphabet.
+ }%%%
+{} where lower-case $\leftrightarrow$ upper-case mappings may be
+context-dependent, many-to-one, and/or time-dependent.%%%
+\footnote{%%%
+ For example, the (lower-case) German ``\ss''
+ doesn't have a unique upper-case equivalent:
+ ``\ss'' usually maps to ``SS''
+ (for example ``gro\ss'' $\leftrightarrow$ ``GROSS''),
+ {\em but\/} if that would conflict
+ with another word, then ``\ss'' maps to ``SZ''
+ (for example ``ma\ss{}e'' $\leftrightarrow$ ``MASZE''
+ because there's a different word ``MASSE'').
+ Or at least that's the way it was prior to 1998.
+ The 1998 revisions to German orthography
+ removed the SZ rule, so now (post-1998) the two
+ distinct German words ``masse'' (English ``mass'')
+ and ``ma\ss{}e'' (``measures'') have identical
+ upper-case forms ``MASSE''. To further complicate
+ matters, (the German-speaking parts of) Switzerland
+ have a slightly different orthography, which never
+ had the SZ rule.
+
+ French provides another tricky example:
+ In France ``\'e'' $\leftrightarrow$ ``\'E'' and
+ ``\`e'' $\leftrightarrow$ ``\`E'',
+ whereas in (the French-speaking parts of) Canada
+ there are no accents on upper-case letters, so
+ ``\'e'' $\leftrightarrow$ ``E'' and
+ ``\`e'' $\leftrightarrow$ ``E''.
+ }%%%
+{} At present Cactus basically ignores these issues. :(
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{strcmp()}
+Standard C library function (prototype in \verb|<string.h>|)
+to compare two strings.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_String.h"
+
+/* does the Cactus parameter driver specify the PUGH driver? */
+/* (Cactus parameters are supposed to be case-insensitive) */
+if (Util_StrCmpi(driver, "pugh") == 0)
+ { /* PUGH code */ }
+else
+ { /* non-PUGH code */ }
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_Strdup}
+\label{Util-Strdup}
+``Duplicate'' a string, \ie{} copy it to a newly--\verb|malloc|ed buffer.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_String.h"
+char* copy = Util_Strdup(const char *str);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{copy}
+A pointer to a buffer obtained from \verb|malloc()|,
+which this function sets to a copy of the (C-style NUL-terminated)
+string \verb|str|. This buffer should be freed with \verb|free()|
+when it's not needed any more.
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{str}
+A non-NULL pointer to a (C-style NUL-terminated) string.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Many systems have a C library function \verb|strdup|, which
+\verb|malloc|s sufficient memory for a copy of its argument string,
+does the copy, and returns a pointer to the copy. However, some
+systems lack this function, so Cactus provides its own version,
+\verb|Util_Strdup()|.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{<stdlib.h>}
+System header file containing prototypes for
+\verb|malloc()| and \verb|free()|.
+\end{SeeAlso}
+\begin{SeeAlso}{strcpy()}
+Standard C library function (prototype in \verb|<string.h>|)
+to copy a string to a buffer.
+{\em This does not check that the buffer is big enough to hold the string,
+and is thus very dangerous. Use \verb|Util_Strlcpy()| instead!}
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_Strlcpy()}
+Safely copy a string.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{NULL}
+\verb|malloc()| was unable to allocate memory for the buffer.
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_String.h"
+
+/*
+ * return the (positive) answer to a question,
+ * or negative if an error occured
+ */
+int answer_question(const char* question)
+{
+/*
+ * we need to modify the question string in the process of parsing it
+ * but we must not destroy the input ==> copy it and modify the copy
+ *
+ * ... note the const qualifier on question_copy says that
+ * the pointer question_copy won't itself change, but
+ * we can modify the string that it points to
+ */
+char* const question_copy = Util_Strdup(question);
+if (question_copy == NULL)
+ { return -1; } /* couldn't get memory for copy buffer */
+
+/* code that will modify question_copy */
+
+free(question_copy);
+return 42;
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_Strlcat}
+\label{Util-Strlcat}
+Concatenate strings safely.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_String.h"
+size_t result_len = Util_Strlcat(char *dst, const char *src, size_t size);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{result\_len}
+The size of the string the function tried to create, i.e.\
+the initial \verb|strlen(dst)| plus \verb|strlen(src)|.
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{dst}
+A non-NULL pointer to the (C-style NUL-terminated) destination string.
+\end{Parameter}
+\begin{Parameter}{src}
+A non-NULL pointer to the (C-style NUL-terminated) source string.
+\end{Parameter}
+\begin{Parameter}{size}
+The size of the destination buffer.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The standard \verb|strcat()| and \verb|strcpy()| functions provide
+no way to specify the size of the destination buffer, so code using
+these functions is often vulnerable to buffer overflows. The standard
+\verb|strncat()| and \verb|strncpy()| functions can be used to write
+safe code, but their API is cumbersome, error-prone, and sometimes
+surprisingly inefficient:
+\begin{itemize}
+\item Their \verb|size| arguments are the number of characters
+ {\em remaining\/} in the destination buffer, which must
+ often be calculated at run-time, and is prone to off-by-one
+ errors.
+\item \verb|strncpy()| doesn't always NUL-terminate the destination string.
+\item \verb|strncpy()| NUL-fills the remainder of the buffer not
+ used for the source string; this NUL-filling can be {\em very\/}
+ expensive.
+\end{itemize}
+
+To solve these problems, the OpenBSD project developed the
+\verb|strlcat()| and \verb|strlcpy()| functions. See
+\verb|http://www.openbsd.org/papers/strlcpy-paper.ps|
+for a history and general discussion of these functions.
+Some other Unix systems (notably Solaris) now provide these,
+but many don't, so Cactus provides its own versions,
+\verb|Util_Strlcat()| and \verb|Util_Strlcpy()|.
+
+\verb|Util_Strlcat()| appends the NUL-terminated string \verb|src| to the
+end of the NUL-terminated string \verb|dst|. It will append at most
+\verb|size - strlen(dst) - 1| characters (hence it never overflows the
+destination buffer), and it always leaves \verb|dst| string NUL-terminated.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{strcat()}
+Standard C library function (prototype in \verb|<string.h>|)
+to concatenate two strings.
+{\em This does not check that the buffer is big enough to hold the result,
+and is thus very dangerous. Use \verb|Util_Strlcat()| instead!}
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_Strlcpy()}
+Safely copy a string.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_String.h"
+
+/*
+ * safely concatenate strings s1,s2,s3 into buffer:
+ * ... this code is safe (it will never overflow the buffer), but
+ * quick-n-dirty in that it doesn't give any error indication
+ * if the result is truncated to fit in the buffer
+ */
+#define BUFFER_SIZE 1024
+char buffer[BUFFER_SIZE];
+
+Util_Strlcpy(buffer, s1, sizeof(buffer));
+Util_Strlcat(buffer, s2, sizeof(buffer));
+Util_Strlcat(buffer, s3, sizeof(buffer));
+\end{verbatim}
+\end{Example}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_String.h"
+
+#define OK 0
+#define ERROR_TRUNC 1
+
+/*
+ * safely concatenate strings s1,s2,s3 into buffer[N_buffer];
+ * return OK if ok, ERROR_TRUNC if result was truncated to fit in buffer
+ */
+int cat3(int N_buffer, char buffer[],
+ const char s1[], const char s2[], const char s3[])
+{
+int length;
+
+length = Util_Strlcpy(buffer, s1, N_buffer);
+if (length >= N_buffer)
+ return ERROR_TRUNC; /*** ERROR EXIT ***/
+
+length = Util_Strlcat(buffer, s2, N_buffer);
+if (length >= N_buffer)
+ return ERROR_TRUNC; /*** ERROR EXIT ***/
+
+length = Util_Strlcat(buffer, s3, N_buffer);
+if (length >= N_buffer)
+ return ERROR_TRUNC; /*** ERROR EXIT ***/
+
+return OK; /*** NORMAL RETURN ***/
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_Strlcpy}
+\label{Util-Strlcpy}
+Copies a string safely.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_String.h"
+size_t result_len = Util_Strlcpy(char *dst, const char *src, size_t size);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{result\_len}
+The size of the string the function tried to create, i.e.\
+\verb|strlen(src)|.
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{dst}
+A non-NULL pointer to the (C-style NUL-terminated) destination string.
+\end{Parameter}
+\begin{Parameter}{src}
+A non-NULL pointer to the (C-style NUL-terminated) source string.
+\end{Parameter}
+\begin{Parameter}{size}
+The size of the destination buffer.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The standard \verb|strcat()| and \verb|strcpy()| functions provide
+no way to specify the size of the destination buffer, so code using
+these functions is often vulnerable to buffer overflows. The standard
+\verb|strncat()| and \verb|strncpy()| functions can be used to write
+safe code, but their API is cumbersome, error-prone, and sometimes
+surprisingly inefficient:
+\begin{itemize}
+\item Their \verb|size| arguments are the number of characters
+ {\em remaining\/} in the destination buffer, which must
+ often be calculated at run-time, and is prone to off-by-one
+ errors.
+\item \verb|strncpy()| doesn't always NUL-terminate the destination string.
+\item \verb|strncpy()| NUL-fills the remainder of the buffer not
+ used for the source string; this NUL-filling can be {\em very\/}
+ expensive.
+\end{itemize}
+
+To solve these problems, the OpenBSD project developed the
+\verb|strlcat()| and \verb|strlcpy()| functions. See
+\verb|http://www.openbsd.org/papers/strlcpy-paper.ps|
+for a history and general discussion of these functions.
+Some other Unix systems (notably Solaris) now provide these,
+but many don't, so Cactus provides its own versions,
+\verb|Util_Strlcat()| and \verb|Util_Strlcpy()|.
+
+\verb|Util_Strlcpy()| copies up to \verb|size-1| characters from the
+source string to the destination string, followed by a NUL character
+(so \verb|dst| is always NUL-terminated). Unlike \verb|strncpy()|,
+\verb|Util_Strlcpy()| does {\em not\/} fill any left-over space at
+the end of the destination buffer with NUL characters.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{strcpy()}
+Standard C library function (prototype in \verb|<string.h>|)
+to copy a string to a buffer.
+{\em This does not check that the buffer is big enough to hold the string,
+and is thus very dangerous. Use \verb|Util_Strlcpy()| instead!}
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_Strdup()}
+``Duplicate'' a string, \ie{} copy it to a newly-\verb|malloc|ed buffer.
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_Strlcat()}
+Safely concatenates two strings.
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_String.h"
+
+/*
+ * safely concatenate strings s1,s2,s3 into buffer:
+ * ... this code is safe (it will never overflow the buffer), but
+ * quick-n-dirty in that it doesn't give any error indication
+ * if the result is truncated to fit in the buffer
+ */
+#define BUFFER_SIZE 1024
+char buffer[BUFFER_SIZE];
+
+Util_Strlcpy(buffer, s1, sizeof(buffer));
+Util_Strlcat(buffer, s2, sizeof(buffer));
+Util_Strlcat(buffer, s3, sizeof(buffer));
+\end{verbatim}
+\end{Example}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_String.h"
+
+#define OK 0
+#define ERROR_TRUNC 1
+
+/*
+ * safely concatenate strings s1,s2,s3 into buffer[N_buffer];
+ * return OK if ok, ERROR_TRUNC if result was truncated to fit in buffer
+ */
+int cat3(int N_buffer, char buffer[],
+ const char s1[], const char s2[], const char s3[])
+{
+int length;
+
+length = Util_Strlcpy(buffer, s1, N_buffer);
+if (length >= N_buffer)
+ return ERROR_TRUNC; /*** ERROR EXIT ***/
+
+length = Util_Strlcat(buffer, s2, N_buffer);
+if (length >= N_buffer)
+ return ERROR_TRUNC; /*** ERROR EXIT ***/
+
+length = Util_Strlcat(buffer, s3, N_buffer);
+if (length >= N_buffer)
+ return ERROR_TRUNC; /*** ERROR EXIT ***/
+
+return OK; /*** NORMAL RETURN ***/
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Full Descriptions of Table Functions}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableClone}
+\label{Util-TableClone}
+Creates a new table which is a ``clone'' (exact copy) of an existing
+table
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int clone_handle = Util_TableClone(int handle);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableClone(clone_handle, handle)
+integer clone_handle, handle
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{clone\_handle ($\ge 0$)}
+A handle to the clone table
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle}
+Handle to the table to be cloned
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Viewing a table as a set of key/value pairs, this function creates
+a new table (with the same flags word as the original) containing
+copies of all the original table's key/value pairs. The two tables
+are completely independent, \ie{} future changes to one won't affect
+the other.
+
+Note that if there are any \verb|CCTK_POINTER| and/or \verb|CCTK_FPOINTER|
+values in the table, they are ``shallow copied'', \ie{} the (pointer)
+values in the table are copied. This results in the clone table's
+pointer values pointing to the same places as the original table's
+pointer values. Be careful with this! In particular,
+if you're using pointer values in the table to keep track of
+\verb|malloc()| memory, be careful not to \verb|free()|
+the same block of memory twice!
+
+Note that table iterators are {\em not\/} guaranteed to sequence
+through the original and clone tables in the same order. (This
+is a special case of the more general ``non-guarantee'' in
+the Section of table iterators in the Users' Guide:
+the order of table iterators may differ even between different
+tables with identical key/value contents.)
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreate()}
+create a table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableDestroy()}
+destroy a table
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_FLAGS}
+flags word is negative in the to-be-cloned table
+(this indicates an internal error in the table routines,
+and should never happen)
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+/*
+ * This function is passed (a handle to) a table containing some entries.
+ * It needs to set some additional entries and pass the table to some
+ * other function(s), but it also needs to leave the original table
+ * intact for other use by the caller. The solution is to clone the
+ * original table and work on the clone, leaving the original table
+ * unchanged.
+ */
+int my_function(int handle, int x, int y)
+{
+int status;
+
+/* clone the table */
+const int clone_handle = Util_TableClone(handle)
+if (clone_handle < 0)
+ return clone_handle; /* error in cloning table */
+
+/* now set our entries in the clone table */
+status = Util_TableSetInt(clone_handle, x, "x");
+if (status < 0)
+ return status; /* error in setting x */
+status = Util_TableSetInt(clone_handle, y, "y");
+if (status < 0)
+ return status; /* error in setting y */
+
+/* ... code to use the clone table ... */
+/* ... eg pass clone_handle to other functions ... */
+
+/* we're done with the clone now */
+Util_TableDestroy(clone_handle);
+return 0;
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableCreate}
+\label{Util-TableCreate}
+Creates a new (empty) table
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int handle = Util_TableCreate(int flags);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableCreate(handle, flags)
+integer handle, flags
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{handle ($\ge 0$)}
+A handle to the newly-created table
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{flags ($\ge 0$)}
+A flags word for the table. This should be the inclusive-or of zero
+or more of the \verb|UTIL_TABLE_FLAGS_|* bit masks (defined in
+\verb|"util_Table.h"|). For Fortran users, note that inclusive-or
+is the same as sum here, since the bit masks are all disjoint.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+We require the flags word to be non-negative so that other
+functions can distinguish flags from (negative) error codes.
+
+Any User-defined flag words should use only bit positions at or above\\
+\verb|UTIL_TABLE_FLAGS_USER_DEFINED_BASE|, i.e.\ all bit positions
+below this are reserved for present of future Cactus use.
+
+At present there is only a single flags-word bit mask defined
+in \verb|"util_Table.h"|:
+\begin{description}
+\item[{\t UTIL\_TABLE\_FLAGS\_CASE\_INSENSITIVE}]\mbox{}\\
+ By default keys are treated as C-style character strings,
+ and the table functions compare them with the standard C
+ \verb|strcmp()| function.
+ However, by setting the\\
+ \verb|UTIL_TABLE_FLAGS_CASE_INSENSITIVE|
+ bit in the flags word, this table's keys may be made
+ case-insensitive, \ie{} the table routines then compare
+ this table's keys with \verb|Util_StrCmpi()|.%%%
+ Note that keys are still {\em stored\/} exactly as
+ the caller specifies them (\ie{} they are {\em not\/}
+ forced into a canonical case); it's only their
+ {\em comparison\/} that's affected by this flag.
+\end{description}
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_StrCmpi()}
+compare two strings, ignoring upper/lower case
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableClone()}
+create a new table which is a ``clone'' (exact copy) of an existing
+table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableDestroy()}
+destroy a table
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_FLAGS}
+flags word is negative
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+/* create a table, simplest case */
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+/* create a table whose keys will be treated as case-insensitive */
+int handle2 = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableCreateFromString}
+\label{Util-TableCreateFromString}
+Creates a new table (with the case-insensitive flag set) and sets
+values in it based on a string argument (interpreted with
+``parameter-file'' semantics)
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int handle = Util_TableCreateFromString(const char *string);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableCreateFromString(handle, string)
+integer handle
+character*(*) string
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{handle ($\ge 0$)}
+a handle to the newly-created table
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{string}
+a pointer to a C-style null-terminated string specifying the table
+contents; see the description for \verb|Util_TableSetFromString()|
+for a full description of the syntax and semantics of this string
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableClone()}
+Create a new table which is a ``clone'' (exact copy) of an existing
+table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableCreate()}
+create a table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+sets values in a table based on a string argument
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetInt()}
+store a \verb|CCTK_INT| value in a table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetReal()}
+store a \verb|CCTK_REAL| value in a table
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_KEY}
+invalid input: key contains invalid character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+invalid input: can't parse input string
+\end{Error}
+\begin{Error}{\rm other error codes}
+this function may also return any error codes returned by
+\verb|Util_TableCreate()| or \verb|Util_TableSetFromString()|
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+int handle = Util_TableCreateFromString("order = 3\t"
+ "myreal = 42.314159\t"
+ "mystring = 'hello'\t"
+ "myarray = { 0 1 2 3 }");
+
+/* equivalent code to the above */
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
+Util_TableSetFromString(handle, "order = 3\t"
+ "myreal = 42.314159\t"
+ "mystring = 'hello'"
+ "myarray = { 0 1 2 3 }");
+
+/* also equivalent to the above */
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
+CCTK_INT array[] = {0, 1, 2, 3};
+
+Util_TableSetInt(handle, 3, "order");
+Util_TableSetReal(handle, 42.314159, "myreal");
+Util_TableSetString(handle, "hello", "mystring");
+Util_TableSetIntArray(handle, 4, array, "myarray");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableDeleteKey}
+\label{Util-TableDeleteKey}
+Deletes a specified key/value entry from a table
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int key_exists = Util_TableDeleteKey(int handle, const char *key);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableDeleteKey(key_exists, handle, key)
+integer key_exists, handle
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0}
+ok (key existed before this call, and has now been deleted)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function invalidates any iterators for the table which are
+not in the ``null-pointer'' state.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_NO\_SUCH\_KEY}
+no such key in table
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableDestroy}
+\label{Util-TableDestroy}
+Destroys a table
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableDestroy(int handle);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableDestroy(status, handle)
+integer status, handle
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0}
+ok
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Of course, this function invalidates any and all iterators for the table. :)
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableClone()}
+Create a new table which is a ``clone'' (exact copy) of an existing
+table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableCreate()}
+create a table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+/* create a table */
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+/* do things with the table: put values in it, */
+/* pass its handle to other functions, etc etc */
+/* ... */
+
+/* at this point we (and all other functions we */
+/* may call in the future) are done with the table */
+Util_TableDestroy(handle);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableGet*}
+\label{Util-TableGet*}
+This is a family of functions, one for each Cactus data type,
+to get the single (1-element array) value, or more generally the
+first array element of the value, associated with a specified key
+in a key/value table.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int N_elements = Util_TableGetXxx(int handle,
+ CCTK_XXX *value,
+ const char *key);
+\end{verbatim}
+where \verb|XXX| is one of
+ \verb|POINTER|, \verb|FPOINTER|%%%
+\footnote{%%%
+ For backwards compatability the function
+ {\tt Util\_TableGetFnPointer()} is also provided
+ as an alias for {\tt Util\_TableGetFPointer()}.
+ This is deprecated as of Cactus 4.0 beta 13.
+ }%%%
+,
+ \verb|CHAR|,
+ \verb|INT|, \verb|INT2|, \verb|INT4|, \verb|INT8|,
+ \verb|REAL|, \verb|REAL4|, \verb|REAL8|, \verb|REAL16|,
+ \verb|COMPLEX|, \verb|COMPLEX8|, \verb|COMPLEX16|, \verb|COMPLEX32|
+(not all of these may be supported on any given system)
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableGetXxx(N_elements, handle, value, key)
+integer N_elements, handle
+CCTK_XXX value
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{N\_elements}
+the number of array elements in the value
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{value}
+a pointer to where this function should store a copy of the value
+(or more generally the first array element of the value) associated
+with the specified key,
+or NULL pointer to skip storing this
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Note that it is {\em not\/} an error for the value to actually have
+$> 1$ array elements; in this case only the first element is stored.
+The rationale for this design is that the caller may know or suspect
+that the value is a large array, but may only want the first array
+element; in this case this design avoids the caller having to allocate
+a large buffer unnecessarily.
+
+In contrast, it {\em is\/} an error for the value to actually be an
+empty (0-length) array, because then there is no ``first array element''
+to get.
+
+It is also an error for the value to actually have a different type
+than \verb|CCTK_XXX|.
+
+If any error code is returned, the user's value buffer
+(pointed to by \verb|value| if this is non-NULL) is unchanged.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_NO\_SUCH\_KEY}
+no such key in table
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_WRONG\_DATA\_TYPE}
+value has data type other than \verb|CCTK_TYPE|
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_VALUE\_IS\_EMPTY}
+value is an empty (0-element) array
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#define N_DIGITS 5
+static const CCTK_INT pi_digits[N_DIGITS] = {3, 14, 159, 2653, 58979};
+
+int N;
+CCTK_INT x;
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetIntArray(handle, N_DIGITS, pi_digits, "digits of pi");
+Util_TableSetIntArray(handle, 0, pi_digits, "empty array");
+
+/* gets N = 5, x = 3 */
+N = Util_TableGetInt(handle, &x, "digits of pi");
+
+/* gets N = UTIL_ERROR_TABLE_VALUE_IS_EMPTY */
+N = Util_TableGetInt(handle, &x, "empty array");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableGet*Array}
+\label{Util-TableGet*Array}
+This is a family of functions, one for each Cactus data type,
+to get a copy of the value associated with a specified key, and store
+it (more accurately, as much of it as will fit) in a specified array
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int N_elements = Util_TableGetXxxArray(int handle,
+ int N_array, CCTK_XXX array[],
+ const char *key);
+\end{verbatim}
+where \verb|XXX| is one of
+ \verb|POINTER|, \verb|FPOINTER|%%%
+\footnote{%%%
+ For backwards compatability the function
+ {\tt Util\_TableGetFnPointerArray()} is also provided
+ as an alias for {\tt Util\_TableGetFPointerArray()}.
+ This is deprecated as of Cactus 4.0 beta 13.
+ }%%%
+,
+ \verb|CHAR|,
+ \verb|INT|, \verb|INT2|, \verb|INT4|, \verb|INT8|,
+ \verb|REAL|, \verb|REAL4|, \verb|REAL8|, \verb|REAL16|,
+ \verb|COMPLEX|, \verb|COMPLEX8|, \verb|COMPLEX16|, \verb|COMPLEX32|
+(not all of these may be supported on any given system)
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableGetXxxArray(N_elements, handle, N_array, array, key)
+integer N_elements, handle, N_array
+CCTK_XXX(*) array
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{N\_elements}
+the number of array elements in the value
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{N\_array}
+the number of array elements in \verb|array[]|
+(must be $\ge 0$ if \verb|array != NULL|)
+\end{Parameter}
+\begin{Parameter}{array}
+a pointer to where this function should store (up to \verb|N_array|
+elements of) a copy of the value associated with the specified key,
+or NULL pointer to skip storing this
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Note that it is {\em not\/} an error for the value to actually have
+$> \verb|N_array|$ array elements; in this case only the first \verb|N_array|
+elements are stored. The caller can detect this by comparing the
+return value with \verb|N_array|.
+The rationale for this design is that the caller may know or suspect
+that the value is a large array, but may only want the first few array
+elements; in this case this design avoids the caller having to allocate
+a large buffer unnecessarily.
+
+It is also {\em not\/} an error for the value to actually have
+$< \verb|N_array|$ array elements; again the caller can detect this by
+comparing the return value with \verb|N_array|.
+
+It {\em is\/} an error for the value to actually have a different type
+than \verb|CCTK_XXX|.
+
+If any error code is returned, the user's value buffer
+(pointed to by \verb|array| if this is non-NULL) is unchanged.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+\verb|array != NULL| and \verb|N_array| $< 0$
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_NO\_SUCH\_KEY}
+no such key in table
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_WRONG\_DATA\_TYPE}
+value has data type other than \verb|CCTK_TYPE|
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#define N_STUFF 3
+static const CCTK_REAL stuff[N_STUFF] = {42.0, 69.0, 105.5};
+
+#define N_OUTPUT 2
+CCTK_INT output[N_OUTPUT];
+
+int N;
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetRealArray(handle, N_STUFF, stuff, "blah blah blah");
+
+/* gets N = 3, output[0] = 42.0, output[1] = 69.0 */
+N = Util_TableGetRealArray(handle, N_OUTPUT, output, "blah blah blah");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableGetGeneric}
+\label{Util-TableGetGeneric}
+Get the single (1-element array) value, or more generally the
+first array element of the value, associated with a specified key
+in a key/value table; the value's data type is generic. That
+is, the value is specified by a \verb|CCTK_VARIABLE_|* type code
+and a \verb|void *| pointer.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int N_elements = Util_TableGetGeneric(int handle,
+ int type_code,
+ void *value,
+ const char *key);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableGetGeneric(N_elements, handle, type_code, value, key)
+integer N_elements, handle, type_code
+CCTK_POINTER value
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{N\_elements}
+the number of array elements in the value
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{type\_code}
+the value's type code
+(one of the \verb|CCTK_VARIABLE_|* constants from \verb|"cctk_Constants.h"|)
+\end{Parameter}
+\begin{Parameter}{value}
+a pointer to where this function should store a copy of the value
+(or more generally the first array element of the value) associated
+with the specified key,
+or NULL pointer to skip storing this
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Note that it is {\em not\/} an error for the value to actually have
+$> 1$ array elements; in this case only the first element is stored.
+The rationale for this design is that the caller may know or suspect
+that the value is a large array, but may only want the first array
+element; in this case this design avoids the caller having to allocate
+a large buffer unnecessarily.
+
+In contrast, it {\em is\/} an error for the value to actually be an
+empty (0-length) array, because then there is no ``first array element''
+to get.
+
+It is also an error for the value to actually have a different type
+than that specified by \verb|type_code|.
+
+If any error code is returned, the user's value buffer
+(pointed to by \verb|value| if this is non-NULL) is unchanged.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableItQueryValueInfo()}
+query key present/absent in table, and optionally type and/or number
+of elements, using an iterator
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableQueryValueInfo()}
+query key present/absent in table, and optionally type and/or number
+of elements
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_NO\_SUCH\_KEY}
+no such key in table
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_WRONG\_DATA\_TYPE}
+value has data type other than \verb|CCTK_TYPE|
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_VALUE\_IS\_EMPTY}
+value is an empty (0-element) array
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+#include "cctk_Constants.h"
+
+#define N_DIGITS 5
+static const CCTK_INT pi_digits[N_DIGITS] = {3, 14, 159, 2653, 58979};
+
+int N;
+CCTK_INT x;
+void *xptr = (void *) &x;
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetIntArray(handle, N_DIGITS, pi_digits, "digits of pi");
+Util_TableSetIntArray(handle, 0, pi_digits, "empty array");
+
+/* gets N = 5, x = 3 */
+N = Util_TableGetGeneric(handle, CCTK_VARIABLE_INT, &x, "the answer");
+
+/* gets N = UTIL_ERROR_TABLE_VALUE_IS_EMPTY, leaves x unchanged */
+N = Util_TableGetGeneric(handle, CCTK_VARIABLE_INT, &x, "empty array");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableGetGenericArray}
+\label{Util-TableGetGenericArray}
+Get a copy of the value associated with a specified key, and store
+it (more accurately, as much of it as will fit) in a specified array;
+the array's data type is generic. That is the array is specified by
+a \verb|CCTK_VARIABLE_|* type code, a count of the number of array
+elements, and a \verb|void *| pointer.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int N_elements = Util_TableGetGenericArray(int handle,
+ int type_code,
+ int N_array, void *array,
+ const char *key);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableGetGenericArray(N_elements,
+. handle,
+. type_code,
+. N_array, array,
+. key)
+integer N_elements, handle, type_code, N_array
+CCTK_POINTER array
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{N\_elements}
+the number of array elements in the value
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{type\_code}
+the value's type code
+(one of the \verb|CCTK_VARIABLE_|* constants from \verb|"cctk_Constants.h"|)
+\end{Parameter}
+\begin{Parameter}{N\_array}
+the number of array elements in \verb|array[]|
+(must be $\ge 0$ if \verb|array != NULL|)
+\end{Parameter}
+\begin{Parameter}{array}
+a pointer to where this function should store (up to \verb|N_array|
+elements of) a copy of the value associated with the specified key,
+or NULL pointer to skip storing this
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Note that it is {\em not\/} an error for the value to actually have
+$> \verb|N_array|$ array elements; in this case only the first \verb|N_array|
+elements are stored. The caller can detect this by comparing the
+return value with \verb|N_array|.
+The rationale for this design is that the caller may know or suspect
+that the value is a large array, but may only want the first few array
+elements; in this case this design avoids the caller having to allocate
+a large buffer unnecessarily.
+
+It is also {\em not\/} an error for the value to actually have
+$< \verb|N_array|$ array elements; again the caller can detect this by
+comparing the return value with \verb|N_array|.
+
+It {\em is\/} an error for the value to actually have a different type
+than that specified by \verb|type_code|.
+
+If any error code is returned, the user's value buffer
+(pointed to by \verb|array| if this is non-NULL) is unchanged.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableItQueryValueInfo()}
+query key present/absent in table, and optionally type and/or number
+of elements, using an iterator
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableQueryValueInfo()}
+query key present/absent in table, and optionally type and/or number
+of elements
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+\verb|array != NULL| and \verb|N_array| $< 0$
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_NO\_SUCH\_KEY}
+no such key in table
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_WRONG\_DATA\_TYPE}
+value has data type other than \verb|CCTK_TYPE|
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#define N_STUFF 3
+static const CCTK_REAL stuff[N_STUFF] = {42.0, 69.0, 105.5};
+
+#define N_OUTPUT 2
+CCTK_INT output[N_OUTPUT];
+
+int N;
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetRealArray(handle, N_STUFF, stuff, "stuff");
+
+/* gets N = UTIL_ERROR_TABLE_WRONG_DATA_TYPE, output[] unchanged */
+N = Util_TableGetGenericArray(handle,
+ CCTK_VARIABLE_INT,
+ N_OUTPUT, output,
+ "stuff");
+/* gets N = 3, output[0] = 42.0, output[1] = 69.0 */
+N = Util_TableGetGenericArray(handle,
+ CCTK_VARIABLE_REAL,
+ N_OUTPUT, output,
+ "stuff");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableGetString}
+\label{Util-TableGetString}
+Gets a copy of the character-string value associated with a specified
+key in a table, and stores it (more accurately, as much of it as will fit)
+in a specified character string
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int length = Util_TableGetString(int handle,
+ int buffer_length, char buffer[],
+ const char *key);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{ResultNote}
+Results are the same as all the other \verb|Util_TableGet|* functions:
+\end{ResultNote}
+\begin{Result}{length}
+the length of the string
+(C \verb|strlen()| semantics, \ie{} {\em not\/} including
+the terminating null character)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{buffer\_length}
+the length (\verb|sizeof()|) of \verb|buffer[]|
+(must be $\ge 1$ if \verb|buffer != NULL|)
+\end{Parameter}
+\begin{Parameter}{buffer}
+a pointer to a buffer into which this function should store
+(at most \verb|buffer_length-1| characters of) the value,
+terminated by a null character as usual for C strings,
+or NULL pointer to skip storing this
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function assumes that the string is stored as an array of
+\verb|CCTK_CHAR|s, {\em not\/} including a terminating null character.
+
+This function differs from \verb|Util_TableGetCharArray()| in two ways:
+It explicitly provides a terminating null character for C-style strings,
+and it explicitly checks for the string being too long to fit in the buffer
+(in which case it returns \verb|UTIL_ERROR_TABLE_STRING_TRUNCATED|).
+
+If the error code \verb|UTIL_ERROR_TABLE_STRING_TRUNCATED| is returned,
+then the first \verb|buffer_length-1| characters of the string are
+returned in the user's buffer (assuming \verb|buffer| is non-NULL),
+followed by a null character to properly terminate the string in the
+buffer. If any other error code is returned, the user's value buffer
+(pointed to by \verb|buffer| if this is non-NULL) is unchanged.
+
+To find out how long the string is (and thus how big of a buffer you
+need to allocate to avoid having the string truncated), you can call
+this function with $\verb|buffer_length| = 0$ and $\verb|buffer| = \verb|NULL|$
+(or actually anything you want); the return result will give the
+string length.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetCharArray()}
+get an array-of-\verb|CCTK_CHAR| value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetCharArray()}
+set an array-of-\verb|CCTK_CHAR| value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+\verb|buffer != NULL| and \verb|buffer_length| $\le 0$
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_NO\_SUCH\_KEY}
+no such key in table
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_WRONG\_DATA\_TYPE}
+value has data type other than \verb|CCTK_CHAR|
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_STRING\_TRUNCATED}
+\quad
+\verb|buffer != NULL| and value was truncated to fit in \verb|buffer[]|
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#define N_BUFFER 100
+char buffer[N_BUFFER];
+
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+Util_TableSetString(handle, "relativity", "Einstein");
+
+/* get length of string (= 10 here) */
+int length = Util_TableGetString(handle, 0, NULL, "Einstein");
+
+/* get null-terminated string into buffer, also returns 10 */
+Util_TableGetString(handle, N_BUFFER, buffer, "Einstein");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItAdvance}
+\label{Util-TableItAdvance}
+Advance a table iterator to the next entry in the table
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int is_nonnull = Util_TableItAdvance(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+ok (iterator now points to some table entry)
+\end{Result}
+\begin{Result}{\rm 0}
+ok (iterator has just advanced past the last table entry,
+ and is now in the "null-pointer" state)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+If we view an iterator as an abstraction of a pointer into the table,
+then this function is the abstraction of the C \verb|++| operation applied
+to the pointer, except that this function automagically sets the iterator
+to the "null-pointer" state when it advances past the last table entry.
+
+Note that bad things (garbage results, core dumps) may happen if
+you call this function on an iterator which has been invalidated
+by a change in the table's contents.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+/* walk through all entries of a table */
+int ihandle;
+
+ for ( ihandle = Util_TableItCreate(handle) ;
+ Util_TableItQueryIsNonNull(ihandle) > 0 ;
+ Util_TableItAdvance(ihandle) )
+ {
+ /* do something with the table entry */
+ }
+
+Util_TableItDestroy(ihandle);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItClone}
+\label{Util-TableItClone}
+Creates a new table iterator which is a ``clone'' (exact copy) of an
+existing table iterator
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int clone_ihandle = Util_TableItClone(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{clone\_ihandle ($\ge 0$)}
+A handle to the clone table iterator
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle}
+Handle to the table iterator to be cloned
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function creates a new iterator which points to the same place
+in the same table as the original iterator. If the original iterator
+is in the ``null-pointer'' state, then the clone is also in this state.
+
+Note that bad things (garbage results, core dumps) may happen if
+you call this function on an iterator which has been invalidated
+by a change in the table's contents.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableClone()}
+create a new table which is a ``clone'' (exact copy) of an existing
+table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableItCreate()}
+create a table iterator
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableItDestroy()}
+destroy a table iterator
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle to be cloned, is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+/*
+ * Apart from efficiency and slight differences in error return codes,
+ * Util_TableItClone() could be simulated by the following code.
+ */
+int Util_TableItClone(int ihandle)
+{
+int status;
+
+/* to what table does the to-be-cloned iterator point? */
+const int handle = Util_TableQueryTableHandle(ihandle);
+if (handle < 0)
+ return handle; /* error in querying table handle */
+
+/* create the to-be-cloned iterator */
+/* (pointing into the same table as the original iterator) */
+ {
+const int clone_ihandle = Util_TableItCreate(handle);
+if (clone_ihandle < 0)
+ return clone_ihandle; /* error in creating clone iterator */
+
+/* how long is the key to which the to-be-cloned iterator points? */
+ {
+const int key_length = Util_TableItQueryKeyValueInfo(ihandle,
+ 0, NULL,
+ NULL, NULL);
+if (key_length == UTIL_TABLE_ITERATOR_IS_NULL)
+ {
+ /* to-be-cloned iterator is in "null-pointer" state */
+ Util_TableItSetToNull(clone_ihandle);
+ return clone_ihandle; /* normal return */
+ }
+if (key_length < 0)
+ return key_length; /* error in querying to-be-cloned iterator */
+
+/* to what key does the to-be-cloned iterator point? */
+ {
+const int key_buffer_length = key_length + 1;
+char *const key_buffer = (char *) malloc(key_buffer_length);
+if (key_buffer == NULL)
+ return UTIL_ERROR_NO_MEMORY;
+status = Util_TableItQueryKeyValueInfo(ihandle,
+ key_buffer_length, key_buffer);
+if (status < 0)
+ return status; /* error in querying to-be-cloned iterator */
+
+/* set the clone iterator to point to the same key as the original */
+status = Util_TableItSetToKey(clone_ihandle, key_buffer);
+free(key_buffer);
+return clone_ihandle; /* normal return */
+ }
+ }
+ }
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItCreate}
+\label{Util-TableItCreate}
+Create a new table iterator
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int ihandle = Util_TableItCreate(int handle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table over which the iterator should iterate
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function creates a new table iterator. The iterator initially
+points at the starting table entry.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItDestroy()}
+destroy a table iterator
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+table handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+/* walk through all entries of a table */
+int ihandle;
+
+ for ( ihandle = Util_TableItCreate(handle) ;
+ Util_TableItQueryIsNonNull(ihandle) > 0 ;
+ Util_TableItAdvance(ihandle) )
+ {
+ /* do something with the table entry */
+ }
+
+Util_TableItDestroy(ihandle);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItDestroy}
+\label{Util-TableItDestroy}
+Destroy a table iterator
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableItDestroy(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0}
+ok
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItCreate()}
+create a table iterator
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+/* walk through all entries of a table */
+int ihandle;
+
+ for ( ihandle = Util_TableItCreate(handle) ;
+ Util_TableItQueryIsNonNull(ihandle) > 0 ;
+ Util_TableItAdvance(ihandle) )
+ {
+ /* do something with the table entry */
+ }
+
+Util_TableItDestroy(ihandle);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItQueryIsNonNull}
+\label{Util-TableItQueryIsNonNull}
+Query whether a table iterator is {\em not\/} in the ``null-pointer'' state
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableItQueryIsNonNull(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+iterator is {\em not\/} in the ``null-pointer'' state,
+\ie{} iterator points to some table entry
+\end{Result}
+\begin{Result}{\rm 0}
+iterator is in the ``null-pointer'' state
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+If no errors occur,
+\verb|Util_TableItQueryIsNonNull(ihandle)|
+is the same as\\
+\verb|1 - Util_TableItQueryIsNull(ihandle)|.
+
+Note that bad things (garbage results, core dumps) may happen if
+you call this function on an iterator which has been invalidated
+by a change in the table's contents.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItQueryIsNull()}
+query whether a table iterator is in the ``null-pointer'' state
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+/* walk through all entries of a table */
+int ihandle;
+
+ for ( ihandle = Util_TableItCreate(handle) ;
+ Util_TableItQueryIsNonNull(ihandle) > 0 ;
+ Util_TableItAdvance(ihandle) )
+ {
+ /* do something with the table entry */
+ }
+
+Util_TableItDestroy(ihandle);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItQueryIsNull}
+\label{Util-TableItQueryIsNull}
+Query whether a table iterator is in the ``null-pointer'' state
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableItQueryIsNull(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+iterator is in the ``null-pointer'' state
+\end{Result}
+\begin{Result}{\rm 0}
+iterator is {\em not\/} in the ``null-pointer'' state,
+\ie{} iterator points to some table entry
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+If no errors occur,
+\verb|Util_TableItQueryIsNull(ihandle)|
+is the same as
+\verb|1 - Util_TableItQueryIsNonNull(ihandle)|.
+
+Note that bad things (garbage results, core dumps) may happen if
+you call this function on an iterator which has been invalidated
+by a change in the table's contents.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItQueryIsNonNull()}
+query whether a table iterator is {\em not\/} in the ``null-pointer'' state,
+\ie{} whether the iterator points to some table entry
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+/* variant code to walk through all entries of a table */
+int ihandle;
+
+ for ( ihandle = Util_TableItCreate(handle) ;
+ Util_TableItQueryIsNull(ihandle) == 0 ;
+ Util_TableItAdvance(ihandle) )
+ {
+ /* do something with the table entry */
+ }
+
+Util_TableItDestroy(ihandle);
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItQueryKeyValueInfo}
+\label{Util-TableItQueryKeyValueInfo}
+Query the key and the type and number of elements of the value
+corresponding to that key, of the table entry to which an iterator points
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int key_length =
+ Util_TableItQueryKeyValueInfo(int ihandle,
+ int key_buffer_length, char key_buffer[],
+ CCTK_INT *type_code, CCTK_INT *N_elements)
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{key\_length}
+The string length of the key
+(this has C {\t strlen()} semantics, \ie{} it does {\em not\/}
+include a terminating null character)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table iterator
+\end{Parameter}
+\begin{Parameter}{key\_buffer\_length}
+\quad
+the length (\verb|sizeof()|) of \verb|key_buffer[]|
+(must be $\ge 1$ if \verb|key_buffer != NULL|)
+\end{Parameter}
+\begin{Parameter}{key\_buffer}
+a pointer to a buffer into which this function should store
+(at most \verb|key_buffer_length-1| characters of) the key,
+terminated by a null character as usual for C strings,
+or NULL pointer to skip storing this
+\end{Parameter}
+\begin{Parameter}{type\_code}
+a pointer to where this function should store the value's type code
+(one of the \verb|CCTK_VARIABLE_|* constants from \verb|"cctk_Constants.h"|),
+or a NULL pointer to skip storing this.
+\end{Parameter}
+\begin{Parameter}{N\_elements}
+a pointer to where this function should store
+the number of array elements in the value,
+or a NULL pointer to skip storing this.
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The usual use of an iterator is to iterate through all the entries
+of a table, calling this function on each entry, then taking further
+action based on the results.
+
+Note that bad things (garbage results, core dumps) may happen if
+you call this function on an iterator which has been invalidated
+by a change in the table's contents.
+
+If the error code \verb|UTIL_ERROR_TABLE_STRING_TRUNCATED| is returned,
+then the first \verb|key_buffer_length-1| characters of the key are
+returned in the user's key buffer (assuming \verb|key_buffer| is non-NULL),
+followed by a null character to properly terminate the string in the
+buffer. If any other error code is returned, the user's key buffer
+(pointed to by \verb|key_buffer| if this is non-NULL) is unchanged.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableQueryValueInfo()}
+query key present/absent in table, and optionally type and/or number
+of elements, but using the key instead of an iterator
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_ITERATOR\_IS\_NULL}
+\quad
+iterator is in "null-pointer" state
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_STRING\_TRUNCATED}
+\quad
+\verb|key_buffer != NULL| and key was truncated to fit in \verb|key_buffer|
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+/* print out all entries in a table */
+/* return 0 for ok, type code for any types we can't handle, */
+/* -ve for other errors */
+#include <stdio.h>
+#include <stdlib.h>
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+#include "cctk.h"
+
+int print_table(int handle)
+{
+int max_key_length, N_key_buffer, ihandle;
+char *key_buffer;
+
+max_key_length = Util_TableQueryMaxKeyLength(handle);
+if (max_key_length < 0)
+ return max_key_length;
+
+N_key_buffer = max_key_length + 1;
+key_buffer = (char *) malloc(N_key_buffer);
+if (key_buffer == NULL)
+ return UTIL_ERROR_NO_MEMORY;
+
+ for ( ihandle = Util_TableItCreate(handle) ;
+ Util_TableItQueryIsNonNull(ihandle) > 0 ;
+ Util_TableItAdvance(ihandle) )
+ {
+ CCTK_INT type_code, N_elements;
+ CCTK_INT value_int;
+ CCTK_REAL value_real;
+
+ Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements);
+ printf("key = \"%s\"\n", key_buffer);
+
+ switch (type_code)
+ {
+ case CCTK_VARIABLE_INT:
+ Util_TableGetInt(handle, &value_int, key_buffer);
+ printf("value[int] = %d\n", (int)value_int);
+ break;
+ case CCTK_VARIABLE_REAL:
+ Util_TableGetReal(handle, &value_real, key_buffer);
+ printf("value[real] = %g\n", (double)value_real);
+ break;
+ default:
+ /* we don't know how to handle this type */
+ Util_TableItDestroy(ihandle);
+ free(key_buffer);
+ return type_code;
+ }
+ }
+
+Util_TableItDestroy(ihandle);
+free(key_buffer);
+return 0;
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItQueryTableHandle}
+\label{Util-TableItQueryTableHandle}
+Query what table a table iterator iterates over
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int handle = Util_TableItQueryTableHandle(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{handle ($\ge 0$)}
+handle to the table over which the iterator iterates
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Note that it is always ok to call this function, regardless of
+whether or not the iterator is in the ``null-pointer'' state.
+
+It's also ok to call this function even when the iterator has been
+invalidated by a change in the table's contents.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItCreate()}
+create an iterator (which iterates over a specified table)
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItResetToStart}
+\label{Util-TableItResetToStart}
+Reset a table iterator to point to the starting table entry
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableItResetToStart(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{ResultNote}
+Results are the same as calling \verb|Util_TableItQueryIsNonNull()|
+on the iterator after the reset:
+\end{ResultNote}
+\begin{Result}{\rm 1}
+iterator is {\em not\/} in the ``null-pointer'' state,
+\ie{} iterator points to some table entry
+\end{Result}
+\begin{Result}{\rm 0}
+iterator is in the ``null-pointer'' state
+(this happens if and only if the table is empty)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Note that it is always ok to call this function, regardless of
+whether or not the iterator is in the ``null-pointer'' state.
+
+It's also ok to call this function even when the iterator has been
+invalidated by a change in the table's contents.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItSetToNull()}
+set an iterator to the ``null-pointer'' state
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableItSetToKey()}
+set an iterator to point to a specified table entry
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItSetToKey}
+\label{Util-TableItSetToKey}
+Set a table iterator to point to a specified table entry
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableItSetToKey(int ihandle, const char *key);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0}
+ok
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function has the same effect as calling \verb|Util_TableItResetToStart()|
+followed by calling \verb|Util_TableItAdvance()| zero or more times
+to make the iterator point to the desired table entry. However, this
+function will typically be (much) more efficient than that sequence.
+
+Note that it is always ok to call this function, regardless of
+whether or not the iterator is in the ``null-pointer'' state.
+
+It's also ok to call this function even when the iterator has been
+invalidated by a change in the table's contents.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItResetToStart()}
+reset an iterator to point to the starting table entry
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableItSetToNull()}
+set a table iterator to the "null-pointer" state
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_NO\_SUCH\_KEY}
+no such key in table
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableItSetToNull}
+\label{Util-TableItSetToNull}
+Set a table iterator to the "null-pointer" state
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int handle = Util_TableItSetToNull(int ihandle);
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 0}
+ok
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{ihandle ($\ge 0$)}
+handle to the iterator
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Note that it is always ok to call this function, regardless of
+whether or not the iterator is already in the ``null-pointer'' state.
+
+It's also ok to call this function even when the iterator has been
+invalidated by a change in the table's contents.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItResetToStart()}
+reset an iterator to point to the starting table entry
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableItSetToKey()}
+set an iterator to point to a specified table entry
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+iterator handle is invalid
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableQueryFlags}
+Query a table's flags word
+\label{Util-TableQueryFlags}
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int flags = Util_TableQueryFlags(int handle);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableQueryFlags(flags, handle)
+integer flags, handle
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{flags ($\ge 0$)}
+the flags word
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+See \verb|Util_TableCreate()| for further discussion of the semantics
+of flag words.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableClone()}
+create a new table which is a ``clone'' (exact copy) of an existing
+table
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableCreate()}
+create a table (flags word specified explicitly)
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table (with certain default flags)
+and set key/value entries in it based on a parameter-file--like
+character string
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include <string.h>
+#include "util_ErrorCodes.h"
+#include "util_String.h"
+#include "util_Table.h"
+
+/* compare two strings, doing the comparison with the same */
+/* case-sensitive/insensitive semantics as a certain table uses */
+int compare_strings(int handle, const char *str1, const char *str2)
+{
+int flags = Util_TableQueryFlags(handle);
+return (flags & UTIL_TABLE_FLAGS_CASE_INSENSITIVE)
+ ? Util_StrCmpi(str1, str2)
+ : strcmp (str1, str2);
+}
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableQueryValueInfo}
+\label{Util-TableQueryValueInfo}
+Query whether or not a specified key is in the table, and optionally
+the type and/or number of elements of the value corresponding to this key
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int key_exists =
+ Util_TableQueryValueInfo(int handle,
+ CCTK_INT *type_code, CCTK_INT *N_elements,
+ const char *key);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableQueryValueInfo(key_exists,
+. handle,
+. type_code, N_elements,
+. key)
+integer key_exists, handle
+CCTK_INT type_code, N_elements
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+ok (key is in table)
+\end{Result}
+\begin{Result}{\rm 0}
+ok (no such key in table)\\
+(in this case nothing is stored in \verb|*type_code| and \verb|*N_elements|)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{type\_code}
+a pointer to where this function should store the value's type code
+(one of the \verb|CCTK_VARIABLE_|* constants from \verb|"cctk_Constants.h"|),
+or a NULL pointer to skip storing this.
+\end{Parameter}
+\begin{Parameter}{N\_elements}
+a pointer to where this function should store
+the number of array elements in the value,
+or a NULL pointer to skip storing this.
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+Unlike all the other table query functions, this function returns
+0 for ``no such key in table''. The rationale for this design is that
+by passing NULL pointers for \verb|type_code| and \verb|N_elements|, this
+function is then a Boolean ``is key in table?'' predicate.
+
+If any error code is returned, the user's buffers (pointed to by
+\verb|type_code| and \verb|N_elements| if these are non-NULL) are
+unchanged.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableItQueryKeyValueInfo()}
+query key present/absent in table, and optionally type and/or number
+of elements, but using an iterator instead of the key
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains `/' character
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include <stdio.h>
+#include <assert.h>
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+static const int data[] = {314, 159, 265};
+#define N_DATA (sizeof(data) / sizeof(data[0]))
+
+CCTK_INT type_code, N_elements;
+
+/* see whether or not "key" is in table */
+if (Util_TableQueryValueInfo(handle, NULL, NULL, "key"))
+ {
+ /* key is in the table */
+ }
+ else {
+ /* key is not in the table */
+ }
+
+/* put "data" in table as 3-element integer array */
+Util_TableSetIntArray(handle, N_DATA, data, "data");
+
+/* query info about "data" value */
+assert( Util_TableQueryValueInfo(handle,
+ &type_code, &N_elements,
+ "data") == 1 );
+assert( type_code == CCTK_VARIABLE_INT );
+assert( N_elements == N_DATA );
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableQueryMaxKeyLength}
+\label{Util-TableQueryMaxKeyLength}
+Query the maximum key length in a table
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int max_key_length = Util_TableQueryMaxKeyLength(int handle);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableQueryMaxKeyLength(max_key_length, handle)
+integer max_key_length, handle
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{max\_key\_length ($\ge 0$)}
+The string length of the longest key in the table
+(this has C {\t strlen()} semantics, \ie{} it does {\em not\/}
+include a terminating null character)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+This function is useful if you're going to iterate through a table,
+and you want to allocate a buffer which is guaranteed to be big enough
+to hold any key in the table.
+\end{Discussion}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include <stdlib.h>
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+#include "cctk.h"
+
+int max_key_length = Util_TableQueryMaxKeyLength(handle);
+int N_buffer = max_key_length + 1;
+char *const buffer = (char *) malloc(N_buffer);
+if (buffer == NULL)
+ {
+ CCTK_WARN(-1, "couldn't allocate memory for table key buffer!");
+ abort(); /* CCTK_Abort() would be better */
+ /* if we have a cGH* available */
+ }
+
+/* now buffer is guaranteed to be */
+/* big enough for any key in the table */
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableQueryNKeys}
+\label{Util-TableQueryNKeys}
+Query the number of key/value entries in a table
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int N_Keys = Util_TableQueryNKeys(int handle);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableQueryNKeys(N_Keys, handle)
+integer N_Keys, handle
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{N\_Keys ($\ge 0$)}
+the number of key/value entries in the table
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\end{ErrorSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableSet*}
+\label{Util-TableSet*}
+This is a family of functions, one for each Cactus data type,
+to set the value associated with a specified key to be a specified
+single (1-element array) value
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableSetXxx(int handle,
+ CCTK_XXX value,
+ const char *key);
+\end{verbatim}
+where \verb|XXX| is one of
+ \verb|POINTER|, \verb|FPOINTER|%%%
+\footnote{%%%
+ For backwards compatability the function
+ {\tt Util\_TableSetFnPointer()} is also provided
+ as an alias for {\tt Util\_TableSetFPointer()}.
+ This is deprecated as of Cactus 4.0 beta 13.
+ }%%%
+,
+ \verb|CHAR|,
+ \verb|INT|, \verb|INT2|, \verb|INT4|, \verb|INT8|,
+ \verb|REAL|, \verb|REAL4|, \verb|REAL8|, \verb|REAL16|,
+ \verb|COMPLEX|, \verb|COMPLEX8|, \verb|COMPLEX16|, \verb|COMPLEX32|
+(not all of these may be supported on any given system)
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableSetXxx(status, handle, value, key)
+integer status, handle
+CCTK_XXX value
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+ok (key was already in table before this call, old value was replaced)\\
+ (it doesn't matter what the old value's \verb|type_code| and
+ \verb|N_elements| were, \ie{} these do {\em not\/} have to match
+ the new value)
+\end{Result}
+\begin{Result}{\rm 0}
+ok (key was not in table before this call)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{value}
+the value to be associated with the key
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The key may be any C character string which does not contain a slash
+character (\verb|'/'|).
+
+The value is stored as a 1-element array.
+
+This function invalidates any iterators for the table which are
+not in the ``null-pointer'' state.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include <math.h>
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+CCTK_COMPLEX16 z;
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetInt(handle, 42, "the answer");
+Util_TableSetReal(handle, 299792458.0, "speed of light");
+
+z.Re = cos(0.37); z.Im = sin(0.37);
+Util_TableSetComplex16(handle, z, "my complex number");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableSet*Array}
+\label{Util-TableSet*Array}
+This is a family of functions, one for each Cactus data type,
+to set the value associated with a specified key to be a copy
+of a specified array
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableSetXxxArray(int handle,
+ int N_elements,
+ const CCTK_XXX array[],
+ const char *key);
+\end{verbatim}
+where \verb|XXX| is one of
+ \verb|POINTER|, \verb|FPOINTER|%%%
+\footnote{%%%
+ For backwards compatability the function
+ {\tt Util\_TableSetFnPointerArray()} is also provided
+ as an alias for {\tt Util\_TableSetFPointerArray()}.
+ This is deprecated as of Cactus 4.0 beta 13.
+ }%%%
+,
+ \verb|CHAR|,
+ \verb|INT|, \verb|INT2|, \verb|INT4|, \verb|INT8|,
+ \verb|REAL|, \verb|REAL4|, \verb|REAL8|, \verb|REAL16|,
+ \verb|COMPLEX|, \verb|COMPLEX8|, \verb|COMPLEX16|, \verb|COMPLEX32|
+(not all of these may be supported on any given system)
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableSetXxxArray(status, handle, N_elements, array, key)
+integer status, handle, N_elements
+CCTK_XXX(*) array
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+ok (key was already in table before this call, old value was replaced)\\
+ (it doesn't matter what the old value's \verb|type_code| and
+ \verb|N_elements| were, \ie{} these do {\em not\/} have to match
+ the new value)
+\end{Result}
+\begin{Result}{\rm 0}
+ok (key was not in table before this call)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{N\_elements ($\ge 0$)}
+the number of array elements in \verb|array[]|
+\end{Parameter}
+\begin{Parameter}{array}
+a pointer to the array (a copy of which) is to be associated with the key
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The key may be any C character string which does not contain a slash
+character (\verb|'/'|).
+
+Note that empty (0-element) arrays are ok.
+
+This function invalidates any iterators for the table which are
+not in the ``null-pointer'' state.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+\verb|N_elements| $< 0$
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#define N_DIGITS 5
+static const CCTK_INT pi_digits[N_DIGITS] = {3, 14, 159, 2653, 58979};
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetIntArray(handle, N_DIGITS, pi_digits, "digits of pi");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableSetFromString}
+\label{Util-TableSetFromString}
+Sets values in a table based on a string argument, which is interpreted
+with ``parameter-file'' semantics
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int count = Util_TableSetFromString(int handle, const char *string);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableSetFromString(count, handle, string)
+integer count, handle
+character*(*) string
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{count ($\ge 0$)}
+the number of key/value entries set
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{string}
+a pointer to a C-style null-terminated string specifying the table
+entries to be set (see below for details on the string contents)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The string should contain a sequence of zero or more \verb|key=value|
+``assignments'', separated by whitespace. This function processes
+these assignments in left-to-right order, setting corresponding key/value
+entries in the table.
+
+The present implementation only recognises integer, real, and character-string
+values (not complex), and integer and real arrays.
+To be precise, the string must match the following BNF:\\
+\quad
+\begin{tabular}{l@{\quad$\rightarrow$\quad}p{9cm}}
+string & assign* \\
+assign & whitespace* \\
+assign & whitespace* key whitespace* = whitespace* value delimiter \\
+key & any string not containing \verb|'/'| or \verb|'='| or whitespace\\
+value & array $\big|$ int\_value $\big|$ real\_value $\big|$ string\_value\\
+array & \{ int\_value* \} $\big|$ \{ real\_value \} \\
+int\_value & anything recognized as a valid integer by strdol(3)
+ in base 10 \\
+real\_value & anything not recognized as a valid integer by strtol(3)
+ but recognized as valid by strdod(3) \\
+string\_value & a C-style string enclosed in "double quotes"
+ (C-style character escape codes are allowed
+ ie. bell~(\verb|'\a'|), backspace~(\verb|'\b'|),
+ form-feed~(\verb|'\f'|), newline~(\verb|'\n'|),
+ carriage-return~(\verb|'\r'|), tab~(\verb|'\t'|),
+ vertical-tab~(\verb|'\v'|), backslash~(\verb|'\\'|),
+ single-quote~(\verb|'\''|), double-quote~(\verb|'\"'|),
+ question-mark~(\verb|'\?'|)) \\
+string\_value & a C-style string enclosed in 'single quotes'
+ (C-style character escape codes are {\bf not} allowed,
+ ie. every character within the string is interpreted
+ literally) \\
+delimiter & end-of-string $\big|$ whitespace \\
+whitespace & blank~(\verb|' '|)
+ $\big|$ tab~(\verb|'\t'|)
+ $\big|$ newline~(\verb|'\n'|)
+ $\big|$ carriage-return~(\verb|'\r'|)
+ $\big|$ form-feed~(\verb|'\f'|)
+ $\big|$ vertical-tab~(\verb|'\v'|) %%%\\
+\end{tabular}\\
+where * denotes 0 or more repetitions and $\big|$ denotes logical or.
+
+Notice also that the keys allowed by this function are somewhat more
+restricted than those allowed by the other \verb|Util_TableSet*()|
+functions, in that this function disallows keys containing \verb|'='|
+and/or whitespace.
+
+If any error code is returned, assignments lexicographically earlier
+in the input string than where the error was detected will already
+have been made in the table. Unfortunately, there is no easy way to
+find out where the error was detected. :(
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_KEY}
+invalid input: key contains invalid character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_BAD\_INPUT}
+invalid input: can't parse input string
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MIXED\_TYPE\_ARRAY}
+invalid input: different array values have different datatypes
+\end{Error}
+\begin{Error}{\rm other error codes}
+this function may also return any error codes returned by
+\verb|Util_TableSetString()|, \verb|Util_TableSetInt()|,
+\verb|Util_TableSetReal()|, \verb|Util_TableSetIntArray()|,
+or \verb|Util_TableSetRealArray()|.
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+/* suppose we have a table referred to by handle */
+
+/* then the call... */
+int count = Util_TableSetFromString(handle, "n = 6\t"
+ "dx = 4.0e-5\t"
+ "pi = 3.1\t"
+ "s = 'my string'\t"
+ "array = { 1 2 3 }");
+/* ... will return count=5 ... */
+
+/* ... and is otherwise equivalent to the five calls ... */
+CCTK_INT array[] = {1, 2, 3};
+
+Util_TableSetInt(handle, 6, "n");
+Util_TableSetReal(handle, 4.0e-5, "dx");
+Util_TableSetReal(handle, 3.1, "pi");
+Util_TableSetString(handle, "my string", "s");
+Util_TableSetIntArray(handle, 3, array, "array");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableSetGeneric}
+\label{Util-TableSetGeneric}
+Set the value associated with a specified key to be a specified
+single (1-element array) value, whose data type is generic. That
+is, the value is specified by a \verb|CCTK_VARIABLE_|* type code
+and a \verb|void *| pointer.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableSetGeneric(int handle,
+ int type_code, const void *value,
+ const char *key);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableSetGeneric(status, handle, type_code, value, key)
+integer status, handle, type_code
+CCTK_POINTER value
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+ok (key was already in table before this call, old value was replaced)\\
+ (it doesn't matter what the old value's \verb|type_code| and
+ \verb|N_elements| were, \ie{} these do {\em not\/} have to match
+ the new value)
+\end{Result}
+\begin{Result}{\rm 0}
+ok (key was not in table before this call)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{type\_code}
+the array elements' type code
+(one of the \verb|CCTK_VARIABLE_|* constants from \verb|"cctk_Constants.h"|)
+\end{Parameter}
+\begin{Parameter}{value\_ptr}
+a pointer to the value to be associated with the key
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The key may be any C character string which does not contain a slash
+character (\verb|'/'|).
+
+The value is stored as a 1-element array.
+
+This function invalidates any iterators for the table which are
+not in the ``null-pointer'' state.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_Table.h"
+#include "cctk_Constants.h"
+
+const CCTK_INT i = 42;
+const void *iptr = (void *) &i;
+CCTK_INT icopy;
+
+const CCTK_REAL x = 299792458.0;
+const void *xptr = (void *) &x;
+CCTK_REAL xcopy;
+
+const int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetGeneric(handle, CCTK_VARIABLE_INT, iptr, "the answer");
+Util_TableSetGeneric(handle, CCTK_VARIABLE_REAL, xptr, "speed of light");
+
+/* gets icopy to 42 */
+Util_TableGetInt(handle, &icopy, "the answer");
+
+/* gets xcopy to 299792458.0 */
+Util_TableGetReal(handle, &xcopy, "speed of light");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableSetGenericArray}
+\label{Util-TableSetGenericArray}
+Set the value associated with a specified key to be a copy of a
+specified array, whose data type is generic. That is, the array
+is specified by a \verb|CCTK_VARIABLE_|* type code, a count of
+the number of array elements, and a \verb|void *| pointer.
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableSetGenericArray(int handle,
+ int type_code,
+ int N_elements, const void *array,
+ const char *key);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableSetGenericArray(status,
+. handle,
+. type_code,
+. N_elements, array,
+. key)
+integer status, handle, type_code, N_elements
+CCTK_POINTER(*) array
+character*(*) key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{Result}{\rm 1}
+ok (key was already in table before this call, old value was replaced)\\
+ (it doesn't matter what the old value's \verb|type_code| and
+ \verb|N_elements| were, \ie{} these do {\em not\/} have to match
+ the new value)
+\end{Result}
+\begin{Result}{\rm 0}
+ok (key was not in table before this call)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{type\_code}
+the array elements' type code
+(one of the \verb|CCTK_VARIABLE_|* constants from \verb|"cctk_Constants.h"|)
+\end{Parameter}
+\begin{Parameter}{N\_elements ($\ge 0$)}
+the number of array elements in \verb|array[]|
+\end{Parameter}
+\begin{Parameter}{value\_ptr}
+a pointer to the value to be associated with the key
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The key may be any C character string which does not contain a slash
+character (\verb|'/'|).
+
+The value is stored as a 1-element array.
+
+This function invalidates any iterators for the table which are
+not in the ``null-pointer'' state.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetFromString()}
+convenience routine to set key/value entries in a table based on a
+parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetString()}
+set a character-string value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_Table.h"
+#include "cctk_Constants.h"
+
+#define N_IARRAY 3
+const CCTK_INT iarray[N_IARRAY] = {42, 69, 105};
+const void *iarray_ptr = (void *) iarray;
+CCTK_INT iarray2[N_IARRAY];
+
+#define N_XARRAY 2
+const CCTK_REAL xarray[N_XARRAY] = {6.67e-11, 299792458.0};
+const void *xarray_ptr = (void *) xarray;
+CCTK_REAL xarray2[N_XARRAY];
+
+const int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetGenericArray(handle,
+ CCTK_VARIABLE_INT,
+ N_IARRAY, iarray_ptr,
+ "my integer array");
+Util_TableSetGenericArray(handle,
+ CCTK_VARIABLE_REAL,
+ N_XARRAY, xarray_ptr,
+ "my real array");
+
+/* gets iarray2[0] = 42, iarray2[1] = 69, iarray2[2] = 105 */
+Util_TableGetIntArray(handle, N_IARRAY, iarray2, "my integer array");
+
+/* gets xarray2[0] = 6.67e-11, xarray2[1] = 299792458.0 */
+Util_TableGetRealArray(handle, N_XARRAY, xarray2, "my real array");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{FunctionDescription}{Util\_TableSetString}
+\label{Util-TableSetString}
+Sets the value associated with a specified key in a table, to be
+a copy of a specified C-style null-terminated character string
+
+\begin{SynopsisSection}
+\begin{Synopsis}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+int status = Util_TableSetString(int handle,
+ const char *string,
+ const char *key);
+\end{verbatim}
+\end{Synopsis}
+\begin{Synopsis}{Fortran}
+\begin{verbatim}
+call Util_TableSetString(status, handle, string, key)
+integer status, handle
+character*(*) string, key
+\end{verbatim}
+\end{Synopsis}
+\end{SynopsisSection}
+
+\begin{ResultSection}
+\begin{ResultNote}
+Results are the same as all the other \verb|Util_TableSet|* functions:
+\end{ResultNote}
+\begin{Result}{\rm 1}
+ok (key was already in table before this call, old value was replaced)\\
+ (it doesn't matter what the old value's \verb|type_code| and
+ \verb|N_elements| were, \ie{} these do {\em not\/} have to match
+ the new value)
+\end{Result}
+\begin{Result}{\rm 0}
+ok (key was not in table before this call)
+\end{Result}
+\end{ResultSection}
+
+\begin{ParameterSection}
+\begin{Parameter}{handle ($\ge 0$)}
+handle to the table
+\end{Parameter}
+\begin{Parameter}{string}
+a pointer to the string (a C-style null-terminated string)
+\end{Parameter}
+\begin{Parameter}{key}
+a pointer to the key (a C-style null-terminated string)
+\end{Parameter}
+\end{ParameterSection}
+
+\begin{Discussion}
+The key may be any C character string which does not contain a slash
+character (\verb|'/'|).
+
+The string is stored as an array of \verb|strlen(string)|
+\verb|CCTK_CHAR|s. It does {\em not\/} include a terminating
+null character.
+
+This function is very similar to \verb|Util_TableSetCharArray()|.
+
+This function invalidates any iterators for the table which are
+not in the ``null-pointer'' state.
+\end{Discussion}
+
+\begin{SeeAlsoSection}
+\begin{SeeAlso}{Util\_TableCreateFromString()}
+convenience routine to create a table and set key/value entries
+in it based on a parameter-file--like character string
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*()}
+get a single (1-element array) value,
+or more generally the first array element of an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*Array()}
+get an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGeneric()}
+get a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGetGenericArray()}
+get an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableGet*String()}
+get a character-string value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetCharArray()}
+get an array-of-\verb|CCTK_CHAR| value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*()}
+set a single (1-element array) value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSet*Array()}
+set an array value
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGeneric()}
+set a single (1-element array) value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetGenericArray()}
+set an array value with generic data type
+\end{SeeAlso}
+\begin{SeeAlso}{Util\_TableSetCharArray()}
+set an array-of-\verb|CCTK_CHAR| value
+\end{SeeAlso}
+\end{SeeAlsoSection}
+
+\begin{ErrorSection}
+\begin{Error}{UTIL\_ERROR\_BAD\_HANDLE}
+handle is invalid
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_TABLE\_BAD\_KEY}
+key contains '/' character
+\end{Error}
+\begin{Error}{UTIL\_ERROR\_NO\_MEMORY}
+unable to allocate memory
+\end{Error}
+\end{ErrorSection}
+
+\begin{ExampleSection}
+\begin{Example}{C}
+\begin{verbatim}
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+static const CCTK_CHAR array[]
+ = {'r', 'e', 'l', 'a', 't', 'i', 'v', 'i', 't', 'y'};
+#define N_ARRAY (sizeof(array) / sizeof(array[0]))
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+
+Util_TableSetString(handle, "relativity", "Einstein");
+
+/* this produces the same table entry as the Util_TableSetString() */
+Util_TableSetCharArray(handle, N_ARRAY, array, "Einstein");
+\end{verbatim}
+\end{Example}
+\end{ExampleSection}
+\end{FunctionDescription}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{cactuspart}
diff --git a/doc/ReferenceManual/Preface.tex b/doc/ReferenceManual/Preface.tex
new file mode 100644
index 00000000..1e4b0e8a
--- /dev/null
+++ b/doc/ReferenceManual/Preface.tex
@@ -0,0 +1,111 @@
+% /*@@
+% @file Preface.tex
+% @date Sun Jul 20 11:41:11 CEST 2003
+% @author Jonathan Thornburg, borrowing heavily from the
+% Preface for the Cactus User's Guide
+% @desc
+% Preface for the Cactus Reference Manual
+% @enddesc
+% @version $Header$
+% @@*/
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+{\large \bf Preface}
+\label{sec:pr}
+
+\vskip .5cm
+
+This document will eventually be a complete reference manual for
+the Cactus Code. However, it is currently under
+development, so please be patient if you can't find what you need.
+Please report omissions, errors, or suggestions to
+and of our contact addresses below, and we will
+try and fix them as soon as possible.
+
+\vskip .5cm
+
+{\bf Overview of documentation}
+
+\vskip .5cm
+
+This guide covers the following topics
+
+\begin{Lentry}
+
+\item [{\bf Part~\ref{part:FunctionReference}: Function Reference.}]
+ Here all Cactus flesh functions which are available to
+ thorn writers in C and/or Fortran are described.
+
+\item [\bf Part~\ref{part:Appendices}: Appendices.]
+ These contain a description of the Cactus Configuration Language,
+ a glossary,
+ and other odds and ends, such as how to use GNATS or TAGS.
+
+\end{Lentry}
+
+Other topics to be discussed in separate documents include:
+
+\begin{Lentry}
+
+\item [{\bf Users' Guide}] This gives a general overview of the
+ Cactus Computational Tool Kit, including overall design/architecture,
+ how to get/configure/compile/run it, and general discussions of the
+ how to program in Cactus.
+
+\item [{\bf Relativity Thorn Guide}] This will contain details about the arrangements and thorns making up the Cactus Relativity Tool Kit, one of the major
+ motivators, and still the driving force, for the Cactus Code.
+
+\item [{\bf Flesh Maintainers Guide}]
+ This will contain all the gruesome details
+ about the inner workings of Cactus, for all those who want or need to
+ expand or maintain the core of Cactus.
+
+\end{Lentry}
+
+\vskip .5cm
+
+{\bf Typographical Conventions}
+
+\begin{Lentry}
+
+\item[{\tt Typewriter}] Is currently used for everything you type,
+ for program names, and code extracts.
+\item[{\tt < ... >}] Indicates a compulsory argument.
+\item[{\tt [ ... ]}] Indicates an optional argument.
+\item[{\tt |}] Indicates an exclusive or.
+
+\end{Lentry}
+
+\vskip .5cm
+
+{\bf How to Contact Us}
+
+\vskip .5cm
+
+Please let us know of any errors or omissions in this guide, as well
+as suggestions for future editions. These can be reported via our
+bug tracking system at {\tt www.cactuscode.org}, or via email to
+{\tt cactusmaint@cactuscode.org}. Alternatively, write to us at
+
+\vskip .5cm
+The Cactus Team\\
+Albert Einstein Institute\\
+Max Planck Institute for Gravitational Physics\\
+Am M\"{u}hlenberg 1\\
+D-14476 Golm\\
+Germany
+
+
+\vskip .5cm
+
+{\bf Acknowledgements}
+
+\vskip .5cm
+
+Hearty thanks to all those who have helped with documentation for the
+Cactus Code. Special thanks to those who struggled with the earliest
+sparse versions of this guide and sent in mistakes and suggestions,
+in particular John Baker, Carsten Gundlach, Ginny Hudak-David,
+Sai Iyer, Paul Lamping, Nancy Tran and Ed Seidel.
diff --git a/doc/ReferenceManual/ReferenceManual.tex b/doc/ReferenceManual/ReferenceManual.tex
new file mode 100644
index 00000000..446221f4
--- /dev/null
+++ b/doc/ReferenceManual/ReferenceManual.tex
@@ -0,0 +1,89 @@
+% /*@@
+% @file ReferenceManual.tex
+% @date Sun Jul 20 11:37:03 CEST 2003
+% @author Jonathan Thornburg, borrowing latex source from
+% the Cactus Users' Guide which was contributed by
+% many people
+% @desc
+% Main file for the Cactus Reference Manual
+% @enddesc
+% @version $Header$
+% @@*/
+
+\documentclass{report}
+
+\usepackage[
+pdfauthor={Gabrielle Allen, Tom Goodale, Gerd Lanfermann, Thomas Radke, David Rideout, Jonathan Thornburg},
+pdftitle={Cactus Reference Manual},
+pdfpagelabels,
+pdfstartview=FitV,
+hypertexnames=false,
+plainpages=false,
+colorlinks=true,
+linkcolor=blue,
+citecolor=blue,
+urlcolor=blue
+]{hyperref}
+
+
+
+% This must come after most of the other \usepackages, because we
+% might want to pass options to them
+\usepackage{../latex/cactus}
+
+
+
+\usepackage{tocloft}
+\addtolength{\cftchapnumwidth}{0.5em}
+\addtolength{\cftsecnumwidth}{0.5em}
+\addtolength{\cftsubsecnumwidth}{0.5em}
+\addtolength{\cftsubsubsecnumwidth}{0.5em}
+
+\makeatletter
+\@addtoreset{chapter}{part}
+\makeatother
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{document}
+
+\cactustitlepage{Reference Manual}{$ $Revision$ $}{$ $Date$ $}
+
+\setcounter{page}{1}
+
+% Table of contents
+\pagenumbering{roman}
+
+\tableofcontents
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\renewcommand{\thepart}{\BigAlph{part}}
+\renewcommand{\thechapter}{\BigAlph{part}\arabic{chapter}}
+\renewcommand{\thepage}{\BigAlph{part}\arabic{page}}
+\pagestyle{fancy}
+\parskip = 10 pt
+\parindent = 0pt
+
+\newpage
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\input Preface.tex
+
+\input FunctionReference.tex
+
+\input ../UsersGuide/Appendices.tex
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{document}