diff options
-rw-r--r-- | README | 16 | ||||
-rw-r--r-- | doc/documentation.tex | 529 | ||||
-rw-r--r-- | doc/space_mask.eps | 203 | ||||
-rw-r--r-- | doc/space_mask.fig | 68 | ||||
-rw-r--r-- | interface.ccl | 17 | ||||
-rw-r--r-- | schedule.ccl | 27 | ||||
-rw-r--r-- | src/MaskInit.c | 94 | ||||
-rw-r--r-- | src/MaskUtils.c | 496 | ||||
-rw-r--r-- | src/SpaceMask.h | 113 | ||||
-rw-r--r-- | src/make.code.defn | 2 |
10 files changed, 1521 insertions, 44 deletions
@@ -1,19 +1,9 @@ Cactus Code Thorn SpaceMask -Authors : Tom Goodale +Authors : Denis Pollney CVS info : $Header$ -------------------------------------------------------------------------- Purpose of the thorn: -This will provide two integer grid functions - -space_mask -space_table_field - -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. - -Thorns interested in the mask should inherit from this implementation. - -There may also be aliased query functions provided. +Provides utilities for assigning states to individual grid points +using a mask grid function. 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 diff --git a/doc/space_mask.eps b/doc/space_mask.eps new file mode 100644 index 0000000..a9b2c62 --- /dev/null +++ b/doc/space_mask.eps @@ -0,0 +1,203 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: space_mask.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3d +%%CreationDate: Thu Nov 14 11:23:42 2002 +%%For: dp@nbdell15 (Denis Pollney,,,) +%%BoundingBox: 0 0 400 242 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 242 moveto 0 0 lineto 400 0 lineto 400 242 lineto closepath clip newpath +-55.3 491.8 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06299 0.06299 sc +% +% Fig objects follow +% +% Polyline +15.000 slw +n 7200 4275 m 900 4275 l 900 4725 l + 7200 4725 l gs col0 s gr +% Polyline +n 900 4275 m 1350 4275 l 1350 4725 l 900 4725 l + cp gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 1350 4275 m 1800 4275 l 1800 4725 l 1350 4725 l + cp gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 1800 4275 m 2250 4275 l 2250 4725 l 1800 4725 l + cp gs col3 1.00 shd ef gr gs col0 s gr +% Polyline +n 2250 4275 m 2700 4275 l 2700 4725 l 2250 4725 l + cp gs col3 1.00 shd ef gr gs col0 s gr +% Polyline +n 2700 4275 m 3150 4275 l 3150 4725 l 2700 4725 l + cp gs col3 1.00 shd ef gr gs col0 s gr +% Polyline +n 3150 4275 m 3600 4275 l 3600 4725 l 3150 4725 l + cp gs col0 s gr +% Polyline +n 3600 4275 m 4050 4275 l 4050 4725 l 3600 4725 l + cp gs col0 s gr +% Polyline +n 4050 4275 m 4500 4275 l 4500 4725 l 4050 4725 l + cp gs col0 s gr +% Polyline +n 4500 4275 m 4950 4275 l 4950 4725 l 4500 4725 l + cp gs col0 s gr +% Polyline +n 4950 4275 m 5400 4275 l 5400 4725 l 4950 4725 l + cp gs col0 s gr +% Polyline +n 5400 4275 m 5850 4275 l 5850 4725 l 5400 4725 l + cp gs col0 s gr +% Polyline +n 5850 4275 m 6300 4275 l 6300 4725 l 5850 4725 l + cp gs col0 s gr +% Polyline +n 6300 4275 m 6750 4275 l 6750 4725 l 6300 4725 l + cp gs col0 s gr +% Polyline +n 1485 5535 m 3420 5535 l 3420 6885 l 1485 6885 l + cp gs col0 s gr +% Polyline +n 4140 5535 m 6030 5535 l 6030 7785 l 4140 7785 l + cp gs col0 s gr +% Polyline +n 1125 4725 m 1125 4950 l + 1575 4950 l gs col0 s gr +% Polyline +n 1575 4725 m + 1575 5535 l gs col0 s gr +% Polyline +n 2025 4725 m 2025 4950 l 4230 4950 l + 4230 5535 l gs col0 s gr +% Polyline +n 2475 4725 m + 2475 4950 l gs col0 s gr +% Polyline +n 2925 4725 m + 2925 4950 l gs col0 s gr +% Polyline +n 1485 5535 m 3420 5535 l 3420 5940 l 1485 5940 l + cp gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 4140 5535 m 6030 5535 l 6030 5895 l 4140 5895 l + cp gs col3 1.00 shd ef gr gs col0 s gr +/Helvetica-Bold ff 210.00 scf sf +1575 6165 m +gs 1 -1 sc (00 = "normal") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +1575 6420 m +gs 1 -1 sc (01 = "excised") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +1575 6705 m +gs 1 -1 sc (10 = "boundary") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 6165 m +gs 1 -1 sc (000 = "black") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 6420 m +gs 1 -1 sc (001 = "red") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 6675 m +gs 1 -1 sc (010 = "blue") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 6930 m +gs 1 -1 sc (011 = "green") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 7185 m +gs 1 -1 sc (100 = "yellow") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 7440 m +gs 1 -1 sc (101 = "orange") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 7695 m +gs 1 -1 sc (110 = "white") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +4275 5805 m +gs 1 -1 sc (type: "colour") col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +900 4140 m +gs 1 -1 sc (space_mask) col0 sh gr +/Helvetica-Bold ff 210.00 scf sf +1575 5805 m +gs 1 -1 sc (type: "excision") col0 sh gr +$F2psEnd +rs diff --git a/doc/space_mask.fig b/doc/space_mask.fig new file mode 100644 index 0000000..920d8ed --- /dev/null +++ b/doc/space_mask.fig @@ -0,0 +1,68 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 4 + 7200 4275 900 4275 900 4725 7200 4725 +2 2 0 2 0 6 50 0 20 0.000 0 0 -1 0 0 5 + 900 4275 1350 4275 1350 4725 900 4725 900 4275 +2 2 0 2 0 6 50 0 20 0.000 0 0 -1 0 0 5 + 1350 4275 1800 4275 1800 4725 1350 4725 1350 4275 +2 2 0 2 0 3 50 0 20 0.000 0 0 -1 0 0 5 + 1800 4275 2250 4275 2250 4725 1800 4725 1800 4275 +2 2 0 2 0 3 50 0 20 0.000 0 0 -1 0 0 5 + 2250 4275 2700 4275 2700 4725 2250 4725 2250 4275 +2 2 0 2 0 3 50 0 20 0.000 0 0 -1 0 0 5 + 2700 4275 3150 4275 3150 4725 2700 4725 2700 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 3150 4275 3600 4275 3600 4725 3150 4725 3150 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 3600 4275 4050 4275 4050 4725 3600 4725 3600 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 4050 4275 4500 4275 4500 4725 4050 4725 4050 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 4500 4275 4950 4275 4950 4725 4500 4725 4500 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 4950 4275 5400 4275 5400 4725 4950 4725 4950 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 5400 4275 5850 4275 5850 4725 5400 4725 5400 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 5850 4275 6300 4275 6300 4725 5850 4725 5850 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 6300 4275 6750 4275 6750 4725 6300 4725 6300 4275 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 1485 5535 3420 5535 3420 6885 1485 6885 1485 5535 +2 2 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 5 + 4140 5535 6030 5535 6030 7785 4140 7785 4140 5535 +2 1 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 3 + 1125 4725 1125 4950 1575 4950 +2 1 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 2 + 1575 4725 1575 5535 +2 1 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 4 + 2025 4725 2025 4950 4230 4950 4230 5535 +2 1 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 2 + 2475 4725 2475 4950 +2 1 0 2 0 6 50 0 -1 0.000 0 0 -1 0 0 2 + 2925 4725 2925 4950 +2 2 0 2 0 6 50 0 20 0.000 0 0 -1 0 0 5 + 1485 5535 3420 5535 3420 5940 1485 5940 1485 5535 +2 2 0 2 0 3 50 0 20 0.000 0 0 -1 0 0 5 + 4140 5535 6030 5535 6030 5895 4140 5895 4140 5535 +4 0 0 50 0 18 14 0.0000 4 165 1425 1575 6165 00 = "normal"\001 +4 0 0 50 0 18 14 0.0000 4 165 1485 1575 6420 01 = "excised"\001 +4 0 0 50 0 18 14 0.0000 4 210 1710 1575 6705 10 = "boundary"\001 +4 0 0 50 0 18 14 0.0000 4 165 1380 4275 6165 000 = "black"\001 +4 0 0 50 0 18 14 0.0000 4 165 1170 4275 6420 001 = "red"\001 +4 0 0 50 0 18 14 0.0000 4 165 1275 4275 6675 010 = "blue"\001 +4 0 0 50 0 18 14 0.0000 4 210 1425 4275 6930 011 = "green"\001 +4 0 0 50 0 18 14 0.0000 4 210 1470 4275 7185 100 = "yellow"\001 +4 0 0 50 0 18 14 0.0000 4 210 1560 4275 7440 101 = "orange"\001 +4 0 0 50 0 18 14 0.0000 4 165 1365 4275 7695 110 = "white"\001 +4 0 0 50 0 18 14 0.0000 4 210 1470 4275 5805 type: "colour"\001 +4 0 0 50 0 18 14 0.0000 4 210 1275 900 4140 space_mask\001 +4 0 0 50 0 18 14 0.0000 4 210 1650 1575 5805 type: "excision"\001 diff --git a/interface.ccl b/interface.ccl index 81fb75a..70433bd 100644 --- a/interface.ccl +++ b/interface.ccl @@ -8,14 +8,19 @@ USES INCLUDE: Symmetry.h public: +CCTK_INT8 space_mask_group type=GF +{ + space_mask +} + +# +# The following emask GF is kept for the sake of compatibility with +# the existing excision thorns. Once these are translated to the new +# mask, this function will disappear. Please don't use it for +# anything. +# real mask type = GF { emask } "Mask" -# Will be changed to: -#INTEGER spacemasks TYPE=GF -#{ -# space_mask -# space_table_field -#} diff --git a/schedule.ccl b/schedule.ccl index 9923239..68492fb 100644 --- a/schedule.ccl +++ b/schedule.ccl @@ -1,15 +1,34 @@ # Schedule definitions for thorn SpaceMask # $Header$ -if (use_mask) +if (use_mask) { - STORAGE: mask - schedule MaskOne at CCTK_INITIAL + STORAGE: space_mask_group + + schedule MaskZero at CCTK_INITIAL { LANG: C - } "Set mask to one" + } "Initialise mask to zero" + schedule MaskSym at CCTK_BASEGRID { LANG: C } "Set grid symmetries for mask" + + # + # The following is for compatibility with current excision routines, + # and will be removed once they are up-to-date with the new mask + # scheme. + # + STORAGE: mask + schedule MaskSym_emask at CCTK_BASEGRID + { + LANG: C + } "Set grid symmetries for mask" + + schedule MaskOne at CCTK_INITIAL + { + LANG: C + } "Set mask to one" + } diff --git a/src/MaskInit.c b/src/MaskInit.c index 50760dc..9436404 100644 --- a/src/MaskInit.c +++ b/src/MaskInit.c @@ -14,6 +14,7 @@ #include "cctk_Arguments.h" #include "Symmetry.h" +#include "SpaceMask.h" static const char *rcsid = "$Header$"; @@ -46,8 +47,61 @@ void MaskOne(CCTK_ARGUMENTS); ********************* External Routines ********************** ********************************************************************/ - /*@@ +/*@@ + @routine SetupSpaceMaskRegistry + @date November 2002 + @author Denis Pollney + @desc + Allocate and initialise the global spacemask registry. + @enddesc +@@*/ +void SetupSpaceMaskRegistry (void) +{ + SpaceMask_Registry* spacemask_registry; + + spacemask_registry = (SpaceMask_Registry*) malloc + (sizeof(SpaceMask_Registry)); + + spacemask_registry->ntypes=0; + spacemask_registry->type_list = NULL; + + return; +} + +/*@@ @routine MaskSym + @date October 2002 + @author Denis Pollney + @desc + Scheduled routine to set symmetries for mask + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +void MaskSym(CCTK_ARGUMENTS) +{ + DECLARE_CCTK_ARGUMENTS + + int one; + int sym[3]; + + one = 1; + + sym[0] = one; + sym[1] = one; + sym[2] = one; + + SetCartSymVN(cctkGH, sym, "spacemask::space_mask"); + + return; +} + +/*@@ + @routine MaskSym_emask @date Fri 3 May 2002 @author Gabrielle Allen @desc @@ -60,7 +114,7 @@ void MaskOne(CCTK_ARGUMENTS); @endhistory @@*/ -void MaskSym(CCTK_ARGUMENTS) +void MaskSym_emask(CCTK_ARGUMENTS) { DECLARE_CCTK_ARGUMENTS @@ -69,16 +123,16 @@ void MaskSym(CCTK_ARGUMENTS) one = 1; - sym[0] = one; - sym[1] = one; - sym[2] = one; + sym[0] = one; + sym[1] = one; + sym[2] = one; - SetCartSymVN(cctkGH, sym,"spacemask::emask"); + SetCartSymVN(cctkGH, sym, "spacemask::emask"); return; } - /*@@ +/*@@ @routine MaskOne @date @author Miguel Alcubierre @@ -105,6 +159,32 @@ void MaskOne(CCTK_ARGUMENTS) return; } +/*@@ + @routine MaskZero + @date + @author Denis Pollney + @desc + Initialise the mask to zero. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +void MaskZero(CCTK_ARGUMENTS) +{ + DECLARE_CCTK_ARGUMENTS + + int i; + + for(i = 0; i < cctk_lsh[0]*cctk_lsh[1]*cctk_lsh[2]; i++) + space_mask[i] = 0; + + return; +} + /******************************************************************** ********************* Local Routines ************************* ********************************************************************/ diff --git a/src/MaskUtils.c b/src/MaskUtils.c new file mode 100644 index 0000000..f8c5a75 --- /dev/null +++ b/src/MaskUtils.c @@ -0,0 +1,496 @@ +/*@@ + @file MaskUtils.c + @date October 2002 + @author Denis Pollney + @desc + Utilities for registering/setting/checking the mask. + @desc + @version $Header$ +@@*/ + +#include <stdio.h> + +#include "cctk.h" +#include "cctk_FortranString.h" + +#include "SpaceMask.h" + +static const char* rcsid = "$Header$"; + +CCTK_FILEVERSION(CACTUSEINSTEIN_SPACEMASK_MaskUtils_c); + +SpaceMask_Registry* spacemask_registry = NULL; + +/*@@ + @routine SpaceMask_get_bit_nbr + @author Denis Pollney + @date 15 October 2002 + @desc + Return the number of bits required to represent a given number. + Cheesy divide-by-two method, maybe something else is quicker. + @enddesc +@@*/ + +int +SpaceMask_get_bit_nbr(int nstates) +{ + int bstates; + int bit_nbr; + + bstates = nstates-1; + + for (bit_nbr=0; bstates>0; ++bit_nbr) + bstates /= 2; + + return bit_nbr; +} + +/*@@ + @routine SpaceMask_get_free_bits + @author Denis Pollney + @date 15 October 2002 + @desc + Determine the mask bits which have not yet been allocated. + The return value is a bitmask with the requested number of + free bits set to 1. If there are not enough free bits left + to satisfy the request, stop with an error. + @enddesc +@@*/ + +CCTK_INT8 +SpaceMask_get_free_bits(int nbits) +{ + CCTK_INT8 used_bits; + CCTK_INT8 new_bits; + int i; + int j; + int n; + + used_bits = 0; + if (spacemask_registry != NULL) + { + for (i=0; i<spacemask_registry->ntypes; ++i) + used_bits |= spacemask_registry->type_list[i]->bitmask; + } + + n=1; + new_bits = 0; + j = 0; + for (i=0; i<sizeof(CCTK_INT8)*8 & j<nbits; ++i) + { + if (!(n & used_bits)) + { + ++j; + new_bits |= n; + } + n *= 2; + } + + if (j<nbits) + CCTK_WARN (0, "Cannot allocate mask: Not enough free bits."); + + return new_bits; +} + +/*@@ + @routine SpaceMask_determine_state_mask + @author Denis Pollney + @date 15 October 2002 + @desc + Determine appropriate bitmasks to represent a number of + states, using the allocated bit mask. + That is, if allocated_bits is set to 00111000, then + the returned list of states are permutations of the three + non-zero (active) bits. + @enddesc +@@*/ + +CCTK_INT8* +SpaceMask_determine_state_mask(CCTK_INT8 allocated_bits, int nstates) +{ + CCTK_INT8* state_mask; + int n; + int bit; + int i; + int j; + + state_mask = + (CCTK_INT8*) malloc (nstates*sizeof(CCTK_INT8)); + + for (j=0; j<nstates; ++j) + state_mask[j] = 0; + + n=1; + bit=1; + + for (i=0; i<sizeof(CCTK_INT8)*8; ++i) + { + if (n & allocated_bits) + { + for (j=0; j<nstates; ++j) + { + if (bit & j) + state_mask[j] += n; + } + bit *= 2; + } + n *= 2; + } + + return state_mask; +} + +/*@@ + @routine SpaceMask_setup_new_state + @author Denis Pollney + @date 15 October 2002 + @desc + Allocate a new SpaceMask_State, giving it a name and + a bit mask. + @enddesc +@@*/ + +SpaceMask_State* +SpaceMask_setup_new_state(CCTK_INT8 state_mask, char* name) +{ + SpaceMask_State* new_state; + + new_state = (SpaceMask_State*) malloc (sizeof(SpaceMask_State)); + new_state->name = name; + new_state->bitmask = state_mask; + + return new_state; +} + +/*@@ + @routine SpaceMask_setup_new_type + @author Denis Pollney + @date 15 October 2002 + @desc + Allocate a new SpaceMask_Type. This involves allocating + a set of bits within the mask to the new type, and creating + appropriate bitmasks (using the allocated bits) for each of + the requested states. + @enddesc +@@*/ + +SpaceMask_Type* +SpaceMask_setup_new_type(CCTK_INT8 new_bits, char* type_name, + int nstates, char** state_list, + CCTK_INT8* state_mask) +{ + SpaceMask_Type* new_type; + int j; + + new_type = (SpaceMask_Type*) malloc (sizeof(SpaceMask_Type)); + new_type->bitmask = new_bits; + new_type->nstates = nstates; + new_type->name = type_name; + new_type->state_list = + (SpaceMask_State**) malloc (nstates*sizeof(SpaceMask_State*)); + + for (j=0; j<nstates; ++j) + new_type->state_list[j] = SpaceMask_setup_new_state(state_mask[j], + state_list[j]); + return new_type; +} + +/*@@ + @routine SpaceMask_append_type_to_registry + @author Denis Pollney + @date 15 October 2002 + @desc + Adds a new type to the spacemask_registry. + @enddesc +@@*/ + +void +SpaceMask_append_type_to_registry(SpaceMask_Type* new_type) +{ + SpaceMask_Type** new_type_list; + int ntypes; + int i; + + if (spacemask_registry == NULL) + { + spacemask_registry = + (SpaceMask_Registry*) malloc (sizeof(SpaceMask_Registry)); + ntypes = 1; + new_type_list = (SpaceMask_Type**) malloc (sizeof(SpaceMask_Type*)); + new_type_list[0] = new_type; + } + else + { + ntypes = spacemask_registry->ntypes + 1; + new_type_list = + (SpaceMask_Type**) malloc (ntypes*sizeof(SpaceMask_Type*)); + for (i=0; i<ntypes-1; ++i) + new_type_list[i] = spacemask_registry->type_list[i]; + new_type_list[ntypes-1] = new_type; + free(spacemask_registry->type_list); + } + + spacemask_registry->ntypes = ntypes; + spacemask_registry->type_list = new_type_list; +} + +/*@@ + @routine SpaceMask_RegisterType + @author Denis Pollney + @date 15 October 2002 + @desc + Allocates a set of bits of the SpaceMask to represent + a set of states of the named type. + @enddesc +@@*/ + +int +SpaceMask_RegisterType(char* type_name, int nstates, char** state_list) +{ + SpaceMask_Type* new_type; + CCTK_INT8 new_bits; + CCTK_INT8* state_mask; + int bit_nbr; + + bit_nbr = SpaceMask_get_bit_nbr(nstates); + new_bits = SpaceMask_get_free_bits(bit_nbr); + state_mask = SpaceMask_determine_state_mask(new_bits, nstates); + + new_type = SpaceMask_setup_new_type(new_bits, type_name, nstates, + state_list, state_mask); + + SpaceMask_append_type_to_registry (new_type); + + return 0; +} + +/*@@ + @routine SpaceMask_AppendStatesToType + @author Denis Pollney + @date 15 October 2002 + @desc + Adds a new set of possible states to an already existing + type. If required, new bits of the mask are allocated to the + given state. If bits are not available for this, then an + error is returned. + @enddesc +@@*/ + +int +SpaceMask_AppendStatesToType(char* type_name, int nstates, char** state_list) +{ + CCTK_INT8 new_bits; + CCTK_INT8 allocated_bits; + CCTK_INT8* state_mask; + SpaceMask_Type* old_type; + SpaceMask_Type* new_type; + char** new_state_list; + int i; + int j; + int old_type_idx; + int new_bit_nbr; + int total_nstates; + + old_type = NULL; + for (i=0; i<spacemask_registry->ntypes; ++i) + { + if (!strcmp(spacemask_registry->type_list[i]->name, type_name)) + { + old_type = spacemask_registry->type_list[i]; + old_type_idx = i; + } + } + + if (old_type == NULL) + { + CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING, + "Mask type \"%s\" has not been registered", type_name); + return -1; + } + + total_nstates = old_type->nstates + nstates; + new_bit_nbr = SpaceMask_get_bit_nbr(total_nstates) - + SpaceMask_get_bit_nbr(old_type->nstates); + + new_bits = SpaceMask_get_free_bits(new_bit_nbr); + allocated_bits = old_type->bitmask | new_bits; + + state_mask = SpaceMask_determine_state_mask(allocated_bits, total_nstates); + + new_state_list = (char**) malloc (total_nstates*sizeof(char*)); + + i = 0; + for (j=0; j<old_type->nstates; ++j, ++i) + new_state_list[i] = old_type->state_list[j]->name; + for (j=0; j<nstates; ++j, ++i) + new_state_list[i] = state_list[j]; + + new_type = SpaceMask_setup_new_type(allocated_bits, type_name, total_nstates, + new_state_list, state_mask); + free(old_type); + + spacemask_registry->type_list[old_type_idx] = new_type; + + return 0; +} + +/*@@ + @routine SpaceMask_GetTypeBits + @author Denis Pollney + @date 15 October 2002 + @desc + Returns the bitmask corresponding to the given type. Bits + which are allocated to the given type are set to 1, all other + bits are 0. + @enddesc +@@*/ + +CCTK_INT8 +SpaceMask_GetTypeBits(char* type_name) +{ + int i; + + for (i=0; i<spacemask_registry->ntypes; ++i) + { + if (!strcmp(spacemask_registry->type_list[i]->name, type_name)) + return spacemask_registry->type_list[i]->bitmask; + } + + CCTK_VInfo (CCTK_THORNSTRING, "Type \"%s\" has not been registered.\n", + type_name); + + return 0; +} + +/*@@ + @routine SpaceMask_GetStateBits + @author Denis Pollney + @date 15 October 2002 + @desc + Returns the bitmask corresponding to the given state. + @enddesc +@@*/ + +CCTK_INT8 +SpaceMask_GetStateBits(char* type_name, char* state_name) +{ + SpaceMask_Type* type; + int i, j; + + for (i=0; i<spacemask_registry->ntypes; ++i) + { + if (!strcmp(spacemask_registry->type_list[i]->name, type_name)) + { + type = spacemask_registry->type_list[i]; + for (j=0; j<type->nstates; ++j) + { + if (!strcmp(type->state_list[j]->name, state_name)) + return type->state_list[j]->bitmask; + } + } + } + + CCTK_VInfo (CCTK_THORNSTRING, + "Requested state \"%s\" could not be found in type \"%s\"\n", + state_name, type_name); + + return 0; +} + +/*@@ + @routine SpaceMask_SetState + @author Denis Pollney + @date 15 October 2002 + @desc + Sets the mask at a point to the given state. + @enddesc +@@*/ + +void +SpaceMask_SetState(CCTK_INT8* mask, int point, char* type_name, char* state) +{ + CCTK_INT8 type_bits; + CCTK_INT8 state_bits; + + type_bits = SpaceMask_GetTypeBits(type_name); + state_bits = SpaceMask_GetStateBits(type_name, state); + + SpaceMask_SetStateBits(mask, point, type_bits, state_bits); +} + +/*@@ + @routine SpaceMask_CheckState + @author Denis Pollney + @date 15 October 2002 + @desc + Checks that the mask at a point has the given state, in which + case return 1, otherwise return 0. + @enddesc +@@*/ + +int +SpaceMask_CheckState(CCTK_INT8* mask, int point, char* type_name, char* state) +{ + CCTK_INT8 type_bits; + CCTK_INT8 state_bits; + + type_bits = SpaceMask_GetTypeBits(type_name); + state_bits = SpaceMask_GetStateBits(type_name, state); + + return SpaceMask_CheckStateBits(mask, point, type_bits, state_bits); +} + + +/******************************************************************** + ********************* Fortran Wrappers *************************** + ********************************************************************/ + +/* How do you pass the char** state list from fortran??? +void +CCTK_FCALL CCTK_FNAME(SpaceMask_RegisterType)(int* ierr, char* type_name, + int* nstates, char** state_list) +{ + *ierr = SpaceMask_RegisterType(type_name, *nstates, state_list); +} +*/ + +void +CCTK_FCALL CCTK_FNAME(SpaceMask_GetTypeBits)(CCTK_INT8* type_bits, + ONE_FORTSTRING_ARG) +{ + ONE_FORTSTRING_CREATE(type_name) + + *type_bits = SpaceMask_GetTypeBits(type_name); + + free(type_name); +} + +void +CCTK_FCALL CCTK_FNAME(SpaceMask_GetStateBits)(CCTK_INT8* state_bits, + TWO_FORTSTRING_ARG) +{ + + TWO_FORTSTRING_CREATE(type_name, state_name) + + *state_bits = SpaceMask_GetStateBits(type_name, state_name); +} + +void +CCTK_FCALL CCTK_FNAME(SpaceMask_SetState)(CCTK_INT8* mask, + CCTK_INT* point, TWO_FORTSTRING_ARG) +{ + TWO_FORTSTRING_CREATE(type_name, state) + + SpaceMask_SetState(mask, *point, type_name, state); +} + +void +CCTK_FCALL CCTK_FNAME(SpaceMask_CheckState)(int* retval, + CCTK_INT8* mask, + CCTK_INT* point, + TWO_FORTSTRING_ARG) +{ + TWO_FORTSTRING_CREATE(type_name, state) + + *retval = SpaceMask_CheckState(mask, *point, type_name, state); +} diff --git a/src/SpaceMask.h b/src/SpaceMask.h new file mode 100644 index 0000000..bbcecdf --- /dev/null +++ b/src/SpaceMask.h @@ -0,0 +1,113 @@ +/*@@ + @file MaskUtils.c + @date October 2002 + @author Denis Pollney + @desc + Function prototypes and macros mask utilities. + @desc + @version $Header$ +@@*/ + +#ifndef __CACTUSEINSTEIN_SPACEMASK_H__ +#define __CACTUSEINSTEIN_SPACEMASK_H__ + +#define DEBUG 0 + +/******************************************************************** + ********************* Routine Prototypes ************************* + ********************************************************************/ +#ifdef CCODE + +#ifdef __cplusplus +extern "C" +{ +#endif + +int SpaceMask_RegisterType(char*, int, char**); +int SpaceMask_AppendStatesToType(char*, int, char**); +void SpaceMask_SetState(CCTK_INT8*, int, char*, char*); +int SpaceMask_CheckState(CCTK_INT8*, int, char*, char*); +CCTK_INT8 SpaceMask_GetTypeBits(char*); +CCTK_INT8 SpaceMask_GetStateBits(char*, char*); + +#ifdef __cplusplus +} +#endif + +#endif + +/******************************************************************** + ********************* Local Data Types ********************** + ********************************************************************/ + +#ifdef CCODE + +typedef struct +{ + char* name; + CCTK_INT8 bitmask; +} SpaceMask_State; + +typedef struct +{ + char* name; + int nstates; + CCTK_INT8 bitmask; + SpaceMask_State** state_list; +} SpaceMask_Type; + +typedef struct +{ + int ntypes; + SpaceMask_Type** type_list; +} SpaceMask_Registry; + +extern SpaceMask_Registry* spacemask_Registry; + +#endif + +/******************************************************************** + ********************* Macros ****************************** + ********************************************************************/ + +/*@@ + @routine SpaceMask_SetStateBits + @author Denis Pollney + @date 15 October 2002 + @desc + Sets the mask at a point to the given state, as specified + using a bitmask. + @enddesc +@@*/ + +#ifdef FCODE +#define SpaceMask_SetStateBitsF90(mask, i, j, k, type_bits, state_bits) \ + mask(i,j,k) = ior(iand(mask(i,j,k), not(type_bits)), state_bits) +#endif + +#ifdef CCODE +#define SpaceMask_SetStateBits(mask, ijk, type_bits, state_bits) \ + mask[ijk] = (mask[ijk] & ~type_bits) | state_bits; +#endif + +/*@@ + @routine SpaceMask_CheckStateBits + @author Denis Pollney + @date 15 October 2002 + @desc + Checks that the mask at a point has the specified state, + in which case return 1, otherwise return 0. + @enddesc +@@*/ + +#ifdef FCODE +#define SpaceMask_CheckStateBitsF90(mask, i, j, k, type_bits, state_bits) \ + (iand(mask(i,j,k), type_bits) .eq. state_bits) +#endif + +#ifdef CCODE +#define SpaceMask_CheckStateBits(mask, ijk, type_bits, state_bits) \ + (mask[ijk] & type_bits) == state_bits +#endif + +#endif /* __CACTUSEINSTEIN_SPACEMASK_H__ */ diff --git a/src/make.code.defn b/src/make.code.defn index 4a62d46..ed19aad 100644 --- a/src/make.code.defn +++ b/src/make.code.defn @@ -2,7 +2,7 @@ # $Header$ # Source files in this directory -SRCS = MaskInit.c +SRCS = MaskInit.c MaskUtils.c # Subdirectories containing source files SUBDIRS = |