aboutsummaryrefslogtreecommitdiff
path: root/doc/documentation.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/documentation.tex')
-rw-r--r--doc/documentation.tex529
1 files changed, 516 insertions, 13 deletions
diff --git a/doc/documentation.tex b/doc/documentation.tex
index 5376ec6..33cad43 100644
--- a/doc/documentation.tex
+++ b/doc/documentation.tex
@@ -8,8 +8,8 @@
\begin{document}
-\title{SpaceMask}
-\author{Tom Goodale}
+\title{Using SpaceMask}
+\author{Denis Pollney}
\date{$ $Date$ $}
\maketitle
@@ -18,25 +18,528 @@
% START CACTUS THORNGUIDE
\begin{abstract}
-Provides a mask function for the spatial slice variables
+The SpaceMask thorn provides a grid function which can be used to
+store user-defined states at each grid point. Routines are provided
+for quickly setting and checking the mask states.
\end{abstract}
-\section{Purpose}
+\section{The mask bit-field}
-This will provide two integer grid functions
+The mask is a grid function which can be used to assign a state to
+each point on the grid. It is used as a bit field, with different
+bits, or combinations of bits, assigned to represent various states.
+The mask is currently implemented as a CCTK\_INT8 grid function,
+providing 64 bits per point. Appropriate numbers of bits within
+the mask can be allocated to represent individual states of
+a given type.
-space\_mask
-space\_table\_field
+For instance, a programmer wants to record whether each point of the
+grid has \emph{state} ``interior'', ``excised'' or ``boundary''. The
+collection of these states is called a \emph{type}, and 2-bits of the
+mask (enough to represent the three possible states of the type) are
+allocated to hold this information. If an independent classification
+of points (ie. a new type) is required, bits are allocated to it from
+the remaining free bits in the mask. (See Figure \ref{fig:mask_bits}.)
-the first one will be a bitmask describing the point, with one bit
-indicating that there is extra data in a table the handle of which can be
-found in the corresponding point in the space\_table\_field.
+The SpaceMask thorn provides a set of routines for allocating bits
+within the mask, and for setting and checking the mask state at
+individual points.
-Thorns interested in the mask should inherit from this implementation.
+\begin{figure}
+ \centering
+ \includegraphics{space_mask.eps}
+ \caption{The \texttt{SpaceMask\_RegisterType()} function allocates
+ bits of the mask to a new ``type'' (eg. ``excision'' and ``colour''
+ in the figure). The number of bits that are allocated is determined
+ by the number of possible states of the given type.}
+ \label{fig:mask_bits}
+\end{figure}
-There may also be aliased query functions provided.
+\section{Using the mask}
-\section{Comments}
+A number of functions are provided for registering new types, and
+checking and setting mask values at a point. The interface to these
+functions differs slightly for C and Fortran90 code.
+
+\subsection{Accessing the mask from C Code}
+
+The following description describes the C interface for manipulating
+the mask. An example of code using these functions can be found in
+Appendix \ref{app:eg_C}.
+
+\subsubsection{Registering a new type}\label{sec:reg_C}
+
+Bits of the mask are allocated to a new type using the function:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+int SpaceMask\_RegisterType(char* \emph{type\_name}, int \emph{nstates},
+ char** \emph{state\_list})
+}
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{type\_name}] The name of the new type to be registered;
+ \item[\emph{nstates}] The number of states in the new type;
+ \item[\emph{state\_list}] A list of names, one for each state.
+\end{description}
+}
+}
+
+\noindent An appropriate number of bits of the mask are allocated to
+hold a unique value for the $n$ states specified by the \emph{nstates}
+argument. The registration must take place before the type can be
+used, so for instance, could be scheduled at CCTK\_STARTUP. New
+states can be added to an already allocated type using the function:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+ int SpaceMask\_AppendStatesToType(char* \emph{type\_name},
+ int \emph{nstates}, char** \emph{state\_list})
+}
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{type\_name}] The name of an already registered type;
+ \item[\emph{nstates}] The number of states to be added;
+ \item[\emph{state\_list}] A list of names, one for each of the new
+ states.
+\end{description}
+}}
+
+\noindent A number of new bits will be added to the specified type
+appropriate to hold the number of existing states plus the extra
+states. The allocated bits need not be contiguous within the mask.
+
+\subsubsection{Setting and checking mask states}
+
+The state of the mask at a given point is set using the function:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+void SpaceMask\_SetState(CCTK\_INT8* \emph{mask}, int \emph{point},
+ char* \emph{type\_name}, char* \emph{state})
+}
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{mask}] A pointer to the mask grid function;
+ \item[\emph{point}] The index of the point within the grid function
+ array;
+ \item[\emph{type\_name}] The name of the type containing the state;
+ \item[\emph{state\_name}] The particular state to be set.
+\end{description}
+}}
+
+The state of the mask at a given point can be checked using:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+int SpaceMask\_CheckState(CCTK\_INT8* \emph{mask}, int \emph{point},
+ char* \emph{type\_name}, char* \emph{state})
+}
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{mask}] A pointer to the mask grid function;
+ \item[\emph{point}] The index of the point within the grid function
+ array;
+ \item[\emph{type\_name}] The name of the type containing the state;
+ \item[\emph{state\_name}] The particular state to be compared.
+\end{description}
+}}
+
+The return value is 1 if the given \emph{state\_name} has been set at
+the point, or 0 otherwise.
+
+\subsubsection{Faster bitwise operators}
+
+The above mentioned functions for checking and setting the mask are
+rather inefficient, since they require strings to be compared at each
+point. A set of faster macros are provided which operate on the mask
+by performing bit operations directly. In order to use these
+functions, the bitmasks corresponding to the desired type and it's
+states need to be obtained using the following functions:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+CCTK\_INT8 SpaceMask\_GetTypeBits(char* \emph{type\_name})
+}\\
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{type\_name}] The type for which the bitmask is to be
+ determined.
+\end{description}
+}}
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+CCTK\_INT8 SpaceMask\_GetStateBits(char* \emph{type\_name},
+ char* \emph{state\_name})
+}
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{type\_name}] The type containing the state in question;
+ \item[\emph{state\_name}] The state whose bitmask is to be determined.
+\end{description}
+}}
+
+\noindent Each of these functions returns a CCTK\_INT which holds the
+bitmask corresponding to the given type or state. For example, if a
+given type uses three bits of the mask, the returned value could be
+the integer corresponding to the bitfield 001110000\ldots, where the
+location of 1s indicates the bits which have been allocated to the
+given type.
+
+The following macros have been defined for fast setting and checking
+of the mask by direct bitwise operations:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+void SpaceMask\_SetStateBits(CCTK\_INT8* \emph{mask}, int \emph{point},
+ CCTK\_INT8 \emph{type\_bits},\\\hspace*{10mm} CCTK\_INT8 \emph{state\_bits})
+}\\
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{mask}] A pointer to the mask grid function;
+ \item[\emph{point}] The index of the point within the grid function
+ array;
+ \item[\emph{type\_bits}] The bitmask corresponding to the required
+ type;
+ \item[\emph{state\_bits}] The bitmask corrsponding to the required
+ state;
+\end{description}
+}}
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+int SpaceMask\_CheckStateBits(CCTK\_INT8* \emph{mask}, int \emph{point},
+ CCTK\_INT8 \emph{type\_bits},\\\hspace*{10mm} CCTK\_INT8 \emph{state\_bits})
+}\\
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{mask}] A pointer to the mask grid function;
+ \item[\emph{point}] The index of the point within the grid function
+ array;
+ \item[\emph{type\_bits}] The bitmask corresponding to the required
+ type;
+ \item[\emph{state\_bits}] The bitmask corrsponding to the required
+ state;
+\end{description}
+}}
+
+\noindent The latter macro returns a 1 if the given state has been
+set, a 0 otherwise. The \emph{type\_bits} and \emph{state\_bits} can
+be obtained using the \texttt{SpaceMask\_Get*Bits} functions,
+described above.
+
+\subsection{Accessing the mask from Fortran90 Code}
+
+The following Fortran interfaces to the mask utilities apply only to
+Fortran90 code, since fast bitwise operations are not a part of the
+Fortran77 standard. An example of the use of the Fortran90 interface
+can be found in Appendix \ref{app:eg_F90}.
+
+\subsubsection{Registering a new type}
+
+Registration functions have not been implemented for the Fortran90
+interface, though they can easily be written in C by following the
+descriptions in Section \ref{sec:reg_C} and the example in Appendix
+\ref{app:eg_C}.
+
+\subsubsection{Setting and checking mask states}
+
+The mask states can be manipulated using the following functions:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+ SpaceMask\_SetState(CCTK\_INT8 \emph{mask(,,)}, int \emph{point},
+ character \emph{type\_name},\\\hspace*{10mm} character \emph{state\_name})
+}\\
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{mask}] A pointer to the mask grid function;
+ \item[\emph{point}] The index of the point within the grid function
+ array;
+ \item[\emph{type\_name}] The name of the type containing the state;
+ type;
+ \item[\emph{state\_name}] The name of the state to be set.
+\end{description}
+}}
+
+\noindent The value of the \emph{mask} variable is changed to turn on
+the specified state at the point.
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+ SpaceMask\_CheckState(CCTK\_INT \emph{check}, CCTK\_INT8 \emph{mask(,,)},
+ int \emph{point},\\\hspace*{10mm} character \emph{type\_name},
+ character \emph{state\_name})
+}\\
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{check}] A variable which is set to 1 if the requested
+ state has been set;
+ \item[\emph{mask}] A pointer to the mask grid function;
+ \item[\emph{point}] The index of the point within the grid function
+ array;
+ \item[\emph{type\_name}] The name of the type containing the state;
+ type;
+ \item[\emph{state\_name}] The name of the state to be checked.
+\end{description}
+}}
+
+\subsubsection{Faster bitwise operators}
+
+As in the C interface, alternative bitwise operators have been defined
+in order to more quickly operate on the mask at a point. In order to
+use these functions, the bitmasks corresponding to the type and states
+in question must first be obtained using the following functions:
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+ SpaceMask\_GetTypeBits(CCTK\_INT8 \emph{type\_bits},
+ character \emph{type\_name})
+}
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{type\_bits}] A variable which will be set to the bitmask of
+ the requested type;
+ \item[\emph{type\_name}] A character string naming the type.
+\end{description}
+}}
+
+\indent\parbox{\linewidth}{
+\vspace{\baselineskip}\noindent\texttt{
+ SpaceMask\_GetStateBits(CCTK\_INT8 \emph{state\_bits},
+ character \emph{type\_name},\\\hspace*{10mm} character \emph{state\_name})
+}\\
+\hspace*{10mm}\parbox{\linewidth}{
+\begin{description}
+ \item[\emph{state\_bits}] A variable which will be set to the bitmask of
+ the requested state;
+ \item[\emph{type\_name}] A character string naming the type
+ containing the state;
+ \item[\emph{type\_name}] A character string naming the state.
+\end{description}
+}}
+
+\noindent Once the bitmasks for the type and state have been obtained,
+the following macros can be used directly:
+
+\vspace{\baselineskip}\noindent\texttt{
+ SpaceMask\_SetStateBitsF90(mask, i, j, k, type\_bits, state\_bits)
+}\\
+
+\noindent This macro sets the value of the mask at the index $(i,j,k)$
+to the given state. It doesn't have a return value, and can be used
+directly inline (without a Fortran `call').
+
+\vspace{\baselineskip}\noindent\texttt{
+ SpaceMask\_CheckStateBitsF90(mask, i, j, k, type\_bits, state\_bits)
+}\\
+
+\noindent A value of `\texttt{.true.}' is returned if the given state
+has been set, or `\texttt{.false.}' otherwise. The macro can be used
+directly in Fortran boolean expressions, as in the examples in
+Appendix \ref{app:eg_F90}.
+
+
+\section{Notes}
+
+A proposal exists to provide a more versatile solution by allowing
+tables to be associated with each grid point. This could be
+implemented using the existing standard outlined here through the
+addition of an additional integer grid function
+
+\texttt{space\_table\_field}
+
+A bit of the existing \texttt{space\_mask} would be allocated to
+indicate whether or not a table has been associated with the given
+point. If so, then the corresponding point in the
+\texttt{space\_table\_field} would hold the table handle.
+
+
+\section{Acknowledgements}
+
+Thanks to Jonathan Thornburg, Tom Goodale, and Erik Schnetter for
+helpful comments on the original specification. Useful implementation
+of the mask required grid symmetries to work for integer grid
+functions. This was done by Thomas Radke. Peter Diener helped with the
+coding of the Fortran90 bitwise operators.
+
+\pagebreak
+\appendix
+\section{Example: C code}\label{app:eg_C}
+
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "SpaceMask.h"
+
+/*
+ * Register a mask type with three states.
+ */
+void Eg_RegisterMask (void)
+{
+ char *state_list_excision[3] = {"normal", "excise", "boundary"};
+
+ SpaceMask_RegisterType("excision", 3, state_list_excision);
+
+ return;
+}
+
+/*
+ * Set the mask to the ``normal'' state at each point using the
+ * slower name-reference function. See below for an example using
+ * the faster bitwise operator to check the mask states.
+ */
+void Eg_SetMaskStates (CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ int i, j, k, ijk;
+
+ for (k=0; k<cctk_lsh[2]; ++k)
+ {
+ for (j=0; j<cctk_lsh[1]; ++j)
+ {
+ for (i=0; i<cctk_lsh[0]; ++i)
+ {
+ ijk = CCTK_GFINDEX3D(cctkGH, i, j, k);
+
+ SpaceMask_SetState(space_mask, ijk, \"excision\", \"normal\");
+ }
+ }
+ }
+ return;
+}
+
+/*
+ * Check which of the points of the mask have been set to the
+ * ``boundary'' state using the bitwise macro.
+ */
+void Eg_CheckMaskStates (CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ int i, j, k, ijk;
+
+ CCTK_INT8 excision_mask;
+ CCTK_INT8 boundary_mask;
+
+ excision_mask = SpaceMask_GetTypeBits(\"excision\");
+ boundary_mask = SpaceMask_GetStateBits(\"boundary\");
+
+ for (k=0; k<cctk_lsh[2]; ++k)
+ {
+ for (j=0; j<cctk_lsh[1]; ++j)
+ {
+ for (i=0; i<cctk_lsh[0]; ++i)
+ {
+ ijk = CCTK_GFINDEX3D(cctkGH, i, j, k);
+
+ if (SpaceMask_CheckStateBits(space_mask, ijk, excision_mask,
+ boundary_mask))
+ {
+ CCTK_VINFO(CCTK_THORNSTRING,
+ \"Point (%d,%d,%d) is a boundary point.\n\",
+ i, j, k);
+ }
+ }
+ }
+ }
+ return;
+}
+\end{verbatim}
+
+
+\section{Example: Fortran90 code}\label{app:eg_F90}
+
+\begin{verbatim}
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "SpaceMask.h"
+
+!
+! Sets each point of the mask to the 'normal' state. Here, 'normal'
+! is one of the states of the 'excision' type, which should have
+! been registered previously using the C SpaceMask_RegisterType()
+! function.
+!
+subroutine Eg_SetStateByName(CCTK_ARGUMENTS)
+ implicit none
+
+ integer ni, nj, nk
+ integer i, j, k, ijk
+
+ ni = cctk_lsh(1)
+ nj = cctk_lsh(2)
+ nk = cctk_lsh(3)
+
+ do k=1,nk
+ do j=1,nj
+ do i=1,ni
+
+ ijk = (i-1) + ni*((j-1) + nj*(k-1))
+
+ call SpaceMask_SetState(space_mask, ijk, "excision", "normal")
+
+ end do
+ end do
+ end do
+
+end subroutine Eg_SetStateByName
+
+!
+! Sets the mask values within a radius of 1 to the 'excise' state,
+! then does a check of the state of each point. The bitwise macros
+! are used in this case for greater efficiency in setting/checking
+! the mask.
+!
+subroutine Eg_SetExcisedRegionByBitmask(CCTK_ARGUMENTS)
+ implicit none
+
+ integer ni, nj, nk
+ integer i, j, k, ijk
+
+ CCTK_INT8 type_bits, excised
+
+ ni = cctk_lsh(1)
+ nj = cctk_lsh(2)
+ nk = cctk_lsh(3)
+
+ call SpaceMask_GetTypeBits(type_bits, "excision")
+ call SpaceMask_GetStateBits(excised, "excision", "excised")
+
+ do k=1,nk
+ do j=1,nj
+ do i=1,ni
+
+ if (r(i,j,k).lt.1.d0) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bits, &
+ excised)
+ end if
+
+ end do
+ end do
+ end do
+
+ do k=1,nk
+ do j=1,nj
+ do i=1,ni
+ if (SpaceMask_CheckStateBitsF90(space_mask, i, j, k, type_bits, &
+ excised)) then
+ write(*,*) "The point (", i, j, k, ") has been excised."
+ end if
+ end do
+ end do
+ end do
+
+end subroutine Eg_SetExcisedRegionByBitmask
+\end{verbatim}
% Do not delete next line
% END CACTUS THORNGUIDE