aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschnetter <schnetter@906471b6-c639-44d1-9ea0-3e3d6879f074>2004-03-07 09:48:53 +0000
committerschnetter <schnetter@906471b6-c639-44d1-9ea0-3e3d6879f074>2004-03-07 09:48:53 +0000
commitb82e5c3aa78561c654999489f9a63879af452876 (patch)
treeff8e71d6a990a48b5f6c811ddffe1214434a744b
parentec7367fb09b1f7e0c038cf5eb5085473dea29503 (diff)
Initial implementation of the SymBase specification
git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/SymBase/trunk@2 906471b6-c639-44d1-9ea0-3e3d6879f074
-rw-r--r--README10
-rw-r--r--doc/documentation.tex302
-rw-r--r--interface.ccl85
-rw-r--r--param.ccl2
-rw-r--r--schedule.ccl11
-rw-r--r--src/Faces.c362
-rw-r--r--src/Handles.c164
-rw-r--r--src/Startup.c198
-rw-r--r--src/SymBase.h88
-rw-r--r--src/Table.c165
-rw-r--r--src/make.code.defn8
11 files changed, 1395 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..fc21a92
--- /dev/null
+++ b/README
@@ -0,0 +1,10 @@
+CVS info : $Header$
+
+Cactus Code Thorn SymBase
+Thorn Author(s) : Erik Schnetter <schnetter@aei.mpg.de>
+Thorn Maintainer(s) : Cactus Maintainers <cactusmaint@cactuscode.org>
+--------------------------------------------------------------------------
+
+Purpose of the thorn:
+
+Provide generic handling of symmetries for grids and grid arrays.
diff --git a/doc/documentation.tex b/doc/documentation.tex
new file mode 100644
index 0000000..c37694e
--- /dev/null
+++ b/doc/documentation.tex
@@ -0,0 +1,302 @@
+% *======================================================================*
+% Cactus Thorn template for ThornGuide documentation
+% Author: Ian Kelley
+% Date: Sun Jun 02, 2002
+% $Header$
+%
+% Thorn documentation in the latex file doc/documentation.tex
+% will be included in ThornGuides built with the Cactus make system.
+% The scripts employed by the make system automatically include
+% pages about variables, parameters and scheduling parsed from the
+% relevant thorn CCL files.
+%
+% This template contains guidelines which help to assure that your
+% documentation will be correctly added to ThornGuides. More
+% information is available in the Cactus UsersGuide.
+%
+% Guidelines:
+% - Do not change anything before the line
+% % START CACTUS THORNGUIDE",
+% except for filling in the title, author, date, etc. fields.
+% - Each of these fields should only be on ONE line.
+% - Author names should be separated with a \\ or a comma.
+% - You can define your own macros, but they must appear after
+% the START CACTUS THORNGUIDE line, and must not redefine standard
+% latex commands.
+% - To avoid name clashes with other thorns, 'labels', 'citations',
+% 'references', and 'image' names should conform to the following
+% convention:
+% ARRANGEMENT_THORN_LABEL
+% For example, an image wave.eps in the arrangement CactusWave and
+% thorn WaveToyC should be renamed to CactusWave_WaveToyC_wave.eps
+% - Graphics should only be included using the graphicx package.
+% More specifically, with the "\includegraphics" command. Do
+% not specify any graphic file extensions in your .tex file. This
+% will allow us to create a PDF version of the ThornGuide
+% via pdflatex.
+% - References should be included with the latex "\bibitem" command.
+% - Use \begin{abstract}...\end{abstract} instead of \abstract{...}
+% - Do not use \appendix, instead include any appendices you need as
+% standard sections.
+% - For the benefit of our Perl scripts, and for future extensions,
+% please use simple latex.
+%
+% *======================================================================*
+%
+% Example of including a graphic image:
+% \begin{figure}[ht]
+% \begin{center}
+% \includegraphics[width=6cm]{MyArrangement_MyThorn_MyFigure}
+% \end{center}
+% \caption{Illustration of this and that}
+% \label{MyArrangement_MyThorn_MyLabel}
+% \end{figure}
+%
+% Example of using a label:
+% \label{MyArrangement_MyThorn_MyLabel}
+%
+% Example of a citation:
+% \cite{MyArrangement_MyThorn_Author99}
+%
+% Example of including a reference
+% \bibitem{MyArrangement_MyThorn_Author99}
+% {J. Author, {\em The Title of the Book, Journal, or periodical}, 1 (1999),
+% 1--16. {\tt http://www.nowhere.com/}}
+%
+% *======================================================================*
+
+% If you are using CVS use this line to give version information
+% $Header$
+
+\documentclass{article}
+
+% Use the Cactus ThornGuide style file
+% (Automatically used from Cactus distribution, if you have a
+% thorn without the Cactus Flesh download this from the Cactus
+% homepage at www.cactuscode.org)
+\usepackage{../../../../doc/latex/cactus}
+
+\begin{document}
+
+% The author of the documentation
+\author{Erik Schnetter \textless schnetter@aei.mpg.de\textgreater}
+
+% The title of the document (not necessarily the name of the Thorn)
+\title{SymBase}
+
+% the date your document was last changed, if your document is in CVS,
+% please use:
+\date{$ $Date$ $}
+
+\maketitle
+
+% Do not delete next line
+% START CACTUS THORNGUIDE
+
+% Add all definitions used in this documentation here
+% \def\mydef etc
+
+% Add an abstract for this thorn's documentation
+\begin{abstract}
+Thorn SymBase contains a registry for symmetry conditions and for
+symmetry faces.
+\end{abstract}
+
+% The following sections are suggestive only.
+% Remove them or add your own.
+
+
+
+\section{Introduction}
+
+Thorn SymBase contains a registry for symmetry conditions and for
+symmetry faces. Other thorns that implement symmetry boundary
+conditions register themselves with this thorn and reserve certain
+faces of the grid, so that no other boundary condition is applied
+there. Thorns that implement physical boundary conditions should
+query this thorn about the set of faces that have symmetry boundary
+conditions and should not apply the physical boundary condition there.
+
+
+
+\section{Registering Symmetry Conditions}
+
+Each thorn that implements a symmetry boundary condition should
+register itself with thorn SymBase. This has no consequences per se,
+but it reservers a symmetry handle for later use. The API for
+registering and querying symmetry names and handles is
+
+\begin{verbatim}
+CCTK_INT FUNCTION
+ SymmetryRegister (CCTK_STRING IN sym_name)
+
+CCTK_INT FUNCTION
+ SymmetryHandleOfName (CCTK_STRING IN sym_name)
+
+CCTK_POINTER_TO_CONST FUNCTION
+ SymmetryNameOfHandle (CCTK_INT IN sym_handle)
+\end{verbatim}
+
+The routine \texttt{SymmetryRegister} should be called in a routine
+that has been scheduled in the schedule group
+\texttt{SymmetryRegister}.
+
+\begin{quote}
+Note: We have the API in the specification, we have it in the
+interface file, in the source code, and in a header file, and I
+duplicated it into grdoc headers. I refuse to write and describe and
+cross-check the API a \emph{sixth} time in latex. At some point, we
+have to start using tools for that. Please read the grdoc headers or
+the grdoc-produced html files for a detailed description.
+\end{quote}
+
+
+
+\section{Registering Symmetries for Faces}
+
+Thorn SymBase keeps two registries. The first, described in the
+previous section, contains the set of symmetry boundary conditions
+that exist at all. The second, described here, describes which face
+of the grids have which symmetry condition applied to it, if any.
+Each such mapping from grid face to symmetry condition is described by
+a symmetry table with the following entries:
+
+\begin{verbatim}
+CCTK_INT symmetry_handle[]
+CCTK_INT symmetry_zone_width[]
+\end{verbatim}
+
+Each of these arrays contains one element per face, numbered in the
+same way as the \texttt{cctk\_bbox} array. The
+\texttt{symmetry\_handle} is a symmetry handle as described in the
+previous section, and the \texttt{symmetry\_zone\_width} is the width
+of the symmetry zone.
+
+Code outside SymBase should not modify these table entries.
+
+There is one such table for the grid hierarchy, which is valid for all
+grid functions. There is additionally one such table for each grid
+array group.
+
+The API for registering symmetries for faces is
+
+\begin{verbatim}
+CCTK_INT FUNCTION
+ SymmetryRegisterGrid
+ (CCTK_POINTER IN cctkGH,
+ CCTK_INT IN sym_handle,
+ CCTK_INT IN ARRAY which_faces,
+ CCTK_INT IN ARRAY symmetry_zone_width)
+
+CCTK_INT FUNCTION
+ SymmetryRegisterGI
+ (CCTK_POINTER IN cctkGH,
+ CCTK_INT IN sym_handle,
+ CCTK_INT IN ARRAY which_faces,
+ CCTK_INT IN ARRAY symmetry_zone_width,
+ CCTK_INT IN group_index)
+
+CCTK_INT FUNCTION
+ SymmetryRegisterGN
+ (CCTK_POINTER IN cctkGH,
+ CCTK_INT IN sym_handle,
+ CCTK_INT IN ARRAY which_faces,
+ CCTK_INT IN ARRAY symmetry_zone_width,
+ CCTK_STRING IN group_name)
+\end{verbatim}
+
+The first routine registers a symmetry condition for certain faces for
+the grid hierarchy, the other two routines register for grid array
+groups. \texttt{sym\_handle} must be a symmetry handle obtained as
+described in the previous section. \texttt{which\_faces} and
+\texttt{symmetry\_zone\_width} are arrays with one element per face,
+numbered in the same way as the \texttt{cctk\_bbox} array.
+\texttt{which\_faces} selects which faces to register, and
+\texttt{symmetry\_zone\_width} sets the number of symmetry zones for
+these faces.
+
+It is obviously not possible to register multiple symmetry conditions
+for the same face.
+
+
+
+\section{Querying Symmetries of Faces}
+
+Physical boundary conditions need to know to which faces they should
+apply the boundary condition. They need to query SymBase for the set
+of faces that have a symmetry boundary condition, and they must not
+apply their physical boundary condition there. The API is
+
+\begin{verbatim}
+CCTK_INT FUNCTION
+ SymmetryTableHandleForGrid (CCTK_POINTER_TO_CONST IN cctkGH)
+
+CCTK_INT FUNCTION
+ SymmetryTableHandleForGI
+ (CCTK_POINTER_TO_CONST IN cctkGH,
+ CCTK_INT IN group_index)
+
+CCTK_INT FUNCTION
+ SymmetryTableHandleForGN
+ (CCTK_POINTER_TO_CONST IN cctkGH,
+ CCTK_STRING IN group_name)
+\end{verbatim}
+
+These functions return the the handle for the symmetry table for the
+grid hierarchy or for the grid array group, respectively. The table
+entry \texttt{symmetry\_handle} contains the symmetry handle for the
+symmetry boundary condition, or a negative number if the face has no
+symmetry boundary condition associated with it.
+
+The code to find out which boundaries should have a physical boundary
+condition applied might look as follows:
+
+\begin{verbatim}
+#include <assert.h>
+#include "util_Table.h"
+
+CCTK_INT symtable;
+CCTK_INT symbnd[6];
+int face;
+int ierr;
+
+symtable = SymmetryTableHandleForGrid (cctkGH);
+assert (symtable>=0);
+
+ierr = Util_TableGetIntArray (symtable, 6, symbnd, "symmetry_handle");
+assert (ierr==6);
+
+for (face=0; face<6; ++face) {
+ if (cctk_bbox[face] && symbnd[face]<0) {
+ /* Apply physical boundary condition here */
+ }
+}
+\end{verbatim}
+
+\begin{verbatim}
+#include "util_Table.h"
+
+CCTK_INT symtable
+CCTK_INT symbnd(6)
+integer face
+integer ierr
+
+symtable = SymmetryTableHandleForGrid (cctkGH)
+if (symtable<0) call CCTK_WARN (0, "internal error")
+
+call Util_TableGetIntArray (ierr, int(symtable), 6, symbnd, "symmetry_handle")
+if (ierr/=6) call CCTK_WARN (0, "internal error")
+
+do face=1,6
+ if (cctk_bbox(face)/=0 .and. symbnd(face)<0) then
+ ! Apply physical boundary condition here
+ end if
+end do
+\end{verbatim}
+
+
+
+% Do not delete next line
+% END CACTUS THORNGUIDE
+
+\end{document}
diff --git a/interface.ccl b/interface.ccl
new file mode 100644
index 0000000..2c07bd8
--- /dev/null
+++ b/interface.ccl
@@ -0,0 +1,85 @@
+# Interface definition for thorn SymBase
+# $Header$
+
+IMPLEMENTS: SymBase
+
+
+
+# Register a symmetry, and query the symmetry name/handle mapping:
+
+CCTK_INT FUNCTION SymmetryRegister (CCTK_STRING IN sym_name)
+PROVIDES FUNCTION SymmetryRegister \
+ WITH SymBase_SymmetryRegister \
+ LANGUAGE C
+
+CCTK_INT FUNCTION SymmetryHandleOfName (CCTK_STRING IN sym_name)
+PROVIDES FUNCTION SymmetryHandleOfName \
+ WITH SymBase_SymmetryHandleOfName \
+ LANGUAGE C
+
+CCTK_POINTER_TO_CONST FUNCTION SymmetryNameOfHandle (CCTK_INT IN sym_handle)
+PROVIDES FUNCTION SymmetryNameOfHandle \
+ WITH SymBase_SymmetryNameOfHandle \
+ LANGUAGE C
+
+
+
+# Register a symmetry condition for a face:
+
+CCTK_INT FUNCTION \
+ SymmetryRegisterGrid \
+ (CCTK_POINTER IN cctkGH, \
+ CCTK_INT IN sym_handle, \
+ CCTK_INT IN ARRAY which_faces, \ # array [N_FACES]
+ CCTK_INT IN ARRAY symmetry_zone_width) # array [N_FACES]
+PROVIDES FUNCTION SymmetryRegisterGrid \
+ WITH SymBase_SymmetryRegisterGrid \
+ LANGUAGE C
+
+CCTK_INT FUNCTION \
+ SymmetryRegisterGI \
+ (CCTK_POINTER IN cctkGH, \
+ CCTK_INT IN sym_handle, \
+ CCTK_INT IN ARRAY which_faces, \ # array [N_FACES]
+ CCTK_INT IN ARRAY symmetry_zone_width, \ # array [N_FACES]
+ CCTK_INT IN group_index)
+PROVIDES FUNCTION SymmetryRegisterGI \
+ WITH SymBase_SymmetryRegisterGI \
+ LANGUAGE C
+
+CCTK_INT FUNCTION \
+ SymmetryRegisterGN \
+ (CCTK_POINTER IN cctkGH, \
+ CCTK_INT IN sym_handle, \
+ CCTK_INT IN ARRAY which_faces, \ # array [N_FACES]
+ CCTK_INT IN ARRAY symmetry_zone_width, \ # array [N_FACES]
+ CCTK_STRING IN group_name)
+PROVIDES FUNCTION SymmetryRegisterGN \
+ WITH SymBase_SymmetryRegisterGN \
+ LANGUAGE C
+
+
+
+# Get the symmetry table handle for a grid or grid array:
+
+CCTK_INT FUNCTION \
+ SymmetryTableHandleForGrid (CCTK_POINTER_TO_CONST IN cctkGH)
+PROVIDES FUNCTION SymmetryTableHandleForGrid \
+ WITH SymBase_SymmetryTableHandleForGrid \
+ LANGUAGE C
+
+CCTK_INT FUNCTION \
+ SymmetryTableHandleForGI \
+ (CCTK_POINTER_TO_CONST IN cctkGH, \
+ CCTK_INT IN group_index)
+PROVIDES FUNCTION SymmetryTableHandleForGI \
+ WITH SymBase_SymmetryTableHandleForGI \
+ LANGUAGE C
+
+CCTK_INT FUNCTION \
+ SymmetryTableHandleForGN \
+ (CCTK_POINTER_TO_CONST IN cctkGH, \
+ CCTK_STRING IN group_name)
+PROVIDES FUNCTION SymmetryTableHandleForGN \
+ WITH SymBase_SymmetryTableHandleForGN \
+ LANGUAGE C
diff --git a/param.ccl b/param.ccl
new file mode 100644
index 0000000..e82ab1e
--- /dev/null
+++ b/param.ccl
@@ -0,0 +1,2 @@
+# Parameter definitions for thorn SymBase
+# $Header$
diff --git a/schedule.ccl b/schedule.ccl
new file mode 100644
index 0000000..f3d7f54
--- /dev/null
+++ b/schedule.ccl
@@ -0,0 +1,11 @@
+# Schedule definitions for thorn SymBase
+# $Header$
+
+SCHEDULE SymBase_Startup AT CCTK_STARTUP
+{
+ LANG: C
+} "Register GH Extension for SymBase"
+
+SCHEDULE GROUP SymmetryRegister AT CCTK_WRAGH
+{
+} "Register your symmetries here"
diff --git a/src/Faces.c b/src/Faces.c
new file mode 100644
index 0000000..6817c3f
--- /dev/null
+++ b/src/Faces.c
@@ -0,0 +1,362 @@
+/*@@
+ @file $RCSfile$
+ @author $Author$
+ @date $Date$
+ @desc
+ Register a symmetry condition for a face
+ @version $Header$
+ @enddesc
+@@*/
+
+#include <stdlib.h>
+
+#include "cctk.h"
+
+#include "util_Table.h"
+
+#include "SymBase.h"
+
+
+/* the rcs ID and its dummy function to use it */
+static const char *const rcsid = "$Header$";
+CCTK_FILEVERSION (CactusBase_SymBase_Faces_c);
+
+
+
+/*@@
+ @routine SymBase_SymmetryRegisterFaces
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Register a symmetry for certain faces
+ @enddesc
+ @var sym_table
+ @vtype CCTK_INT
+ @vdesc Table which describes the grid or grid array
+ @vio in
+ @endvar
+ @var group_dim
+ @vtype CCTK_INT
+ @vdesc Dimension of the grid or grid array
+ @vio in
+ @endvar
+ @var sym_handle
+ @vtype CCTK_INT
+ @vdesc Symmetry handle
+ @vio in
+ @endvar
+ @var which_faces
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc The set of faces
+ @vio in
+ @endvar
+ @var symmetry_zone_width
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc Symmetry boundary width
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ status code
+ 0 for success
+ -1 if sym_table has an illegal value
+ -9 if group_dim has an illegal value
+ -2 if sym_handle has an illegal value
+ -3 if which_faces has an illegal value
+ -4 if symmetry_zone_width has an illegal value
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryRegisterFaces (CCTK_INT const sym_table,
+ CCTK_INT const group_dim,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width)
+{
+ CCTK_INT symmetry_handle[100];
+ CCTK_INT symmetry_zone_width[100];
+ int face;
+ int ierr;
+
+ /* Check arguments */
+ if (sym_table < 0)
+ {
+ return -1; /* illegal argument */
+ }
+ if (group_dim < 0)
+ {
+ return -9; /* illegal argument */
+ }
+ if (sym_handle < 0 || sym_handle >= SymBase_num_symmetries)
+ {
+ return -2; /* illegal argument */
+ }
+ if (!which_faces)
+ {
+ return -3; /* illegal argument */
+ }
+ if (!symmetry_zone_width)
+ {
+ return -4; /* illegal argument */
+ }
+
+ /* Get table entries */
+ if (2 * group_dim > 100)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ ierr = Util_TableGetIntArray
+ (sym_table, 2 * group_dim, symmetry_handle, "symmetry_handle");
+ if (ierr != 2 * group_dim)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ ierr = Util_TableGetIntArray
+ (sym_table, 2 * group_dim, symmetry_zone_width, "symmetry_zone_width");
+ if (ierr != 2 * group_dim)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ /* Update table entries */
+ for (face = 0; face < 2 * group_dim; ++face)
+ {
+ if (which_faces[face])
+ {
+ if (symmetry_handle[face] != -1)
+ {
+ return -5; /* The face is already taken */
+ }
+ symmetry_handle[face] = sym_handle;
+ symmetry_zone_width[face] = new_symmetry_zone_width[face];
+ }
+ }
+
+ /* Set table entries */
+ ierr = Util_TableSetIntArray
+ (sym_table, 2 * group_dim, symmetry_handle, "symmetry_handle");
+ if (ierr != 1)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ ierr = Util_TableSetIntArray
+ (sym_table, 2 * group_dim, symmetry_zone_width, "symmetry_zone_width");
+ if (ierr != 1)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ return 0;
+}
+
+
+
+/*@@
+ @routine SymBase_SymmetryRegisterGrid
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Register a symmetry for certain faces of the grid hierarchy
+ @enddesc
+ @var cctkGH
+ @vtype cGH *
+ @vdesc The grid hierarchy
+ @vio in
+ @endvar
+ @var sym_handle
+ @vtype CCTK_INT
+ @vdesc Symmetry handle
+ @vio in
+ @endvar
+ @var which_faces
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc The set of faces
+ @vio in
+ @endvar
+ @var symmetry_zone_width
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc Symmetry boundary width
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ status code
+ 0 for success
+ Error codes of SymBase_SymmetryRegisterFaces
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryRegisterGrid (CCTK_POINTER const cctkGH_,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width)
+{
+ cGH const *const cctkGH = cctkGH_;
+ struct SymBase const *symdata;
+
+ if (!cctkGH)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ symdata = CCTK_GHExtension (cctkGH, "SymBase");
+ if (!symdata)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ return SymBase_SymmetryRegisterFaces
+ (symdata->sym_table, cctkGH->cctk_dim,
+ sym_handle, which_faces, new_symmetry_zone_width);
+}
+
+
+
+/*@@
+ @routine SymBase_SymmetryRegisterGI
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Register a symmetry for certain faces of grid arrays
+ @enddesc
+ @var cctkGH
+ @vtype cGH *
+ @vdesc The grid hierarchy
+ @vio in
+ @endvar
+ @var sym_handle
+ @vtype CCTK_INT
+ @vdesc Symmetry handle
+ @vio in
+ @endvar
+ @var which_faces
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc The set of faces
+ @vio in
+ @endvar
+ @var symmetry_zone_width
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc Symmetry boundary width
+ @vio in
+ @endvar
+ @var group_index
+ @vtype CCTK_INT
+ @vdesc Grid array group
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ status code
+ 0 for success
+ -6 if group_index has an illegal value
+ -7 if the group has an illegal type
+ -8 internal error
+ Error codes of SymBase_SymmetryRegisterFaces
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryRegisterGI (CCTK_POINTER const cctkGH_,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width,
+ CCTK_INT const group_index)
+{
+ cGH const *const cctkGH = cctkGH_;
+ struct SymBase const *symdata;
+
+ if (!cctkGH)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ symdata = CCTK_GHExtension (cctkGH, "SymBase");
+ if (!symdata)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ if (group_index < 0 || group_index >= CCTK_NumGroups ())
+ {
+ return -6; /* illegal argument */
+ }
+
+ switch (CCTK_GroupTypeI (group_index))
+ {
+ case CCTK_GF:
+ return -7; /* illegal group type */
+ case CCTK_SCALAR:
+ case CCTK_ARRAY:
+ return SymBase_SymmetryRegisterFaces
+ (symdata->array_sym_tables[group_index], CCTK_GroupDimI (group_index),
+ sym_handle, which_faces, new_symmetry_zone_width);
+ default:
+ CCTK_WARN (0, "internal error");
+ }
+
+ return -8; /* internal error */
+}
+
+
+
+/*@@
+ @routine SymBase_SymmetryRegisterGI
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Register a symmetry for certain faces of grid arrays
+ @enddesc
+ @var cctkGH
+ @vtype cGH *
+ @vdesc The grid hierarchy
+ @vio in
+ @endvar
+ @var sym_handle
+ @vtype CCTK_INT
+ @vdesc Symmetry handle
+ @vio in
+ @endvar
+ @var which_faces
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc The set of faces
+ @vio in
+ @endvar
+ @var symmetry_zone_width
+ @vtype CCTK_INT[2*group_dim]
+ @vdesc Symmetry boundary width
+ @vio in
+ @endvar
+ @var group_name
+ @vtype CCTK_STRING
+ @vdesc Grid array group
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ status code
+ 0 for success
+ Error codes of CCTK_GroupIndex
+ Error codes of SymBase_SymmetryRegisterGI
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryRegisterGN (CCTK_POINTER const cctkGH_,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width,
+ CCTK_STRING const group_name)
+{
+ int group_index;
+
+ group_index = CCTK_GroupIndex (group_name);
+ if (group_index < 0)
+ {
+ return group_index; /* illegal argument */
+ }
+
+ return SymBase_SymmetryRegisterGI
+ (cctkGH_, sym_handle, which_faces, new_symmetry_zone_width, group_index);
+}
diff --git a/src/Handles.c b/src/Handles.c
new file mode 100644
index 0000000..22b0a1a
--- /dev/null
+++ b/src/Handles.c
@@ -0,0 +1,164 @@
+/*@@
+ @file $RCSfile$
+ @author $Author$
+ @date $Date$
+ @desc
+ Register a symmetry, and query the symmetry name/handle mapping
+ @version $Header$
+ @enddesc
+@@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+
+#include "SymBase.h"
+
+
+
+/* the rcs ID and its dummy function to use it */
+static const char *const rcsid = "$Header$";
+CCTK_FILEVERSION (CactusBase_SymBase_Handles_c);
+
+
+
+/* Number of registered symmetries */
+size_t SymBase_num_symmetries;
+
+/* The names of these symmetries */
+const char **SymBase_symmetry_names;
+
+
+
+/*@@
+ @routine SymBase_SymmetryRegister
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Register a symmetry
+ @enddesc
+ @var sym_name
+ @vtype CCTK_STRING
+ @vdesc Name of the symmetry
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ >=0 symmetry handle
+ -1 if sym_name has an illegal value
+ -2 if a symmetry with the same name has already been registered
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryRegister (CCTK_STRING const sym_name)
+{
+ int n;
+
+ if (!sym_name)
+ {
+ return -1; /* illegal argument */
+ }
+
+ for (n = 0; n < SymBase_num_symmetries; ++n)
+ {
+ if (strcmp (sym_name, SymBase_symmetry_names[n]) == 0)
+ {
+ return -2; /* symmetry exists already */
+ }
+ }
+
+ SymBase_symmetry_names
+ = realloc (SymBase_symmetry_names,
+ (SymBase_num_symmetries + 1) * sizeof *SymBase_symmetry_names);
+ if (!SymBase_symmetry_names)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ SymBase_symmetry_names[SymBase_num_symmetries] = strdup (sym_name);
+ if (!SymBase_symmetry_names[SymBase_num_symmetries])
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ ++SymBase_num_symmetries;
+
+ return SymBase_num_symmetries - 1;
+}
+
+
+
+/*@@
+ @routine SymBase_SymmetryHandleOfName
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Map a symmetry name to a symmetry handle
+ @enddesc
+ @var sym_name
+ @vtype CCTK_STRING
+ @vdesc Name of the symmetry
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ >=0 symmetry handle
+ -1 if sym_name has an illegal value
+ -2 if no symmetry with that name has been registered
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryHandleOfName (CCTK_STRING const sym_name)
+{
+ int n;
+
+ if (!sym_name)
+ {
+ return -1; /* illegal argument */
+ }
+
+ for (n = 0; n < SymBase_num_symmetries; ++n)
+ {
+ if (strcmp (sym_name, SymBase_symmetry_names[n]) == 0)
+ {
+ return n; /* found */
+ }
+ }
+
+ return -2; /* not found */
+}
+
+
+
+/*@@
+ @routine SymBase_SymmetryNameOfHandle
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Map a symmetry handle to a symmetry name
+ @enddesc
+ @var sym_handle
+ @vtype CCTK_INT
+ @vdesc Symmetry name
+ @vio in
+ @endvar
+ @returntype CCTK_POINTER_TO_CONST
+ @returndesc
+ char const * containing the symmetry name
+ NULL if no symmetry with that handle has been registered
+ @endreturndesc
+@@*/
+
+CCTK_POINTER_TO_CONST
+SymBase_SymmetryNameOfHandle (CCTK_INT const sym_handle)
+{
+ if (sym_handle < 0 || sym_handle >= SymBase_num_symmetries)
+ {
+ return NULL; /* illegal argument */
+ }
+
+ return SymBase_symmetry_names[sym_handle];
+}
diff --git a/src/Startup.c b/src/Startup.c
new file mode 100644
index 0000000..b09c7e3
--- /dev/null
+++ b/src/Startup.c
@@ -0,0 +1,198 @@
+/*@@
+ @file $RCSfile$
+ @author $Author$
+ @date $Date$
+ @desc
+ Thorn startup
+ @version $Header$
+ @enddesc
+@@*/
+
+#include <stdlib.h>
+
+#include "cctk.h"
+
+#include "util_Table.h"
+
+#include "SymBase.h"
+
+
+
+/* the rcs ID and its dummy function to use it */
+static const char *const rcsid = "$Header$";
+CCTK_FILEVERSION (CactusBase_SymBase_Startup_c);
+
+
+
+/*@@
+ @routine SymBase_Startup
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Register a GH extension and initialise the global variables
+ @enddesc
+ @returntype int
+ @returndesc
+ status code
+ 0 for success
+ @endreturndesc
+@@*/
+
+int
+SymBase_Startup (void)
+{
+ int handle;
+ int ierr;
+
+ handle = CCTK_RegisterGHExtension ("SymBase");
+ if (handle < 0)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ ierr = CCTK_RegisterGHExtensionSetupGH (handle, SymBase_Setup);
+ if (ierr != 1)
+ { /* strange error code convention */
+ CCTK_WARN (0, "internal error");
+ }
+
+ SymBase_num_symmetries = 0;
+ SymBase_symmetry_names = NULL;
+
+ return 0; /* no error */
+}
+
+
+
+/*@@
+ @routine SymBase_Setup
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Initialise the GH extension
+ @enddesc
+ @var config
+ @vtype tFleshConfig *
+ @vdesc Internal flesh information, unused
+ @vio in
+ @endvar
+ @var convlev
+ @vtype int
+ @vdesc Convergence level, unused
+ @vio in
+ @endvar
+ @var cctkGH
+ @vtype cGH *
+ @vdesc Grid hierarchy
+ @vio in
+ @endvar
+@@*/
+
+void *
+SymBase_Setup (tFleshConfig * const config,
+ int const convlev, cGH * const cctkGH)
+{
+ struct SymBase *symdata;
+ CCTK_INT symmetry_handle[100];
+ CCTK_INT symmetry_zone_width[100];
+ int group;
+ int face;
+ int ierr;
+
+ /* Create GH extension */
+ symdata = malloc (sizeof *symdata);
+ if (!symdata)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ /* Initialise handle and zone width arrays */
+ for (face = 0; face < 100; ++face)
+ {
+ symmetry_handle[face] = -1;
+ symmetry_zone_width[face] = 0;
+ }
+
+ /* Create grid symmetry table */
+ symdata->sym_table = Util_TableCreate (UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
+ if (symdata->sym_table < 0)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ if (2 * cctkGH->cctk_dim > 100)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ ierr = Util_TableSetIntArray
+ (symdata->sym_table,
+ 2 * cctkGH->cctk_dim, symmetry_handle, "symmetry_handle");
+ if (ierr)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ ierr = Util_TableSetIntArray
+ (symdata->sym_table,
+ 2 * cctkGH->cctk_dim, symmetry_zone_width, "symmetry_zone_width");
+ if (ierr)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ /* Create grid array symmetry tables */
+ symdata->array_sym_tables
+ = malloc (CCTK_NumGroups () * sizeof *symdata->array_sym_tables);
+ if (!symdata->array_sym_tables)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ for (group = 0; group < CCTK_NumGroups (); ++group)
+ {
+ switch (CCTK_GroupTypeI (group))
+ {
+ case CCTK_GF:
+
+ /* No table */
+ symdata->array_sym_tables[group] = -1;
+ break;
+
+ case CCTK_SCALAR:
+ case CCTK_ARRAY:
+
+ /* Create array symmetry table */
+ symdata->array_sym_tables[group]
+ = Util_TableCreate (UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
+ if (symdata->array_sym_tables[group] < 0)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ if (2 * CCTK_GroupDimI (group) > 100)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ ierr = Util_TableSetIntArray
+ (symdata->array_sym_tables[group],
+ 2 * CCTK_GroupDimI (group), symmetry_handle, "symmetry_handle");
+ if (ierr)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ ierr = Util_TableSetIntArray
+ (symdata->array_sym_tables[group],
+ 2 * CCTK_GroupDimI (group), symmetry_zone_width,
+ "symmetry_zone_width");
+ if (ierr)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+ break;
+
+ default:
+ CCTK_WARN (0, "internal error");
+ }
+ }
+
+ return symdata;
+}
diff --git a/src/SymBase.h b/src/SymBase.h
new file mode 100644
index 0000000..d343fee
--- /dev/null
+++ b/src/SymBase.h
@@ -0,0 +1,88 @@
+/*@@
+ @file $RCSfile$
+ @author $Author$
+ @date $Date$
+ @desc
+ Declarations for thorn SymBase
+ @version $Header$
+ @enddesc
+@@*/
+
+#ifndef SYMBASE_H
+#define SYMBASE_H
+
+
+
+#include "cctk.h"
+
+
+
+/* SymBase's GH extension */
+struct SymBase
+{
+ /* Grid symmetry table handle */
+ int sym_table;
+
+ /* Grid array symmetry table handles */
+ int *array_sym_tables;
+};
+
+
+
+/* Number of registered symmetries */
+extern size_t SymBase_num_symmetries;
+
+/* The names of these symmetries */
+extern const char **SymBase_symmetry_names;
+
+
+
+/* Startup.c */
+int SymBase_Startup (void);
+void *SymBase_Setup (tFleshConfig * const config,
+ int const convlev, cGH * const cctkGH);
+
+/* Handles.c */
+CCTK_INT SymBase_SymmetryRegister (CCTK_STRING const sym_name);
+CCTK_INT SymBase_SymmetryHandleOfName (CCTK_STRING const sym_name);
+CCTK_POINTER_TO_CONST SymBase_SymmetryNameOfHandle (CCTK_INT const
+ sym_handle);
+
+/* Faces.c */
+CCTK_INT
+SymBase_SymmetryRegisterFaces (CCTK_INT const sym_table,
+ CCTK_INT const group_dim,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width);
+CCTK_INT
+SymBase_SymmetryRegisterGrid (CCTK_POINTER const cctkGH_,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width);
+CCTK_INT
+SymBase_SymmetryRegisterGI (CCTK_POINTER const cctkGH_,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width,
+ CCTK_INT const group_index);
+CCTK_INT
+SymBase_SymmetryRegisterGN (CCTK_POINTER const cctkGH_,
+ CCTK_INT const sym_handle,
+ CCTK_INT const *const which_faces,
+ CCTK_INT const *const new_symmetry_zone_width,
+ CCTK_STRING const group_name);
+
+/* Table.c */
+CCTK_INT
+SymBase_SymmetryTableHandleForGrid (CCTK_POINTER_TO_CONST const cctkGH_);
+CCTK_INT
+SymBase_SymmetryTableHandleForGI (CCTK_POINTER_TO_CONST const cctkGH_,
+ CCTK_INT const group_index);
+CCTK_INT
+SymBase_SymmetryTableHandleForGN (CCTK_POINTER_TO_CONST const cctkGH_,
+ CCTK_STRING const group_name);
+
+
+
+#endif /* ! defined SYMBASE_H */
diff --git a/src/Table.c b/src/Table.c
new file mode 100644
index 0000000..3d88f07
--- /dev/null
+++ b/src/Table.c
@@ -0,0 +1,165 @@
+/*@@
+ @file $RCSfile$
+ @author $Author$
+ @date $Date$
+ @desc
+ Get the symmetry table handle for a grid or grid array
+ @version $Header$
+ @enddesc
+@@*/
+
+#include "cctk.h"
+
+#include "SymBase.h"
+
+
+
+/* the rcs ID and its dummy function to use it */
+static const char *const rcsid = "$Header$";
+CCTK_FILEVERSION (CactusBase_SymBase_Table_c);
+
+
+
+/*@@
+ @routine SymBase_SymmetryTableHandleForGrid
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Return the symmetry table handle for the grid hierarchy
+ @enddesc
+ @var cctkGH
+ @vtype CCTK_POINTER_TO_CONST
+ @vdesc Grid hierarchy
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ >=0 symmetry table handle
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryTableHandleForGrid (CCTK_POINTER_TO_CONST const cctkGH_)
+{
+ cGH const *const cctkGH = cctkGH_;
+ struct SymBase const *symdata;
+
+ if (!cctkGH)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ symdata = CCTK_GHExtension (cctkGH, "SymBase");
+ if (!symdata)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ return symdata->sym_table;
+}
+
+
+
+/*@@
+ @routine SymBase_SymmetryTableHandleForGI
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Return the symmetry table handle for a grid array
+ @enddesc
+ @var cctkGH
+ @vtype CCTK_POINTER_TO_CONST
+ @vdesc Grid hierarchy
+ @vio in
+ @endvar
+ @var group_index
+ @vtype CCTK_INT
+ @vdesc Group
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ >=0 symmetry table handle
+ -6 if group_index has an illegal value
+ -7 if the group type has an illegal value
+ -8 if there was an internal error
+ @endreturndesc
+@@*/
+
+CCTK_INT
+SymBase_SymmetryTableHandleForGI (CCTK_POINTER_TO_CONST const cctkGH_,
+ CCTK_INT const group_index)
+{
+ cGH const *const cctkGH = cctkGH_;
+ struct SymBase const *symdata;
+
+ if (!cctkGH)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ symdata = CCTK_GHExtension (cctkGH, "SymBase");
+ if (!symdata)
+ {
+ CCTK_WARN (0, "internal error");
+ }
+
+ if (group_index < 0 || group_index >= CCTK_NumGroups ())
+ {
+ return -6; /* illegal argument */
+ }
+
+ switch (CCTK_GroupTypeI (group_index))
+ {
+ case CCTK_GF:
+ return -7; /* illegal group type */
+ case CCTK_SCALAR:
+ case CCTK_ARRAY:
+ return symdata->array_sym_tables[group_index];
+ default:
+ CCTK_WARN (0, "internal error");
+ }
+
+ return -8; /* internal error */
+}
+
+
+
+/*@@
+ @routine SymBase_SymmetryTableHandleForGN
+ @author Erik Schnetter
+ @date 2004-03-06
+ @desc
+ Return the symmetry table handle for a grid array
+ @enddesc
+ @var cctkGH
+ @vtype CCTK_POINTER_TO_CONST
+ @vdesc Grid hierarchy
+ @vio in
+ @endvar
+ @var group_name
+ @vtype CCTK_STRING
+ @vdesc Group
+ @vio in
+ @endvar
+ @returntype CCTK_INT
+ @returndesc
+ >=0 symmetry table handle
+ Error codes of CCTK_GroupIndex
+ Error codes of SymBase_SymmetryTableHandleForGI
+ @endreturndesc
+@@*/
+CCTK_INT
+SymBase_SymmetryTableHandleForGN (CCTK_POINTER_TO_CONST const cctkGH_,
+ CCTK_STRING const group_name)
+{
+ int group_index;
+
+ group_index = CCTK_GroupIndex (group_name);
+ if (group_index < 0)
+ {
+ return group_index; /* illegal argument */
+ }
+
+ return SymBase_SymmetryTableHandleForGI (cctkGH_, group_index);
+}
diff --git a/src/make.code.defn b/src/make.code.defn
new file mode 100644
index 0000000..84b3c24
--- /dev/null
+++ b/src/make.code.defn
@@ -0,0 +1,8 @@
+# Main make.code.defn file for thorn SymBase
+# $Header$
+
+# Source files in this directory
+SRCS = Faces.c Handles.c Startup.c Table.c
+
+# Subdirectories containing source files
+SUBDIRS =