From 52e3606b0e617ab168c5bb89dea3956a1be8d6cb Mon Sep 17 00:00:00 2001 From: schnetter Date: Tue, 4 Jul 2006 20:53:23 +0000 Subject: Explain how to convert between integer and CCTK_INT in Fortran. git-svn-id: http://svn.cactuscode.org/flesh/trunk@4340 17b73243-c579-4c4c-a9d2-2d5706c11dac --- doc/UsersGuide/ThornWriters.tex | 119 +++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 15 deletions(-) (limited to 'doc') diff --git a/doc/UsersGuide/ThornWriters.tex b/doc/UsersGuide/ThornWriters.tex index 1ab710e0..bc56a993 100644 --- a/doc/UsersGuide/ThornWriters.tex +++ b/doc/UsersGuide/ThornWriters.tex @@ -1255,7 +1255,7 @@ each thorn using the Cactus command line options \texttt{-o} and \texttt{-O} Parameters can be of these types: \begin{Lentry} -\item[Integer] Can take any integral value +\item[Int] Can take any integral value \item[Real] Can take any floating point value \item[Keyword] Can have a value consisting of one of a choice of strings \item[Boolean] Can be true or false ({\t 1}, {\t t}, {\t true}, or @@ -1268,7 +1268,7 @@ Each parameter can be validated against a set of allowed The nature of the range is determined by the type of parameter, as follows: -\subsection{Integer} +\subsection{Int} The range specification is of the form @@ -4371,7 +4371,7 @@ Data Type & Size (bytes) & Variable Type & Fortran Equivalent\\ The availability of these types, and the corresponding C data types are platform-dependent. For each fixed-size data type there exists a corresponding preprocessor macro {\t HAVE\_} which should be used -to check whether the given CCTK data type is supported, e.g. +to check whether the given CCTK data type is supported, e.g.\ \begin{verbatim} /* declare variable with extended-precision complex data type if available @@ -4440,24 +4440,113 @@ files): \begin{center} \begin{tabular}{|l|l|l|} \hline -Data Type & Variable Type & C equivalent \\ -\hline -{\t CCTK\_POINTER} & {\t CCTK\_VARIABLE\_POINTER} - & {\t void *data\_ptr} \\ -{\t CCTK\_POINTER\_TO\_CONST} & {\t CCTK\_VARIABLE\_POINTER} - & {\t const void *data\_ptr} \\ -{\t CCTK\_FPOINTER} & {\t CCTK\_VARIABLE\_FPOINTER} - & {\t void (*fn\_ptr)(void)} \\ -\hline + Data Type & + Variable Type & + C equivalent +\\\hline + {\t CCTK\_POINTER} & + {\t CCTK\_VARIABLE\_POINTER} & + {\t void *data\_ptr} +\\ + {\t CCTK\_POINTER\_TO\_CONST} & + {\t CCTK\_VARIABLE\_POINTER\_TO\_CONST} & + {\t const void *data\_ptr} +\\ + {\t CCTK\_FPOINTER} & + {\t CCTK\_VARIABLE\_FPOINTER} & + {\t void (*fn\_ptr)(void)} +\\\hline \end{tabular} \end{center} \subsection{Fortran Thorn Writers} -Cactus provides a further data type \texttt{CCTK\_POINTER} -for use in Fortran code to declare a pointer passed from C. -for example, the variable \texttt{cctkGH} is of this type. +Cactus provides the data types \texttt{CCTK\_POINTER} and +\texttt{CCTK\_POINTER\_TO\_CONST} for use in Fortran code to declare a +pointer passed from C. For example, the variable \texttt{cctkGH} is +of the type \texttt{CCTK\_POINTER}. The data type +\texttt{CCTK\_STRING} is in Fortran also an opaque type, corresponding +to a C pointer, and one has to use the function +\texttt{CCTK\_FortranString} to convert it to a Fortran string, or the +\texttt{CCTK\_Equals} to compare it to a Fortran String. + +Since the data types \texttt{integer} in Fortran and \texttt{int} in C +may be different,% +\footnote{This is only a theoretical possibility, in practice they + have to be the same type for Cactus to work at all.}% +many routines that can be called from both C and Fortran take +arguments of the type \texttt{CCTK\_INT}. This type can be different +from the type \texttt{integer}. Fortran does not convert routine +arguments automatically, and it is therefore necessary to pay +attention to the exact argument types that a routine expects, and to +converte between \texttt{integer} and \texttt{CCTK\_INT} accordingly. +Currently, most flesh functions take \texttt{integer} arguments, while +all aliased functions take \texttt{CCTK\_INT} arguments. + +\begin{quote} + NOTE: If you make errors in passing Fortran arguments, and if there + are no interfaces (``prototypes'') available for the routines that + are called, then the compiler cannot detect these errors. Be + careful. When you write Fortran code yourself, consider placing + routines in modules, which implicitly define interfaces for all + contained routines. +\end{quote} + +There are two convenient ways to convert between these types. An easy +way is to define parameters or to declare variables of the desired +type, assign a value to these parameters or variables, and then pass +the parameter or value. This makes for very readable code, since the +name of the paramter or variable serves as additional documentation: + +\begin{verbatim} +CCTK_INT, parameter : jtwo = 2 +integer :: vindex_gxx, vindex_kxx +CCTK_INT :: syncvars(jtwo) + +call CCTK_VarIndex (vindex_gxx, "ADMBase::gxx") +call CCTK_VarIndex (vindex_kxx, "ADMBase::kxx") + +syncvars(1) = vindex_gxx +syncvars(2) = vindex_kxx +call CCTK_SyncGroupsI (cctkGH, jtwo, syncvars) +\end{verbatim} + +(You have probably seen the strange Fortran convention where people +introduce constants named \texttt{zero} or \texttt{two}. This is the +reason for this --- it is a convenient way to make sure that the +constant has the correct type.) + +Another possibility are explicit type conversions. They can rather +easily be added to existing code: + +\begin{verbatim} +! Boilerplate code to determine type kinds +integer, parameter :: izero = 0 ! A dummy variable of type integer +CCTK_INT, parameter :: jzero = 0 ! A dummy variable of type CCTK_ITN +integer, parameter :: ik = kind (izero) ! The kind of "integer" +integer, parameter :: jk = kind (jzero) ! The kind of "CCTK_INT" + +integer :: syncvars(2) + +call CCTK_VarIndex (syncvars(1), "ADMBase::gxx") +call CCTK_VarIndex (syncvars(2), "ADMBase::kxx") + +call CCTK_SyncGroupsI (cctkGH, int(2,jk), int(syncvars,jk)) +\end{verbatim} + +Fortran distinguishen between different integer \emph{kinds}. These +kinds are what is different between \texttt{integer} and +\texttt{CCTK\_INT}. The expression \texttt{int(EXPR,KIND)} converts +\texttt{EXPR} to an integer of kind \texttt{KIND}. Above, we use the +convention that the prefix \texttt{i} denotes things having to do with +\texttt{integer}, and the prefix \texttt{j} denotes +\texttt{CCTK\_INT}. + +Note that we declare the array \texttt{syncvars} with the type that is +necessary to set its values. Type conversions are only possible if +variables are read, not when they are written to. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3