\begin{cactuspart}{2}{Application thorn writing}{$RCSfile$}{$Revision$} \renewcommand{\thepage}{\Alph{part}\arabic{page}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Thorn concepts} (This section has to contain enough explanation to make the rest of the writers guide readable the first time through) (The hardest bugs to find are those arising from plausible but incorrect assumptions about the behavior of someone else's thorn.) \begin{itemize} \item Again probably emphasize collaboration, what are thorns, packages, how to share them. \item Things to think about before you start programming: Language, read all the documentation, emphasize use of standard supported Cactus infrastructure \item Available data types \begin{itemize} \item Groups \item Scalars \item Arrays and GFs \end{itemize} \item Understanding the RFR concept \item Understanding the GH concept \item Ghost zones and parallelism \end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Packages} Thorns are grouped into {\em packages}. This is a logical grouping of thorns which is purely for administrative purposes. The compiled code knows nothing about packages. The packages live in the `packages' directory off the main CCTK directory. Package names must be unique, and cannot start with a `\#', or finish with `~' or `.bak'. Inside a package directory there is a directory for each thorn belonging to the package. Thorn names have the same restrictions as package names, with the addition that a thorn cannot be called `doc'. This name is reserved for package documentation. \section{Implementations} One of the key concepts for thorns is the concept of the {\bf implementation}. Relationships between thorns are all based upon relationship between {\bf implementations} and in principle it should be possible to replace one thorn providing an implementation with another thorn providing that implementation without affecting any other thorn. An {\bf implementation} defines a group of variables and parameters which are used to implement some functionality. For example the thorn {\tt CactusPUGH/PUGH} provides the implementation {\tt driver}. This implementation is responsible for providing memory for grid variables and for communication. Another thorn can also implement {\tt driver}, and both thorns can be compiled in {\em at the same time}. Then, at runtime, the user can decide which thorn providing {\tt driver} is used. No other thorn should be affected by this choice. When a thorn decides it needs access to a variable or a parameter provided by another thorn, it defines a relationship between itself and the other thorn's implementation, not explicitly with the other thorn. This allows the transparent replacement, at compile or runtime, of one thorn with another thorn providing the same functionality as seen by the other thorns. \section{Data Types and Sizes} Cactus supports the following fixed size data types \begin{center} \begin{tabular}{|c|c|c|c|} \hline Data Type & Size (bytes) & Variable Type & Fortran Equivalent\\ \hline {\t CCTK\_INT2} & 2 & {\t CCTK\_VARIABLE\_INT2} & {\t integer*2}\\ {\t CCTK\_INT4} & 4 & {\t CCTK\_VARIABLE\_INT4} & {\t integer*4}\\ {\t CCTK\_INT8} & 8& {\t CCTK\_VARIABLE\_INT8} & {\t integer*8}\\ {\t CCTK\_REAL4} & 4 & {\t CCTK\_VARIABLE\_REAL4} & {\t real*4}\\ {\t CCTK\_REAL8} & 8 & {\t CCTK\_VARIABLE\_REAL8} & {\t real*8}\\ {\t CCTK\_REAL16} & 16& {\t CCTK\_VARIABLE\_REAL16} & {\t real*16}\\ {\t CCTK\_COMPLEX4} & 4 & {\t CCTK\_VARIABLE\_COMPLEX4} & {\t complex*4}\\ {\t CCTK\_COMPLEX8} & 8 & {\t CCTK\_VARIABLE\_COMPLEX8} & {\t complex*8}\\ {\t CCTK\_COMPLEX16}& 16& {\t CCTK\_VARIABLE\_COMPLEX16}& {\t complex*16}\\ {\t CCTK\_CHAR} & 1 & {\t CCTK\_VARIABLE\_CHAR} & {\t character} \\ \hline \end{tabular} \end{center} In addition Cactus provides three data types whose size is chosen during the compilation process (at configuration time). This is to allow the code to be easily run at different precisions. Note that the effectiveness of running the code at a lower or higher precision depends crucially on all thorns being used making consistent use of the following data types: \begin{center} \begin{tabular}{|c|c|c|c|} \hline Data Type & Default Size (bytes) & Variable Type & Configuration Option\\ \hline {\t CCTK\_INT} & 4 & {\t CCTK\_VARIABLE\_INT} & {\t INTEGER\_PRECISION}\\ {\t CCTK\_REAL} & 8 & {\t CCTK\_VARIABLE\_REAL} & {\t REAL\_PRECISION}\\ {\t CCTK\_COMPLEX} & (8,8) & {\t CCTK\_VARIABLE\_COMPLEX} & Same as real precision\\ \hline \end{tabular} \end{center} These variable types must be used by thorn writers to declare variables in the thorn interface files (FIXME: REF), and may be used to declare variables in the thorn routines. Note that variable declarations in thorns should obviously match with definitions in the interface files where appropriate. Also provided, are a set of macros which are interpreted by the preprocessor at compile time to signify which data size is being used: \begin{center} \begin{tabular}{|c|c|} \hline Data Type & {\t \#define}\\ {\t CCTK\_INT2} & {\t CCTK\_INT\_PRECISION\_2} \\ {\t CCTK\_INT4} & {\t CCTK\_INT\_PRECISION\_4} \\ {\t CCTK\_INT8} & {\t CCTK\_INT\_PRECISION\_8} \\ {\t CCTK\_REAL4} & {\t CCTK\_REAL\_PRECISION\_4} \\ {\t CCTK\_REAL8} & {\t CCTK\_REAL\_PRECISION\_8} \\ {\t CCTK\_REAL16} & {\t CCTK\_REAL\_PRECISION\_16} \\ {\t CCTK\_COMPLEX4} & {\t CCTK\_COMPLEX\_PRECISION\_4} \\ {\t CCTK\_COMPLEX8} & {\t CCTK\_COMPLEX\_PRECISION\_8} \\ {\t CCTK\_COMPLEX16} & {\t CCTK\_COMPLEX\_PRECISION\_16} \\ \hline \end{tabular} \end{center} Note that the availability of these types, and the corresponding C data types are platform dependent. \subsection{Fortran Thorn Writers} Cactus provides a further data type {\tt CCTK\_POINTER} for use in Fortran code to declare a pointer passed from C. For example, the variable {\tt cctkGH} is of this type. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Anatomy of a thorn} \section{thorns} A thorn consists of a subdirectory of a package containing three administrative files \begin{itemize} \item{\tt interface.ccl}: the cactus interface, which defines the grid functions, variables, etc. See \ref{sec:in}. \item{\tt param.ccl}: the parameters introduced by the thorn. See \ref{param.ccl}. \item{\tt schedule.ccl}: scheduling information for routines called by the flesh. \end{itemize} Thorns can also contain \begin{itemize} \item a subdirectory called {\tt src}, which should hold source files \item a subdirectory {\tt src/include} for include files \item a {\tt README} containing a brief description of the thorn \item a {\tt doc} directory for documentation \item a {\tt par} directory for example parameter files \item a {\tt test} subdirectory may also be added. See \ref{sec:testsuites} for details. \end{itemize} \section{Creating a thorn} To simplify the creation of a thorn, a make target {\tt gmake newthorn} has been provided. When this is run: \begin{enumerate} \item{} You will be prompted for the name of the new thorn. \item{} You will be prompted for the name of the package you would like to include your thorn in. Either enter a new package name or pick one from the list of available packages that are shown. \end{enumerate} \section{Configuring your thorn} The interaction of a thorn with the flesh and other thorns is controlled by various configuration files. These consist of: \begin{itemize} \item {\tt interface.ccl} This defines the {\bf implementation} the thorn provides, and the variables the thorn needs, along with their visibility to other implementations. \item {\tt param.ccl} This defines the parameters that are used to control the thorn, along with their visibility to other implementations. \item {\tt schedule.ccl} This defines which functions from the thorn are called and when they are called. \end{itemize} \subsection{General syntax of CCL files} CCL {\bf Cactus Configuration Language} files are simple text files used to define configuration information for a thorn. CCL files are case independent, and may contain comments introduced by the `\#' character, which marks the rest of the line to the right of its appearence as a comment. \subsection{The {\tt interface.ccl}} The {\tt interface.ccl} file is used to declare the implementation provided by the thorn, and to define the variables provided by it. The implementation is declared by a single line \begin{verbatim} implements: \end{verbatim} at the top of the file. can be any combination of alphanumeric characters and underscores, and is case independent as per everything else in a CCL file. There are three different access levels available for variables \begin{itemize} \item {\tt Public} Can be `inherited' by other implementations (see below). \item {\tt Protected} Can be shared with other implementations which declare themselves to be friends of this one (see below). \item {\tt Private} Can only be seen by this thorn. \end{itemize} Corresponding to the first two access levels there are two relationship statements that can be used to get variables from other thorns. \begin{itemize} \item {\tt Inherits: } This gets all {\tt Public} variables from implementation , plus all variables it has in turn inherited. An implementation may inherit from as many thorns as it likes. \item {\tt Friend: } This gets all {\tt Protected} variables from implementation , but, unlike {\tt inherits} it pushes this implementations {\tt Protected} vaiables onto implementation . This keyword is used to define a group of implementations which all end up with the same {\tt Protected} variables. \end{itemize} So, for example, an interface.ccl starting \begin{verbatim} implements: wavetoy inherits: grid friend: wave_extract \end{verbatim} declares that the thorn provides an implementation called `wavetoy', gets all {\tt public} variables declared by an implementation called `grid', and shares all {\tt protected} variables with `wave\_extract' and its friends. For convenience variables are placed in groups. The group has several attributes: \begin{itemize} \item {\tt variable type} e.g. REAL, INT, COMPLEX \item {\tt name} The name of the group \item {\tt group type} \begin{itemize} \item {\tt SCALAR} This is a single number. \item {\tt GF} This is an array of the default grid size. \item {\tt ARRAY} This is an array of any size. \end{itemize} \item {\tt Dim} This is the dimension of the group. (Meaningless for scalars.) \item {TimeLevels} This is the number of timelevels the group has. \end{itemize} A group specification consists of the variable type, followed by the name of the group, then a space seperated list of the form `attribute = value' . Then a brace delimited block containing a comma or newline seperated list of variables in the group. A description of the group may be included on the line with the closing brace. For example \begin{verbatim} REAL fields type=GF TimeLevels=3 Dim=3 { phi a,b,c,d } "Wave fields" \end{verbatim} defines a group of real GFs of dimension 3 each of which exists on three time levels. By default all groups are {\tt private}, to change this an access specification of the form {\tt public:} or {\tt protected:} (or {\tt private:} to change it back) may be placed on a line by itself. This changes the access level for any group defined in the file from that point on. All variables seen by any one thorn must have distinct names. \subsection{The {\tt param.ccl}} Users control the operation of thorns via parameters. The {\tt param.ccl} is used to specify the parameters used to control an individual thorn, and to specify the values these parameters are allowed to take. When the code is run it reads a parameter file and sets the parameters if they fall within the allowed values. There are three access levels available for parameters: \begin{itemize} \item {\tt Global} These parameters are seen by all thorns. \item {\tt Restricted} These parameters may be used by other implementations if they so desire. \item {\tt Private} These are only seen by this thorn. \end {itemize} A parameter specification consists of: \begin{itemize} \item {\tt the parameter type} \begin{itemize} \item {\tt REAL} \item {\tt INT} \item {\tt KEYWORD} A distinct string with only a few known allowed values. \item {\tt STRING} An arbitrary string, which must conform to a given regular expression. \item {\tt LOGICAL} A boolean type which can take values 1, `t', `true', `yes' or 0, `f', `false', `no'. \end{itemize} \item {\tt A description of the parameter} \item {An allowed value block} This consists of a brace delimited block of lines describing the allowed values of the parameter. Each range may have a description associated with it by placing a :: on the line and putting the description afterwards. \item {\tt The default value} This must be one of the allowed values. \end{itemize} For the numeric types INT and REAL, a range consists of a string of the forms lower-bound:upper-bound:step where a missing number or a \* denotes anything (i.e. infinite bounds or an infinitesmal step). For example \begin{verbatim} REAL Coeff "Important coefficient" { 0:3.14 :: "Range has to be from zero to Pi, default is zero" } 0.0 #No need to define a range for LOGICAL LOGICAL nice "Nice weather ?" { }"yes" # A example for a set of keywords and its default (which has to be # defined in the body) KEYWORD confused "Are we getting confused ?" { "yes" :: "absolutley positively" "perhaps" :: "we are not sure" "never" :: "never" } "never" \end{verbatim} defines a REAL parameter, a LOGICAL parameter, and a KEYWORD. By default all paramters are {\tt private}, to change this an access specification of the form {\tt global:} or {\tt restricted:} (or {\tt private:} to change it back) may be placed on a line by itself. This changes the access level for any parameter defined in the file from that point on. To access {\tt restricted} parameters from another implementation, a line containing {\tt shares: } declares that all parameters mentioned in the file from now until the next access specification originate in implementation . In contrast to parameter declarations in other access blocks, the default value must be ommitted - it is impossible to set the default value of any parameter not originating in this thorn. For example \begin{verbatim} friend:einstein KEYWORD initial_data "" { "bl_bh" :: "Brill Lindquist black holes" "misner_bh" :: "Misner black holes" "schwarzschild" :: "One Schwarzshild black hole" } \end{verbatim} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The {\tt schedule.ccl}} By default no routine of a thorn will be run. The schedule.ccl file defines those that should be run and when they should be run. The specification of this is via a schudule block which consists of a line of the form \begin{verbatim} schedule at