From 39408b904dba508df668f77687fad77626383917 Mon Sep 17 00:00:00 2001 From: rideout Date: Fri, 22 Aug 2003 20:40:40 +0000 Subject: CoordBase thorn, which implements the Coordinate spec git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/CoordBase/trunk@2 0337457d-221f-4ee6-a5f0-14255d5370d8 --- README | 8 + doc/documentation.tex | 408 +++++++++++++++++++++++++++ interface.ccl | 6 + param.ccl | 2 + schedule.ccl | 7 + src/CoordBase.c | 756 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/CoordBase.h | 59 ++++ src/GHExtension.c | 164 +++++++++++ src/coordbaseGH.h | 32 +++ src/make.code.defn | 8 + 10 files changed, 1450 insertions(+) create mode 100644 README create mode 100644 doc/documentation.tex create mode 100644 interface.ccl create mode 100644 param.ccl create mode 100644 schedule.ccl create mode 100644 src/CoordBase.c create mode 100644 src/CoordBase.h create mode 100644 src/GHExtension.c create mode 100644 src/coordbaseGH.h create mode 100644 src/make.code.defn diff --git a/README b/README new file mode 100644 index 0000000..68a9fa9 --- /dev/null +++ b/README @@ -0,0 +1,8 @@ +Cactus Code Thorn CoordBase +Authors : Cactus Maintainers +CVS info : $Header$ +-------------------------------------------------------------------------- + +Purpose of the thorn: + +Provides generic handling of coordinates for grid arrays. diff --git a/doc/documentation.tex b/doc/documentation.tex new file mode 100644 index 0000000..b69e31e --- /dev/null +++ b/doc/documentation.tex @@ -0,0 +1,408 @@ +% *======================================================================* +% 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 +% relevent 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 +% % BEGIN 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 sparated with a \\ or a comma +% - You can define your own macros are OK, but they must appear after +% the BEGIN 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 graphix package. +% More specifically, with the "includegraphics" command. Do +% not specify any graphic file extensions in your .tex file. This +% will allow us (later) 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{...} +% - 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{Cactus Maintainers $<$\code{cactusmaint@cactuscode.org}$>$} + +% The title of the document (not necessarily the name of the Thorn) +\title{Coordinate Base Thorn} + +% the date your document was last changed: +\date{$ $Date$ $} + +\maketitle + +% Do not delete next line +% START CACTUS THORNGUIDE + +% Add all definitions used in this documentation here: +\def\WHAGH{CCTK\_WHAGH} +\def\beforetable{\\[1mm]} + +\hyphenation{Coord} + +% Add an abstract for this thorn's documentation +\begin{abstract} +CoordBase provides a mechanism for registering coordinate systems, and +maintaining a database of coordinate systems and their coordinates, +using key-value tables. +\end{abstract} + + +\section{Introduction} + +Many applications which use Cactus will want to make use of coordinate +systems. The CoordBase thorn provides a method of registering +coordinate systems and their properties. Thorns which implement +coordinate systems will register the systems they provide with +CoordBase. Since coordinate systems are composed of a collection of +coordinates, the coordinates which comprise the systems are registered +with CoordBase as well. The data describing coordinate systems are +held on Cactus key-value tables. A schema for the format of these +tables is provided in section +\ref{CactusBase_CoordBase_coordinate_schema}. Developers are free to +compose and use their own schema, but are encouraged to use the one +detailed here, as this will be the standard for all of the core Cactus +thorns. + +CoordBase specifies an extensible set of coordinate properties. The +use of key-value tables to hold the these properties makes CoordBase +flexible and configurable. The coordinate values themselves can be +specified in a number of ways, depending on the nature of the +coordinate system. This way symmetries of the coordinates on the +computational grid can be exploited to minimize memory consumption. +Via a function call, one can easily acertain what coordinate system is +associated with any given grid variable, which is convenient for e.g.\ +I/O. A method of registering default coordinates for all grid +variables of a certain dimension makes it simple to specify which +coordinate systems should be associated with which grid variables. + +The coordinate infrastructure provided by CoordBase will work +seamlessly with AMR and multi-model codes. + +%extensible database of coordinate systems, coordinates, and their +%properties + +Thorns which provide coordinates will inherit from CoordBase, and +register both the coordinate systems they provide, and the default +coordinate systems for the appropriate dimension of grid variables. +In addition, one can associate a coordinate with any Cactus grid +variable, within a thorn's interface.ccl. +Coordinate systems specified in the interface.ccl override defaults +for the dimension. + +The coordinate functions in the Cactus flesh are deprecated with the +introduction of this thorn. Please use the functions provided here in +preference to those in the flesh. + + +\section{Coordinate system symmetries} + +Since computations performed with Cactus are done on a discrete +lattice, only a discrete set of coordinate values are used for any +coordinate system. The symmetries of how the coordinate values vary +on the grid points make coordinates fall into three types: +\emph{uniform}, \emph{nonuniform}, and \emph{warped}. (At least these +are the three cases that the CoordBase schema considers.) A uniform +coordinate varies from each of its neighbors by a constant. i.e.\ its +value can be determined from the index of the grid point from simply +an origin and constant `delta'. A nonuniform coordinate has a +spatially varying `delta'. For both uniform and nonuniform +coordinates, the coordinate values do not vary along the other +directions of the grid. (e.g.\ the $x$ coordinate will be the same +regardless of the `j' index of the grid point.) Thus one could +completely determine the coordinate values of a 3D system of +nonuniform coordinates by providing three 1D arrays. This later +assumption is relaxed for a warped coordinate; a warped coordinate +will vary across the entire grid. Recall that `coordinate lines' +(lines of constant coordinate value) cannot cross (because one n-tuple +of coordinate values would specify muliple points in space), so this +places a `bound' of sorts on the possible `warping' of the +coordinates. + +The type of a coordinate system will be the same as that of its +coordinates. If there are different types of coordinates within the +same system, then the coordinate system is \emph{mixed}. Note that a +warped coordinate system is the most general possible, so any +coordinate system could be regarded as warped if one wishes. + +\subsection{Specifying coordinate values} + +As mentioned above, for a uniform coordinate system, it is sufficient +to specify the origin and spacing for a uniform coordinate. One may +also specify a grid variable to hold the coordinate values, if +desired. See section \ref{CactusBase_CoordBase_coordinate_schema}. A +nonuniform coordinate can be specified with a 1D grid variable, if +desired, or an nD variable. A warped coordinate system will always +need a nD grid variable. FMR and AMR will need an nD grid +variable to specify the coordinate values. A mixed coordinate system +can use some combination of the above, or simply an nD grid variable. + + +\section{Coordinate Thorns} + +Generally coordinate thorns will allow the declaration of default +coordinate systems for a dimension to be controled by parameters. + +If a thorn attempts to register a default for a dimension which +already has a default registered, a level 1 warning will result, and +the default will be overwritten with the new default. Since the order +of execution of the registration calls will in general not be +specified, one must be careful when activating more than one coordinate thorn. + +Coordinate systems and defaults can be changed at any time throughout +a run, as can coordinate properties. +In general these are set at \WHAGH\ and CCTK\_BASEGRID, respectively. + +The coordinate thorns are responsible for filling out the portions of +the coordinate and coordinate system tables that are not written by +the registration routines. See sections +\ref{CactusBase_CoordBase_system_tables} and +\ref{CactusBase_CoordBase_coord_tables}. + +\section{Application thorns} + +Application thorns should check at CCTK\_PARAMCHECK to see if the correct +coordinate system is being used for each relevant grid variable. +While the old flesh API is still being used you may want to make this +merely a warning. +Use Coord\_GroupSystem() to find the coordinate system for groups (see +section \ref{CactusBase_CoordBase_APIs}). + + +\section{Coordinate APIs} +\label{CactusBase_CoordBase_APIs} + +\begin{verbatim} +int systemhandle = Coord_SystemRegister(const cGH *GH, + int dim, + const char *systemname) +\end{verbatim} +registers a coordinate system, along with its +dimension, with the CoordBase thorn. This will create a coordinate +system table, and return the handle of the table for success, or a +negative error code upon error. The possible errors are:\beforetable +\begin{tabular}{ll} +COORDERROR\_INVALIDDIM & invalid dimension passed in\\ +COORDERROR\_INVALIDNAME & invalid name passed in\\ +COORDERROR\_TABLEERROR & error from key-value or hash tables in flesh\\ +COORDERROR\_SYSTEMEXISTS & coordinate system of this name already exists\\ +\end{tabular} +\\These error codes are defined in CoordBase.h. CoordBase holds the +table handles on a GH extension, under the name ``CoordBase''. + +\begin{verbatim} +int systemhandle = Coord_SystemHandle(const cGH *GH, + const char *systemname) +\end{verbatim} +returns the handle for a given coordinate system, or +negative on error:\beforetable +\begin{tabular}{ll} + COORDERROR\_TABLEERROR & error from hash table\\ + COORDERROR\_NOSYSTEM & no coordinate system of this name is registered\\ +\end{tabular} + +\begin{verbatim} +int coordhandle = Coord_CoordRegister(const cGH *GH, + int systemhandle, + int direction, + const char *coordname) +\end{verbatim} +registers a coordinate within a coordinate system, in the specified +`direction'. (Direction in this context means the index in the +coordinate basis, which ranges from 1 to the dimension of the system.) +Coord\_CoordRegister() returns the coordinate handle, or negative for an +error:\beforetable +\begin{tabular}{ll} +COORDERROR\_INVALIDDIM & invalid `direction'\\ +COORDERROR\_INVALIDHANDLE & invalid handle passed in / coordinate system + does not exist\\ +COORDERROR\_TABLEERROR & error from hash or key-value tables in flesh\\ +COORDERROR\_COORDINATEEXISTS & coordinate already exists for this `direction'\\ +COORDERROR\_DUPLICATENAME & coordinate of this name already exists in this + system\\ +\end{tabular} + +\begin{verbatim} +int coordhandle = Coord_CoordHandle(const cGH *GH, + const char *coordname, + const char *systemname) +\end{verbatim} +returns the coordinate handle for a given coordinatate in a coordinate system, +or negative on error:\beforetable +\begin{tabular}{ll} +COORDERROR\_NOSYSTEM & no coordinate system of this name is registered\\ +COORDERROR\_TABLEERROR & error from hash table\\ +COORDERROR\_NOSUCHCOORD & no coordinate of the name is registered for this + system\\ +\end{tabular} + +\begin{verbatim} +int systemhandle = Coord_GroupSystem(const cGH *GH, + const char *groupname) +\end{verbatim} +returns the handle for the coordinate system associated with a group of grid +variables, or negative on error. +This can either be the default for coordinate systems of this +dimension, or the coordinate system that is specified in the +interface.ccl. Coordinate systems specified in interface.ccl will +override any defaults. The possible error codes are:\beforetable +\begin{tabular}{ll} +COORDERROR\_INVALIDGROUPNAME & no such group exists\\ +COORDERROR\_NOCOORDSYS & no coordinate system is associated with the + group +\end{tabular} + +\begin{verbatim} +int systemhandle = Coord_SetDefaultSystem(const cGH *GH, + const char *systemname) +\end{verbatim} +sets this coordinate system to be the default for grid variables of +the same dimension. It returns the handle of the system, or negative +for errors:\beforetable +\begin{tabular}{ll} +COORDERROR\_INVALIDNAME & no coordinate system of this name has been + registered\\ +COORDERROR\_NODIMENSION & coordinate system does not have a valid dimension\\ +COORDERROR\_DEFAULTEXISTS & grid variables of this dimension already have a \\ + & default coordinate system registered\\ +\end{tabular} +\\There can be a default coordinate system for each grid dimension. The +default system will apply for each grid variable of that dimension, +unless it is overridden. + + +\section{Coordinate Schema} +\label{CactusBase_CoordBase_coordinate_schema} + +\subsection{Coordinate System Tables} +\label{CactusBase_CoordBase_system_tables} + +Associated with each coordinate system is a table, which should have the +following entries:\beforetable +\begin{tabular}{|l|l|l|} +\hline +\textbf{key} & \textbf{data type} & \textbf{value}\\ +\hline +NAME & CCTK\_STRING & \code{Cart3d|Spher3d|....}\\ +DIMENSION & CCTK\_INT & \code{1,2,3,...}\\ +TYPE & CCTK\_STRING & \code{uniform|nonuniform|warped|mixed}\\ +COORDINATES & CCTK\_INT array & \verb|,...|\\ +\hline +\end{tabular} +\\The values for the coordinates array are the handles for the +coordinate tables (see section +\ref{CactusBase_CoordBase_coord_tables}). The NAME and DIMENSION +fields are filled out when Coord\_SystemRegister() is called. The +COORDINATES field is filled out by Coord\_CoordRegister(). It is left +for the coordinate thorn to fill out the TYPE field. + +\subsection{Coordinate Tables} +\label{CactusBase_CoordBase_coord_tables} + +Associated with each coordinate of each coordinate system is another +table, which should have the following entries:\beforetable +\begin{tabular}{|l|l|l|} +\hline +\textbf{key} & \textbf{data type} & \textbf{values}\\ +\hline +SYSTEM & CCTK\_INT & \verb||\\ +NAME & CCTK\_STRING & \code{x}\\ +DIRECTION & CCTK\_INT & \code{2}\\ +PHYSICALMIN & CCTK\_REAL & \code{0.0}\\ +COMPMIN & CCTK\_REAL & \\ +PHYSICALMAX & CCTK\_REAL & \\ +COMPMAX & CCTK\_REAL & \\ +TYPE & CCTK\_STRING & \verb/uniform|non-uniform|warped/\\ +TIMEDEPENDENT & CCTK\_INT & \verb//\\ +DATATYPE & CCTK\_STRING & \\ +GAINDEX & CCTK\_INT & \\ +\hline +DELTA\footnotemark %{only for type=uniform} + & CCTK\_REAL & \code{147.372e16}\\ +\hline +\end{tabular} +\footnotetext{only for type=\code{uniform}} +\\ +Coord\_CoordRegister() fills out the SYSTEM, NAME, and DIRECTION +fields, and the COORDINATES field of the system table. The remaining +fields are the responsivility of the coordinate thorn. + +% Each of these fields should be explained... +% Though most are pretty self-explanatory. + + +\section{Specifying coordinate systems in the interface.ccl} + +Coordinate systems associated with grid variable groups can be +specified in the group's tags table, using the key \code{COORDSYSTEM}. +Below is a grid array which could represent a vector field on a +2-sphere. +\begin{verbatim} +CCTK_REAL SphericalVectorField TYPE=ARRAY DIM=2 TAGS='COORDSYSTEM="sphere2d" TENSORTYPE="vector"' +{ + field_theta, field_phi +} +\end{verbatim} +Even though another thorn has set a default for all 2D grid variables +to something else, Coord\_GroupSystem() will always return the handle +for sphere2d when called on this group. + +% Do not delete next line +% END CACTUS THORNGUIDE + +\end{document} diff --git a/interface.ccl b/interface.ccl new file mode 100644 index 0000000..6133c52 --- /dev/null +++ b/interface.ccl @@ -0,0 +1,6 @@ +# Interface definition for thorn CoordBase +# $Header$ + +implements: CoordBase + +include header: CoordBase.h in CoordBase.h diff --git a/param.ccl b/param.ccl new file mode 100644 index 0000000..c294bac --- /dev/null +++ b/param.ccl @@ -0,0 +1,2 @@ +# Parameter definitions for thorn CoordBase +# $Header$ diff --git a/schedule.ccl b/schedule.ccl new file mode 100644 index 0000000..4160bc2 --- /dev/null +++ b/schedule.ccl @@ -0,0 +1,7 @@ +# Schedule definitions for thorn CoordBase +# $Header$ + +schedule CoordBase_Startup at CCTK_STARTUP +{ + LANG: C +} "Register a GH extension to store the coordinate system handles" diff --git a/src/CoordBase.c b/src/CoordBase.c new file mode 100644 index 0000000..ff18a75 --- /dev/null +++ b/src/CoordBase.c @@ -0,0 +1,756 @@ + /*@@ + @file CoordBase.c + @date 23 July 2003 + @author Gabrielle Allen and David Rideout + @desc + Functions which implement the coordinate API. + @enddesc + @version $Header$ + @@*/ + +#include +#include +#include + +#include "cctk.h" +#include "util_Table.h" +#include "util_Hash.h" +#include "util_String.h" +#include "CoordBase.h" +#include "coordbaseGH.h" + +static const char *rcsid = "$Header$"; + +CCTK_FILEVERSION(CactusBase_CoordBase_CoordBase_c); + +/******************************************************************** + ********************* Aliased Routine Prototypes ***************** + ********************************************************************/ + +/******************************************************************** + ********************* Local Data ********************************* + ********************************************************************/ + +/* table: provides master table for all coordinate systems */ +//static int tAllSystems=-1; +/* Doesn't this do everything that we need? What is the need for the GH extension? Probably I should have used a GHExtension for the boundary stuff? */ + +static unsigned int longest_coordname=0; +static int longest_systemname=0; + +/******************************************************************** + ********************* (to be Aliased?) Routines ****************** + ********************************************************************/ + + /*@@ + @routine Coord_SystemRegister + @date 24 July 2003 + @author Gabrielle Allen and David Rideout + @desc + Registers a coordinate system. + @enddesc + @calls CCTK_GHExtension, Util_HashData, CCTK_VWarn, Util_TableCreate, + Util_TableSetString, Util_TableSetInt, Util_HashAdd + @calledby + @history + + @endhistory + @var GH + @vdesc cctkGH * + @vtype CCTK_POINTER_TO_CONST + @vio in + @vcomment + @endvar + @var dim + @vdesc coordinate system dimension + @vtype CCTK_INT + @vio in + @vcomment + @endvar + @var systemname + @vdesc coordinate system name + @vtype CCTK_STRING + @vio in + @vcomment + @endvar + + @returntype int + @returndesc + coordinate system handle, or: + COORDERROR_INVALIDDIM invalid dimension passed in + COORDERROR_INVALIDNAME invalid name passed in + COORDERROR_TABLEERROR error from key-value or hash tables in flesh + COORDERROR_SYSTEMEXISTS coordinate system of this name already exists + @endreturndesc +@@*/ + +CCTK_INT Coord_SystemRegister(CCTK_POINTER_TO_CONST GH, CCTK_INT dim, + CCTK_STRING systemname) +{ + int ierr; + int retval; + int *systemhandle_ptr; + int systemname_length; + const coordbaseGH *GHex; + uHash *hash; + void *perr; + + /* Initialize variables */ + retval = 0; + + /* Check input arguments */ + if (dim <= 0) + { + retval = COORDERROR_INVALIDDIM; + } + else if (!systemname) + { + retval = COORDERROR_INVALIDNAME; + } + else + { + /* Get coordinate system name / handle hash table from GH Extension */ + GHex = (const coordbaseGH *) CCTK_GHExtension(GH,"CoordBase"); + hash = GHex->coordsystems; + + /* Has a coordinate system of this name already been registered? */ + systemname_length = strlen(systemname); + if (systemname_length>longest_systemname) + { + longest_systemname = systemname_length+1; + } + perr = Util_HashData(hash, systemname_length, systemname, 0); + if (perr!=NULL) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, + "Coordinate system %s already registered",systemname); + retval = COORDERROR_SYSTEMEXISTS; + } + } + + if (retval == 0) + { + + /* Now make a table for this system */ + systemhandle_ptr = (int *) malloc(sizeof(int)); + *systemhandle_ptr = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE); + if (*systemhandle_ptr < 0) + { + CCTK_WARN(0,"Could not create table"); + retval = COORDERROR_TABLEERROR; + } + else + { + retval = *systemhandle_ptr; + } + + /* Add coordinate system name */ + ierr = Util_TableSetString(*systemhandle_ptr, systemname, "NAME"); + if (ierr < 0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, + "Error %d when writing coordinate system name to table", + ierr); + retval = COORDERROR_TABLEERROR; + } + + /* Add dimension information */ + Util_TableSetInt(*systemhandle_ptr, dim, "DIMENSION"); + if (ierr < 0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, + "Error %d when writing coordinate system dimension to table", + ierr); + retval = COORDERROR_TABLEERROR; + } + + /* Register it with the Coordinate GH Extension */ + ierr = Util_HashAdd(hash, systemname_length, systemname, 0, + (void *) systemhandle_ptr); + if (ierr < 0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, + "Error %d when storing coordinate system handle", + ierr); + retval = COORDERROR_TABLEERROR; + } + } + + return retval; +} + + + /*@@ + @routine Coord_SystemHandle + @date 24 July 2003 + @author Gabrielle Allen and David Rideout + @desc + Returns the coordinate system handle for a given name. + @enddesc + @calls CCTK_GHExtension, Util_HashData + @calledby + @history + + @endhistory + @var GH + @vdesc cctkGH * + @vtype CCTK_POINTER_TO_CONST + @vio in + @vcomment + @endvar + @var systemname + @vdesc coordinate system name + @vtype CCTK_STRING + @vio in + @vcomment + @endvar + + @returntype int + @returndesc + coordinate system handle, or: + COORDERROR_TABLEERROR error from hash table + COORDERROR_NOSYSTEM no coordinate system of this name is registered + @endreturndesc +@@*/ + +CCTK_INT Coord_SystemHandle(CCTK_POINTER_TO_CONST GH, CCTK_STRING systemname) +{ + int *handle_ptr; + const coordbaseGH *GHex; + uHash *hash; + + /* Get coordinate system name / handle hash table from GH Extension */ + GHex = (const coordbaseGH *) CCTK_GHExtension(GH,"CoordBase"); + hash = GHex->coordsystems; + + /* Get coordinate handle from hash table */ + handle_ptr = Util_HashData(hash, strlen(systemname), systemname, 0); + if (!handle_ptr) + { + *handle_ptr = COORDERROR_NOSYSTEM; + } + else if (*handle_ptr<0) + { + *handle_ptr = COORDERROR_TABLEERROR; + } + + return *handle_ptr; +} + + /*@@ + @routine Coord_CoordRegister + @date 24 July 2003 + @author Gabrielle Allen and David Rideout + @desc + Registers a coordinate within a coordinate system. + @enddesc + @calls Util_TableGetInt, CCTK_VWarn, Util_TableGetIntArray, + Util_TableSetIntArray, Util_TableGetString, Util_StrCmpi, + Util_TableCreate, Util_TableSetInt, Util_TableSetString + @calledby + @history + + @endhistory + @var GH + @vdesc cctkGH * + @vtype CCTK_POINTER_TO_CONST + @vio in + @vcomment + @endvar + @var systemhandle + @vdesc coordinate system handle + @vtype CCTK_INT + @vio in + @vcomment + @endvar + @var direction + @vdesc index within coodinate basis + @vtype CCTK_INT + @vio in + @vcomment ranges from 1 to the dimension of the coordinate system + @endvar + @var coordname + @vdesc coordinate system name + @vtype CCTK_STRING + @vio in + @vcomment + @endvar + + @returntype int + @returndesc + coordinate handle, or: + COORDERROR_INVALIDDIM invalid 'direction' + COORDERROR_INVALIDHANDLE invalid handle passed in / coordinate system + does not exist + COORDERROR_TABLEERROR error from hash or key-value tables in flesh + COORDERROR_COORDINATEEXISTS coordinate already exists for this 'direction' + COORDERROR_DUPLICATENAME coordinate of this name already exists in + this system + @endreturndesc +@@*/ + +CCTK_INT Coord_CoordRegister(CCTK_POINTER_TO_CONST GH, + CCTK_INT systemhandle, + CCTK_INT direction, + CCTK_STRING coordname) +{ + int coordinate_handle; + int ierr; + CCTK_INT system_dimension; + CCTK_INT *coordinate_tables; + CCTK_INT i; + char *coordname_buffer; + + /* Initialize variables */ + coordinate_handle = 0; + GH = GH; + /*(void *) ((const cGH *)GH + 0);*/ + + /* Check input arguments */ + /* Get coordinate system dimension, and check for valid systemhandle */ + ierr = Util_TableGetInt(systemhandle, &system_dimension, + "DIMENSION"); + if (ierr<0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Invalid system handle " + "%d", systemhandle); + coordinate_handle = COORDERROR_INVALIDHANDLE; + } + + /* Check for valid 'direction' */ + if (direction<1 || direction>system_dimension) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Invalid 'direction'. " + "It but be an integer from 1 to the coordinate system " + "dimension %d.", system_dimension); + coordinate_handle = COORDERROR_INVALIDDIM; + } + + /* Get coordinate tables from system table */ + coordinate_tables = (CCTK_INT *) malloc(system_dimension*sizeof(CCTK_INT)); + ierr = Util_TableGetIntArray(systemhandle, system_dimension, + coordinate_tables, "COORDINATES"); + if (ierr<0) + { + /* The only possibility is that this is a bad key, so add this entry */ + for (i=0; i=0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Coordinate already " + "registered for 'direction' %d", direction); + coordinate_handle = COORDERROR_COORDINATEEXISTS; + } + + /* Has this coordinate name been used already in this system? */ + coordname_buffer = (char *) malloc((longest_coordname)*sizeof(char)); + for (i=0; i=0) + { + ierr = Util_TableGetString(coordinate_tables[i], longest_coordname, + coordname_buffer, "NAME"); + if (ierr<0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, "Error reading " + "coordinate name from its table"); + coordinate_handle = COORDERROR_TABLEERROR; + } + else if (Util_StrCmpi(coordname_buffer, coordname)==0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Coordinate named %s " + "is already registered for this system", coordname_buffer); + coordinate_handle = COORDERROR_DUPLICATENAME; + break; + } + } + } + + /* Everything checks out */ + if (coordinate_handle==0) + { + + /* Is this coordinate name the longest yet? */ + if (strlen(coordname)+1 > longest_coordname) + { + longest_coordname = strlen(coordname)+1; + } + + /* Create coordinate table */ + coordinate_handle = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE); + if (coordinate_handle < 0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, "Could not create " + "coordinate table"); + coordinate_handle = COORDERROR_TABLEERROR; + } + ierr = Util_TableSetInt(coordinate_handle, systemhandle, "SYSTEM"); + ierr += Util_TableSetString(coordinate_handle, coordname, "NAME"); + ierr += Util_TableSetInt(coordinate_handle, direction, "DIRECTION"); + if (ierr<0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, "Error writing to" + "coordinate table"); + coordinate_handle = COORDERROR_TABLEERROR; + } + + /* Register coordinate table with system table */ + coordinate_tables[direction-1] = coordinate_handle; + ierr = Util_TableSetIntArray(systemhandle, system_dimension, + coordinate_tables, "COORDINATES"); + if (ierr<0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, "Error writing " + "coordinate table to system table"); + coordinate_handle = COORDERROR_TABLEERROR; + } + } + + free(coordinate_tables); + free(coordname_buffer); + return coordinate_handle; +} + + + /*@@ + @routine Coord_CoordHandle + @date 25 July 2003 + @author Gabrielle Allen and David Rideout + @desc + Returns the coordinate handle for a given coordinate name and + system name + @enddesc + @calls CCTK_GHExtension, Util_HashData, CCTK_WARN, Util_TableGetInt, + Util_TableGetIntArray, Util_TableGetString, CCTK_VWarn, + Util_StrCmpi + @calledby + @history + + @endhistory + @var GH + @vdesc cctkGH * + @vtype CCTK_POINTER_TO_CONST + @vio in + @vcomment + @endvar + @var coordname + @vdesc coordinate name + @vtype CCTK_STRING + @vio in + @vcomment + @endvar + @var systemname + @vdesc coordinate system name + @vtype CCTK_STRING + @vio in + @vcomment + @endvar + + @returntype int + @returndesc + coordinate table handle, or: + COORDERROR_NOSYSTEM no coordinate system of this name is registered + COORDERROR_TABLEERROR error from hash table + COORDERROR_NOSUCHCOORD no coordinate of the name is registered for this + system + @endreturndesc +@@*/ + +CCTK_INT Coord_CoordHandle(CCTK_POINTER_TO_CONST GH, + CCTK_STRING coordname, + CCTK_STRING systemname) +{ + int coord_handle; + int *system_handle_ptr; + CCTK_INT system_dimension; + CCTK_INT *coordinate_table_handles; + int coordname_length; + int ierr; + int i; + const coordbaseGH *GHex; + uHash *hash; + char *coordname_buffer; + + /* Get coordinate system name / handle hash table from GH Extension */ + GHex = (const coordbaseGH *) CCTK_GHExtension(GH,"CoordBase"); + hash = GHex->coordsystems; + + /* Get system table handle */ + system_handle_ptr = Util_HashData(hash, strlen(systemname), systemname, 0); + if (!system_handle_ptr) + { + CCTK_WARN(1, "No such coordinate system registered"); + coord_handle = COORDERROR_NOSYSTEM; + } + + if (system_handle_ptr) + { + + /* Get system dimension */ + ierr = Util_TableGetInt(*system_handle_ptr, &system_dimension, + "DIMENSION"); + if (ierr<0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, "Error reading " + "dimension from system table"); + coord_handle = COORDERROR_TABLEERROR; + } + + /* Get coordinate table handle */ + coordinate_table_handles = + (CCTK_INT *) malloc(system_dimension*sizeof(CCTK_INT)); + ierr = Util_TableGetIntArray(*system_handle_ptr, system_dimension, + coordinate_table_handles, "COORDINATES"); + if (ierr<0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, "Error reading " + "coordinate tables from system table"); + coord_handle = COORDERROR_TABLEERROR; + } + + /* Search for coordname */ + coordname_length = strlen(coordname)+1; + coordname_buffer = (char *) malloc(coordname_length*sizeof(char)); + for (i=0; i=0) + { + ierr = Util_TableGetString(coordinate_table_handles[i], + coordname_length, coordname_buffer, "NAME"); + if (ierr<0) + { + CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING, "Error reading " + "coordinate name"); + coord_handle = COORDERROR_TABLEERROR; + } + else if (Util_StrCmpi(coordname_buffer, coordname)==0) + { + coord_handle = coordinate_table_handles[i]; + break; + } + } + if (i==system_dimension-1) + { + coord_handle = COORDERROR_NOSUCHCOORD; + } + } + + free(coordinate_table_handles); + free(coordname_buffer); + } + return coord_handle; +} + + /*@@ + @routine Coord_GroupSystem + @date 28 July 2003 + @author David Rideout + @desc + Returns the coordinate system handle associated with a group of + grid variables + @enddesc + @calls CCTK_GroupTagsTable, CCTK_VWarn, Util_TableGetString, + Coord_SystemHandle, CCTK_GHExtension, CCTK_GroupIndex, + CCTK_GroupDimI + @calledby + @history + + @endhistory + @var GH + @vdesc cctkGH * + @vtype CCTK_POINTER_TO_CONST + @vio in + @vcomment + @endvar + @var groupname + @vdesc variable group name + @vtype CCTK_STRING + @vio in + @vcomment + @endvar + + @returntype int + @returndesc + coordinate system handle, or: + COORDERROR_INVALIDGROUPNAME no such group exists + COORDERROR_NOCOORDSYS no coordinate system is associated with the + group + @endreturndesc +@@*/ + +CCTK_INT Coord_GroupSystem(CCTK_POINTER_TO_CONST GH, + CCTK_STRING groupname) +{ + int system_handle; + int group_tags_table; + int ierr; + int gindex; /* group index */ + int gdim; /* group dimension */ + const coordbaseGH *GHex; + int *default_coord_systems; + char *system_name; + + system_handle = -9999; + + /* Get tags table associated with this group */ + group_tags_table = CCTK_GroupTagsTable(groupname); + if (group_tags_table < 0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Invalid group name %s", + groupname); + system_handle = COORDERROR_INVALIDGROUPNAME; + } + else + { + /* Get associated coordinate system */ + system_name = (char *) malloc(longest_systemname*sizeof(char)); + ierr = Util_TableGetString(group_tags_table, longest_systemname, + system_name, "COORDSYSTEM"); + if (ierr>=0) + { + system_handle = Coord_SystemHandle(GH, system_name); + if (system_handle < 0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Coordinate system " + "%s associated with group %s does not exist", system_name, + groupname); + system_handle = COORDERROR_INVALIDNAME; + } + } + + if (system_handle == -9999) + { + /* Check for a default for all variables of this dimension */ + GHex = (const coordbaseGH *) CCTK_GHExtension(GH,"CoordBase"); + default_coord_systems = GHex->default_coord_systems; + assert(default_coord_systems); + gindex = CCTK_GroupIndex(groupname); + assert(gindex>=0); + gdim = CCTK_GroupDimI(gindex); + assert(gdim>0); + if ((system_handle = default_coord_systems[gdim-1]) < 0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "No coordinate " + "system is associated with group %s", groupname); + system_handle = COORDERROR_NOCOORDSYS; + } + } + free(system_name); + } + + return system_handle; +} + + /*@@ + @routine Coord_SetDefaultSystem + @date 28 July 2003 + @author David Rideout + @desc + Set this coordinate system to be the default for grid functions + of the same dimension + @enddesc + @calls CCTK_GHExtension, Coord_SystemHandle, CCTK_VWarn, + Util_TableGetInt + @calledby + @history + + @endhistory + @var GH + @vdesc cctkGH * + @vtype CCTK_POINTER_TO_CONST + @vio in + @vcomment + @endvar + @var systemname + @vdesc coordinate system name + @vtype CCTK_STRING + @vio in + @vcomment + @endvar + + @returntype int + @returndesc + coordinate system handle, or + COORDERROR_INVALIDNAME no coordinate system of this name has been + registered + COORDERROR_NODIMENSION coordinate system does not have a valid dimension + COORDERROR_DEFAULTEXISTS grid variables of this dimension already have a + default coordinate system registered + @endreturndesc +@@*/ + +CCTK_INT Coord_SetDefaultSystem(CCTK_POINTER_TO_CONST GH, + CCTK_STRING systemname) +{ + int ierr; + int *default_coord_systems; + int system_handle; + CCTK_INT system_dimension; + int retval; + const coordbaseGH *GHex; +#ifdef DEBUG + int i; +#endif + + /* Retrieve array from GH extension */ + GHex = (const coordbaseGH *) CCTK_GHExtension(GH,"CoordBase"); + default_coord_systems = GHex->default_coord_systems; + + /* Get coordinate system handle */ + system_handle = Coord_SystemHandle(GH, systemname); + if (system_handle<0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Invalid system name " + "%s", systemname); + retval = COORDERROR_INVALIDNAME; + } + else + { + /* Get system dimension */ + ierr = Util_TableGetInt(system_handle, &system_dimension, "DIMENSION"); + if (ierr<0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "System %s does not " + "have a registered dimension", systemname); + retval = COORDERROR_NODIMENSION; + } + else + { + /* Set the default for this dimension */ + if (default_coord_systems[system_dimension-1]>=0) + { + CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING, "Default coordinate " + "system for %d dimensional grid variables is already set. " + "Overwriting to %s.", system_dimension, systemname); + retval = COORDERROR_DEFAULTEXISTS; + } + else + { + retval = system_handle; + } + default_coord_systems[system_dimension-1] = system_handle; + } + } + +#ifdef DEBUG + for (i=0; i + +#include "cctk.h" +#include "coordbaseGH.h" +#include "util_Hash.h" + +static const char *rcsid = "$Header$"; + +CCTK_FILEVERSION(CactusBase_CoordBase_GHExtension_c); + +/******************************************************************** + ********************* Scheduled Routine Prototypes *************** + ********************************************************************/ + +void CoordBase_Startup (void); + +/******************************************************************** + ********************* Local Routine Prototypes ********************* + ********************************************************************/ + +static void *CoordBase_SetupGH (tFleshConfig *config, int conv_level, cGH *GH); +static int CoordBase_InitGH (cGH *GH); + +/******************************************************************** + ********************* External Routines ********************** + ********************************************************************/ + + /*@@ + @routine CoordBase_Startup + @date Sunday Sept 22 2002 + @author Gabrielle Allen + @desc + The startup registration routine for CoordBase. + Registers the GH extension needed for CoordBase. + @enddesc + @calls CCTK_RegisterGHExtension + CCTK_RegisterGHExtensionSetupGH + CCTK_RegisterGHExtensionInitGH +@@*/ +void CoordBase_Startup (void) +{ + int GHex_handle; + + GHex_handle = CCTK_RegisterGHExtension ("CoordBase"); + CCTK_RegisterGHExtensionSetupGH (GHex_handle, CoordBase_SetupGH); + CCTK_RegisterGHExtensionInitGH (GHex_handle, CoordBase_InitGH); +} + + +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ + + /*@@ + @routine CoordBase_SetupGH + @date Sun Sept 22 2002 + @author Gabrielle Allen + @desc + Allocates CoordBase's GH extension structure + @enddesc + + @calls Util_HashCreate + + @var config + @vdesc the CCTK configuration as provided by the flesh + @vtype tFleshConfig * + @vio unused + @endvar + @var conv_level + @vdesc the convergence level + @vtype int + @vio unused + @endvar + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH * + @vio in + @endvar + + @returntype void * + @returndesc + pointer to the allocated GH extension structure + @endreturndesc +@@*/ + +static void *CoordBase_SetupGH (tFleshConfig *config, int conv_level, cGH *GH) +{ + coordbaseGH *myGH; + + /* suppress compiler warnings about unused variables */ + (void) (config + 0); + (void) (conv_level + 0); + (void) (GH + 0); + + /* allocate the GH extension and its components */ + myGH = (coordbaseGH *) malloc (sizeof (coordbaseGH)); + + if (! myGH) + { + CCTK_WARN (0, "CoordBase_SetupGH: Unable to allocate memory for GH " + "extension"); + } + + myGH->coordsystems = Util_HashCreate(8); + + myGH->default_coord_systems = (int *) malloc(CCTK_MaxDim()*sizeof(int)); + + if (! myGH->default_coord_systems) + { + CCTK_WARN (0, "CoordBase_SetupGH: Unable to allocate memory for GH " + "extension"); + } + + return (myGH); +} + + /*@@ + @routine CoordBase_InitGH + @date 28 July 2003 + @author David Rideout + @desc + Initializes CoordBase's GH extension structure + @enddesc + + @calls CCTK_GHExtension, CCTK_MaxDim + + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH * + @vio in + @endvar + + @returntype int + @returndesc + pointer to the initialized GH extension structure + @endreturndesc +@@*/ + +int CoordBase_InitGH (cGH *GH) +{ + const coordbaseGH *GHex; + int i; + + /* Get the GH extension pointer again... */ + GHex = (const coordbaseGH *) CCTK_GHExtension(GH,"CoordBase"); + + /* Initialize default_coord_systems to invalid table handles */ + for (i=0; idefault_coord_systems[i] = -1; + } + + return 0; +} diff --git a/src/coordbaseGH.h b/src/coordbaseGH.h new file mode 100644 index 0000000..d07ef4d --- /dev/null +++ b/src/coordbaseGH.h @@ -0,0 +1,32 @@ + /*@@ + @header coordbaseGH.h + @date Sun Sept 22 2002 + @author Gabrielle Allen + @desc + The extensions to the GH structure from CoordBase + @version $Header$ + @@*/ + +#ifndef _COORDBASE_COORDBASEGH_H_ +#define _COORDBASE_COORDBASEGH_H_ 1 + +#include "util_Hash.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct COORDBASEGH +{ + uHash *coordsystems; /* Hash table mapping coord systems to tables */ + int *default_coord_systems; /* Default coord system for each dimension */ + /* int max_dimension; Allocated size of default_coord_system + array (not used currently) */ +} coordbaseGH; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* _COORDBASE_COORDBASEGH_H_ */ diff --git a/src/make.code.defn b/src/make.code.defn new file mode 100644 index 0000000..0f94373 --- /dev/null +++ b/src/make.code.defn @@ -0,0 +1,8 @@ +# Main make.code.defn file for thorn CoordBase +# $Header$ + +# Source files in this directory +SRCS = CoordBase.c GHExtension.c + +# Subdirectories containing source files +SUBDIRS = -- cgit v1.2.3