aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorknarf <knarf@e77735cb-7dd8-4a7a-87c7-7cc99eb84b11>2009-12-02 22:22:51 +0000
committerknarf <knarf@e77735cb-7dd8-4a7a-87c7-7cc99eb84b11>2009-12-02 22:22:51 +0000
commitcf7a8b58f4ae85517bbe0797efdc95c2a539d76e (patch)
treec08f92fb96a6b7a23fd3505fb50c6632f6ce99de
parent6fc52426d1c824b998cf2c6039a6fea4166d621c (diff)
thorns for general eos interface (moved from Whisky_Dev repositories)
git-svn-id: http://svn.einsteintoolkit.org/cactus/EinsteinBase/EOSG_Base/trunk@2 e77735cb-7dd8-4a7a-87c7-7cc99eb84b11
-rwxr-xr-xREADME9
-rwxr-xr-xconfiguration.ccl8
-rwxr-xr-xdoc/documentation.tex457
-rwxr-xr-xinterface.ccl29
-rwxr-xr-xparam.ccl2
-rwxr-xr-xschedule.ccl8
-rwxr-xr-xsrc/EOSBase_Register.c1094
-rwxr-xr-xsrc/EOS_Utils.c68
-rwxr-xr-xsrc/EOS_Utils.h16
-rwxr-xr-xsrc/make.code.defn9
-rw-r--r--test/test1
11 files changed, 1701 insertions, 0 deletions
diff --git a/README b/README
new file mode 100755
index 0000000..77acde4
--- /dev/null
+++ b/README
@@ -0,0 +1,9 @@
+CVS info : $Header$
+
+Cactus Code Thorn EOSBase_General
+Thorn Author(s) : Ian Hawke <ih@maths.soton.ac.uk>
+Thorn Maintainer(s) : Ian Hawke <ih@maths.soton.ac.uk>
+--------------------------------------------------------------------------
+
+Purpose of the thorn:
+
diff --git a/configuration.ccl b/configuration.ccl
new file mode 100755
index 0000000..d9f5dfc
--- /dev/null
+++ b/configuration.ccl
@@ -0,0 +1,8 @@
+# Configuration definitions for thorn EOSBase_General
+# $Header$
+
+PROVIDES EOSBase_General
+{
+ SCRIPT
+ LANG
+}
diff --git a/doc/documentation.tex b/doc/documentation.tex
new file mode 100755
index 0000000..b1cd8d9
--- /dev/null
+++ b/doc/documentation.tex
@@ -0,0 +1,457 @@
+% *======================================================================*
+% 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{Ian Hawke \textless ih@maths.soton.ac.uk\textgreater}
+
+% The title of the document (not necessarily the name of the Thorn)
+\title{General equations of state}
+
+% the date your document was last changed, if your document is in CVS,
+% please use:
+% \date{$ $Date$ $}
+\date{March 15 2005}
+
+\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}
+ This thorn provides a generalized equation of state interface.
+\end{abstract}
+
+% The following sections are suggestive only.
+% Remove them or add your own.
+
+\section{Equations of state}
+
+In solving the equations of hydrodynamics there are five independent
+variables (typically $\rho, v^i, \epsilon$ for the rest mass density,
+velocity and specific internal energy) and further variables, such as
+the pressure $P$ which depend on the independent variables. Such
+dependent variables are specified by an {\em equation of state} (EOS)
+that closes the system of equations. Simple EOSs depend only on the
+independent variables and are usually given in terms of the pressure,
+i.e.\ $P = P(\rho, \epsilon)$ which then implicitly defines other
+variables such as the temperature $T$, pressure derivatives $P_{\rho},
+P_{\epsilon}$ and the speed of sound $c_s$.
+
+However there is no physical reason to prefer such simple EOSs. A
+realistic EOS will depend on the composition of the fluid as well as
+the independent variables. This thorn is meant to provide an interface
+so that a hydrodynamics code can depend on such a realistic EOS
+without having to know about the details of the composition --
+without, in fact, needing an knowledge of the additional variables
+required by the EOS at all.
+
+\section{Calling an EOS}
+
+The most efficient way of using the EOS is to call it to set grid
+functions. The interface is simple on the face of it; one function
+call will give you a {\em call handle}, and another function call will
+actually set the EOS. The complexity comes in setting up the key value
+tables involved in the function calls.
+
+\begin{FunctionDescription}{EOS\_SetupCall}
+ \label{Whisky_Dev_EOSBase_General_EOS_SetupCall}
+
+ Sets up an equation of state call. If the call handle is stored
+ (which is recommended) then this only needs to be performed once at
+ startup time, and the call handle can be reused.
+
+ \begin{SynopsisSection}
+ \begin{Synopsis}{C}
+\begin{verbatim}
+CCTK_INT call_handle = EOS_SetupCall(CCTK_INT table_handle)
+\end{verbatim}
+ \end{Synopsis}
+ \begin{Synopsis}{Fortran}
+\begin{verbatim}
+CCTK_INT call_handle = EOS_SetupCall(CCTK_INT table_handle)
+\end{verbatim}
+ \end{Synopsis}
+ \end{SynopsisSection}
+
+ \begin{ResultSection}
+ \begin{ResultNote}
+ The {\tt call\_handle} return must be stored for later use in
+ the EOS call. The value should be $\geq 0$. Typically a level
+ 0 warning will be given rather than returning an error code.
+ \end{ResultNote}
+ \begin{Result}{$\geq 0$}
+ The call handle, to be stored for later use.
+ \end{Result}
+ \end{ResultSection}
+
+ \begin{ParameterSection}
+ \begin{Parameter}{table\_handle}
+ The handle of an existing key value table. Appropriate
+ arguments will be described elsewhere.
+ \end{Parameter}
+ \end{ParameterSection}
+
+ \begin{Discussion}
+ The complexity comes in setting up the key-value table to be
+ passed through. Effectively any arguments can be given that will
+ be interpreted by the EOS, but the following are expected (note
+ capitalization - it is always useful to set up the table using the
+ CASE INSENSITIVE flag):
+ \begin{itemize}
+ \item {\tt EOS Name}: This must correspond to the name that the
+ EOS thorn has registered.
+ \item {\tt Independent variable names}: This is a string (a
+ CCTK\_STRING) of whitespace separated names describing the
+ independent variables. Although there is no particular values
+ for these ``names'' required by this base thorns the following
+ conventions for variable names have been used in existing thorns
+ (name in parantheses is the variable name in {\sc whisky}):
+ \begin{itemize}
+ \item {\tt Rho}: Rest mass density ({\tt rho})
+ \item {\tt SpecificInternalEnergy}: Specific internal energy
+ ({\tt eps})
+ \item {\tt Pressure}: Pressure ({\tt press})
+ \item {\tt DPressureDRho}: Partial derivative of pressure with
+ respect to rest mass density, all else being fixed ({\tt
+ dpdrho})
+ \item {\tt DPressureDSpecificInternalEnergy}: Partial derivative
+ of pressure with respect to specific internal energy, all else
+ being fixed ({\tt dpdeps})
+ \item {\tt c\_s\^{}2}: Speed of sound squared ({\tt cs2}).
+ \end{itemize}
+ \item {\tt Dependent variable names}: A string describing the
+ dependent variables, following the same syntax as the {\tt
+ Independent variable names}
+ \item {\tt N independent variables}: The number of independent
+ variables
+ \item {\tt N dependent variables}: The number of dependent
+ variables
+ \item {\tt Independent GFs}: An array of integers containing the
+ indices of the grid functions corresponding to the independent
+ variables. E.g., if the first dependent variable name is {\tt
+ Rho} which is contained in the grid function {\tt whisky::rho}
+ then the first entry of this array is found from {\tt
+ CCTK\_VarIndex("whisky::rho")}.
+ \item {\tt Dependent GFs}: An array of integers containing the
+ indices of the dependent grid functions, following the syntax of
+ the {\tt Independent GFs}.
+ \end{itemize}
+ \end{Discussion}
+
+ \begin{SeeAlsoSection}
+ \begin{SeeAlso}{EOS\_SetGFs}
+ Sets the EOS.
+ \end{SeeAlso}
+ \end{SeeAlsoSection}
+\end{FunctionDescription}
+
+
+
+\begin{FunctionDescription}{EOS\_SetGFs}
+ \label{Whisky_Dev_EOSBase_General_EOS_SetGFs}
+
+ Actually sets the dependent GFs in an EOS call. The call must have
+ been previously set up using EOS\_SetupCall. Must be called from
+ routines scheduled in {\tt local} mode.
+
+ \begin{SynopsisSection}
+ \begin{Synopsis}{C}
+\begin{verbatim}
+CCTK_INT ierr = EOS_SetGFs(CCTK_POINTER_TO_CONST cGH, CCTK_INT call_handle)
+\end{verbatim}
+ \end{Synopsis}
+ \begin{Synopsis}{Fortran}
+\begin{verbatim}
+CCTK_INT ierr = EOS_SetGFs(CCTK_POINTER_TO_CONST cGH, CCTK_INT call_handle)
+\end{verbatim}
+ \end{Synopsis}
+ \end{SynopsisSection}
+
+ \begin{ResultSection}
+ \begin{ResultNote}
+ The {\tt call\_handle} should have been previously set up by
+ EOS\_SetupCall. Currently only successful returns (0) are
+ given.
+ \end{ResultNote}
+ \begin{Result}{\rm 0}
+ success.
+ \end{Result}
+ \end{ResultSection}
+
+ \begin{ParameterSection}
+ \begin{Parameter}{cGH}
+ The Cactus GH structure, and the reason why this must be called
+ in {\tt local} mode.
+ \end{Parameter}
+ \begin{Parameter}{call\_handle}
+ An EOS call previously set up by EOS\_SetupCall.
+ \end{Parameter}
+ \end{ParameterSection}
+
+ \begin{Discussion}
+ Once the EOS call has been setup this routine basically tells the
+ EOS function to apply the appropriate EOS calls at this point to
+ the appropriate arrays.
+ \end{Discussion}
+
+ \begin{SeeAlsoSection}
+ \begin{SeeAlso}{EOS\_SetupCall}
+ Setup the EOS call.
+ \end{SeeAlso}
+ \end{SeeAlsoSection}
+\end{FunctionDescription}
+
+\pagebreak
+\section{Registering an EOS}
+
+Before you can use an EOS one first has to be registered. The best way
+of learning how to do this is to look at the example thorns, such as
+the ``generalized'' polytropic EOS (thorn {\tt EOS\_GeneralPolytrope}) or
+ideal gas EOS (thorn {\tt EOS\_GeneralIdealFluid}). Here is just the
+essential description.
+
+The essential thing that is required is a function (probably in C,
+although in theory it's language independent) that sets arbitrary
+sized arrays\footnote{The arbitrariness applies to the different
+ calls, not different arrays: all arrays, whether for independent or
+ dependent variables are assumed to have the same size in any given
+ call.} of dependent variables from the independent variables. This
+function is registered using the aliased function {\tt
+ EOS\_RegisterCall}. This function, and the function pointer that
+must be called, are as follows.
+
+
+
+
+\begin{FunctionDescription}{EOS\_RegisterCall}
+ \label{Whisky_Dev_EOSBase_General_EOS_RegisterCall}
+
+ Register an EOS with the base thorn.
+
+ \begin{SynopsisSection}
+ \begin{Synopsis}{C}
+\begin{verbatim}
+CCTK_INT ierr = EOS_RegisterCall(CCTK_INT table_handle, \
+ CCTK_INT CCTK_FPOINTER EOS_fn(...))
+\end{verbatim}
+ \end{Synopsis}
+ \begin{Synopsis}{Fortran}
+\begin{verbatim}
+CCTK_INT ierr = EOS_RegisterCall(CCTK_INT table_handle, \
+ CCTK_INT CCTK_FPOINTER EOS_fn(...))
+\end{verbatim}
+ \end{Synopsis}
+ \end{SynopsisSection}
+
+ \begin{ResultSection}
+ \begin{ResultNote}
+ The function pointer {\tt EOS\_fn} is described below on
+ page~\pageref{Whiskty_Dev_EOSBase_General_EOS_fn}.
+
+ Currently only successful returns (0) are given.
+ \end{ResultNote}
+ \begin{Result}{\rm 0}
+ success.
+ \end{Result}
+ \end{ResultSection}
+
+ \begin{ParameterSection}
+ \begin{Parameter}{table\_handle}
+ A key/value table containing any persistent information that the
+ EOS thorn may want to store. This is not used by the base thorn,
+ and is there for the convenience of the EOS thorn.
+ \end{Parameter}
+ \begin{Parameter}{EOS\_fn}
+ A function pointer for the EOS call itself, described below.
+ \end{Parameter}
+ \end{ParameterSection}
+
+ \begin{Discussion}
+ The table can be used to differentiate between different
+ calls. For example, if one thorn implements many different
+ EOSs and the number is not known at compile time (e.g., a table
+ interpolator thorn that provides multiple tables) then only one
+ registration need take place, and the key/value table can be used
+ store which (interpolation) table is being used in the particular
+ call.
+ \end{Discussion}
+
+ \begin{SeeAlsoSection}
+ \begin{SeeAlso}{EOS\_fn}
+ The actual EOS function.
+ \end{SeeAlso}
+ \end{SeeAlsoSection}
+\end{FunctionDescription}
+
+
+\begin{FunctionDescription}{EOS\_fn}
+ \label{Whisky_Dev_EOSBase_General_EOS_fn}
+
+ The actual EOS function that must be provided.
+
+ \begin{SynopsisSection}
+ \begin{Synopsis}{C}
+\begin{verbatim}
+CCTK_INT ierr = EOS_fn(CCTK_INT param_table, \
+ CCTK_INT n_elems, \
+ CCTK_POINTER* indep_arrays, \
+ CCTK_INT* which_dep_arrays_to_set, \
+ CCTK_POINTER* dep_arrys)
+\end{verbatim}
+ \end{Synopsis}
+ \begin{Synopsis}{Fortran}
+\begin{verbatim}
+CCTK_INT ierr = EOS_fn(CCTK_INT param_table, \
+ CCTK_INT n_elems, \
+ CCTK_POINTER* indep_arrays, \
+ CCTK_INT* which_dep_arrays_to_set, \
+ CCTK_POINTER* dep_arrys)
+\end{verbatim}
+ \end{Synopsis}
+ \end{SynopsisSection}
+
+ \begin{ResultSection}
+ \begin{ResultNote}
+ Currently only successful returns (0) are given.
+ \end{ResultNote}
+ \begin{Result}{\rm 0}
+ success.
+ \end{Result}
+ \end{ResultSection}
+
+ \begin{ParameterSection}
+ \begin{Parameter}{param\_table}
+ A key/value table containing any persistent information that the
+ EOS thorn may want to store. This is not used by the base thorn,
+ and is there for the convenience of the EOS thorn.
+ \end{Parameter}
+ \begin{Parameter}{n\_elems}
+ The size of the arrays that are passed in.
+ \end{Parameter}
+ \begin{Parameter}{indep\_arrays}
+ The independent arrays (should essentially be cast to a {\tt
+ CCTK\_REAL**}).
+ \end{Parameter}
+ \begin{Parameter}{which\_dep\_arrays\_to\_set}
+ An array telling the EOS thorn which dependent arrays should be
+ set in this thorn. This is important because dependent arrays
+ that are not needed will NOT be passed in the call; see below.
+ \end{Parameter}
+ \begin{Parameter}{dep\_arrays}
+ The dependent arrays (should essentially be cast to a {\tt
+ CCTK\_REAL**}). Note that you should not assume that all these
+ pointers are non-null (hence the difficulty in using this with
+ Fortran). In general, if the calling thorn does NOT request that
+ a dependent variable be set then the equivalent pointer WILL be
+ null.
+ \end{Parameter}
+ \end{ParameterSection}
+
+ \begin{Discussion}
+ The table can be used to differentiate between different
+ calls. For example, if one thorn implements many different
+ EOSs and the number is not known at compile time (e.g., a table
+ interpolator thorn that provides multiple tables) then only one
+ registration need take place, and the key/value table can be used
+ store which (interpolation) table is being used in the particular
+ call.
+ \end{Discussion}
+
+ \begin{SeeAlsoSection}
+ \begin{SeeAlso}{EOS\_RegisterCall}
+ Register the EOS function with the base thorn.
+ \end{SeeAlso}
+ \end{SeeAlsoSection}
+\end{FunctionDescription}
+
+
+
+\begin{thebibliography}{9}
+
+\end{thebibliography}
+
+% Do not delete next line
+% END CACTUS THORNGUIDE
+
+\end{document}
diff --git a/interface.ccl b/interface.ccl
new file mode 100755
index 0000000..8d82044
--- /dev/null
+++ b/interface.ccl
@@ -0,0 +1,29 @@
+# Interface definition for thorn EOSBase_General
+# $Header$
+
+implements: EOSBase
+
+INCLUDES: EOS_Utils.h IN EOS_GeneralUtils.h
+
+CCTK_INT FUNCTION EOS_RegisterCall(CCTK_INT IN table_handle, \
+ CCTK_INT IN CCTK_FPOINTER \
+ EOS_fn(CCTK_INT IN param_table, \
+ CCTK_INT IN n_elems, \
+ CCTK_POINTER ARRAY IN indeps, \
+ CCTK_INT ARRAY IN which_deps, \
+ CCTK_POINTER ARRAY OUT deps))
+PROVIDES FUNCTION EOS_RegisterCall WITH EOSBase_Register LANGUAGE C
+
+CCTK_INT FUNCTION EOS_SetupCall(CCTK_INT IN table_handle)
+PROVIDES FUNCTION EOS_SetupCall WITH SetupCall LANGUAGE C
+
+CCTK_INT FUNCTION EOS_SetGFs(CCTK_POINTER_TO_CONST IN GH, \
+ CCTK_INT IN call_handle)
+PROVIDES FUNCTION EOS_SetGFs WITH SetGFs LANGUAGE C
+
+CCTK_INT FUNCTION EOS_SetArrays(CCTK_INT IN call_handle)
+PROVIDES FUNCTION EOS_SetArrays WITH SetArrays LANGUAGE C
+
+CCTK_INT FUNCTION EOS_SetInverseArrays(CCTK_INT IN call_handle, \
+ CCTK_INT IN table_handle)
+PROVIDES FUNCTION EOS_SetInverseArrays WITH SetInverseArrays LANGUAGE C
diff --git a/param.ccl b/param.ccl
new file mode 100755
index 0000000..f1d72a1
--- /dev/null
+++ b/param.ccl
@@ -0,0 +1,2 @@
+# Parameter definitions for thorn EOSBase_General
+# $Header$
diff --git a/schedule.ccl b/schedule.ccl
new file mode 100755
index 0000000..64b959c
--- /dev/null
+++ b/schedule.ccl
@@ -0,0 +1,8 @@
+# Schedule definitions for thorn EOSBase_General
+# $Header$
+
+
+schedule group EOSBase_GeneralRegister AT WRAGH
+{
+
+} "Register EOS Thorns with EOSBase_General"
diff --git a/src/EOSBase_Register.c b/src/EOSBase_Register.c
new file mode 100755
index 0000000..3275c85
--- /dev/null
+++ b/src/EOSBase_Register.c
@@ -0,0 +1,1094 @@
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+
+#include "util_String.h"
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#include "EOS_Utils.h"
+
+#define EOSBASE_DBG 1
+
+/*
+ This part is for thorns providing an EOS.
+*/
+
+/*
+ The structure for a single EOS function.
+*/
+
+typedef struct
+{
+ const char* eos_name; /* The name of the EOS, required to match the call */
+ CCTK_INT param_table; /* The parameter table allows the EOS
+ to store persistent information */
+ CCTK_INT n_indeps; /* The number of independent variables
+ the EOS requires */
+ CCTK_INT n_deps; /* The number of dependent variables
+ the EOS can return */
+ char **indep_names; /* The names (labels) of the independent variables */
+ char **dep_names; /* The names (labels) of the dependent variables */
+ CCTK_INT (*EOS_fn)(const CCTK_INT,
+ const CCTK_INT,
+ const CCTK_REAL**,
+ const CCTK_INT*,
+ CCTK_REAL**); /* The actual function pointer */
+} EOS_Function;
+
+/*
+ The list of all EOS functions.
+*/
+
+struct EOSFunctionList
+{
+ CCTK_INT n_eos_fns;
+ EOS_Function* Fns;
+} FnList;
+
+ /*@@
+ @routine SetupFnList
+ @date Fri Jun 10 04:37:10 2005
+ @author Ian Hawke
+ @desc
+ Initialize the list of functions.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+void SetupFnList()
+{
+ FnList.n_eos_fns = 0;
+ FnList.Fns = NULL;
+}
+
+ /*@@
+ @routine EOSBase_Register
+ @date Fri Jun 10 04:37:51 2005
+ @author Ian Hawke
+ @desc
+ The (aliased) function called by an EOS thorn to register its call.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+CCTK_INT
+EOSBase_Register(const CCTK_INT registered_table_handle,
+ CCTK_INT registered_EOS_fn(const CCTK_INT param_table,
+ const CCTK_INT n_dims,
+ const CCTK_POINTER* indep_vars,
+ const CCTK_INT* which_deps_to_set,
+ CCTK_POINTER* dep_vars))
+{
+
+ CCTK_INT ierr= 0, nfn, var, table_ierr;
+ const char *tmp_indep_names;
+ const char *tmp_dep_names;
+ const char* tmpbuffer;
+
+ CCTK_INT registered_n_indeps, registered_n_deps, strlength;
+
+ ++(FnList.n_eos_fns);
+ FnList.Fns = (EOS_Function*)realloc(FnList.Fns,
+ (FnList.n_eos_fns) *
+ sizeof(EOS_Function));
+ nfn = FnList.n_eos_fns - 1;
+
+ (FnList.Fns)[nfn].param_table = registered_table_handle;
+
+ table_ierr = Util_TableGetInt(registered_table_handle,
+ &registered_n_indeps,
+ "N independent variables");
+ if (table_ierr != 1)
+ {
+ CCTK_WARN(0, "What's the number of independent variables?");
+ }
+
+ table_ierr = Util_TableGetInt(registered_table_handle,
+ &registered_n_deps,
+ "N dependent variables");
+ if (table_ierr != 1)
+ {
+ CCTK_WARN(0, "What's the number of dependent variables?");
+ }
+
+ (FnList.Fns)[nfn].n_indeps = registered_n_indeps;
+ (FnList.Fns)[nfn].n_deps = registered_n_deps;
+
+ strlength = Util_TableGetString(registered_table_handle,
+ 0, NULL,
+ "EOS Name");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "What EOS do you actually want?");
+ }
+ (FnList.Fns)[nfn].eos_name =
+ (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(registered_table_handle,
+ (strlength+1), (FnList.Fns)[nfn].eos_name,
+ "EOS name");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ strlength = Util_TableGetString(registered_table_handle,
+ 0, NULL,
+ "Independent variable names");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "Which independent do you actually want?");
+ }
+ tmp_indep_names = (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(registered_table_handle,
+ (strlength+1), tmp_indep_names,
+ "Independent variable names");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ strlength = Util_TableGetString(registered_table_handle,
+ 0, NULL,
+ "Dependent variable names");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "Which dependent variables do you actually want?");
+ }
+ tmp_dep_names = (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(registered_table_handle,
+ (strlength+1), tmp_dep_names,
+ "Dependent variable names");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ (FnList.Fns)[nfn].EOS_fn = registered_EOS_fn;
+
+ (FnList.Fns)[nfn].indep_names = (char**)malloc(registered_n_indeps *
+ sizeof(char*));
+ tmpbuffer = EOS_StrSep(&tmp_indep_names, " ");
+ if (tmpbuffer == NULL) /* line is empty */
+ {
+ CCTK_WARN(0, "Error in the independent name string; empty???");
+ }
+ for (var = 0; var < registered_n_indeps; ++var)
+ {
+ while (*tmpbuffer == '\0')
+ {
+ tmpbuffer = EOS_StrSep(&tmp_indep_names, " ");
+ }
+ ((FnList.Fns)[nfn].indep_names)[var] = Util_Strdup(tmpbuffer);
+ tmpbuffer = EOS_StrSep(&tmp_indep_names, " ");
+ }
+
+ (FnList.Fns)[nfn].dep_names = (char**)malloc(registered_n_deps *
+ sizeof(char*));;
+ tmpbuffer = EOS_StrSep(&tmp_dep_names, " ");
+ if (tmpbuffer == NULL) /* line is empty */
+ {
+ CCTK_WARN(0, "Error in the dependent name string; empty???");
+ }
+ for (var = 0; var < registered_n_deps; ++var)
+ {
+ while (*tmpbuffer == '\0')
+ {
+ tmpbuffer = EOS_StrSep(&tmp_dep_names, " ");
+ }
+ ((FnList.Fns)[nfn].dep_names)[var] = Util_Strdup(tmpbuffer);
+ tmpbuffer = EOS_StrSep(&tmp_dep_names, " ");
+ }
+
+ ierr = 0;
+
+#ifdef EOSBASE_DBG
+ printf("An eos call has been registered. The call number was %d.\n"
+ "The eos name is '%s'.\n"
+ "The number of independent variables is %d.\n"
+ "The number of dependent variables is %d.\n",
+ FnList.n_eos_fns,
+ (FnList.Fns)[nfn].eos_name,
+ (FnList.Fns)[nfn].n_indeps,
+ (FnList.Fns)[nfn].n_deps);
+ for (var = 0; var < (FnList.Fns)[nfn].n_indeps; ++var)
+ {
+ printf("Independent variable %d is '%s'\n",
+ var, (FnList.Fns)[nfn].indep_names[var]);
+ }
+ for (var = 0; var < (FnList.Fns)[nfn].n_deps; ++var)
+ {
+ printf("Dependent variable %d is '%s'\n",
+ var, (FnList.Fns)[nfn].dep_names[var]);
+ }
+#endif
+
+ return ierr;
+}
+
+/*
+ This part is for thorns that want to call the EOS.
+*/
+
+/*
+ The structure describing a single EOS 'call'.
+*/
+
+typedef struct
+{
+ CCTK_INT fn_number; /* The number (in the EOS_FnList) of the EOS function */
+ CCTK_INT* indep_gfs; /* List of independent GF indices
+ (if not using arrays) */
+ CCTK_INT* dep_gfs; /* List of dependent GF indices
+ (if not using arrays) */
+ CCTK_INT* which_deps_to_set; /* List of which of the dependent variables
+ should be set */
+ CCTK_INT n_elems; /* Number of elements in the GFs/arrays */
+ CCTK_REAL** indep_vars; /* Pointers to the independent variable arrays
+ (if not using GFs) */
+ CCTK_REAL** dep_vars; /* Pointers to the dependent variable arrays
+ (if not using GFs) */
+} EOS_Call;
+
+/*
+ The structure describing the list of all EOS calls.
+*/
+
+struct EOSCallList
+{
+ CCTK_INT n_eos_calls;
+ EOS_Call* Calls;
+} CallList;
+
+ /*@@
+ @routine SetupCallList
+ @date Fri Jun 10 04:46:17 2005
+ @author Ian Hawke
+ @desc
+ Initialize the call list.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+void SetupCallList()
+{
+ CallList.n_eos_calls = 0;
+ CallList.Calls = NULL;
+}
+
+ /*@@
+ @routine SetupCall
+ @date Fri Jun 10 04:46:31 2005
+ @author Ian Hawke
+ @desc
+ Set up a single function call.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+CCTK_INT SetupCall(CCTK_INT table_handle)
+{
+
+ CCTK_INT ncall, i, strlength, call_number, type_code, n_entries,
+ ierr, n_elements, var, indep_var, dep_var;
+ const char* fn_name;
+ const char *local_indep_names;
+ const char *local_dep_names;
+ char *tmpbuffer;
+ CCTK_INT *tmp_indep_gfs;
+ CCTK_INT *tmp_dep_gfs;
+ CCTK_REAL **tmp_indep_arrays;
+ CCTK_REAL **tmp_dep_arrays;
+
+ ++(CallList.n_eos_calls);
+ CallList.Calls = (EOS_Call*)realloc(CallList.Calls,
+ (CallList.n_eos_calls) *
+ sizeof(EOS_Call));
+ ncall = CallList.n_eos_calls - 1;
+
+ strlength = Util_TableGetString(table_handle,
+ 0, NULL,
+ "EOS Name");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "What EOS do you actually want?");
+ }
+ fn_name = (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(table_handle,
+ (strlength+1), fn_name,
+ "EOS Name");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ for (call_number = 0; call_number < FnList.n_eos_fns; ++call_number)
+ {
+ if (CCTK_Equals(fn_name, FnList.Fns[call_number].eos_name)) break;
+ }
+ if (call_number < FnList.n_eos_fns)
+ {
+ CallList.Calls[ncall].fn_number = call_number;
+ }
+ else
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Failed to find eos function '%s'.",
+ fn_name);
+ }
+
+ if (Util_TableQueryValueInfo(table_handle, &type_code, &n_entries,
+ "Independent GFs"))
+ {
+ if (type_code != CCTK_VARIABLE_INT)
+ {
+ CCTK_WARN(0, "The independent GF indices must be passed as "
+ "a CCTK_INT array.");
+ }
+ if (n_entries != (FnList.Fns[call_number]).n_indeps)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The EOS function '%s' expects %d independent variables.\n"
+ "Your GF list only contains %d entries.",
+ fn_name, (FnList.Fns[call_number]).n_indeps,
+ n_entries);
+ }
+ tmp_indep_gfs = (CCTK_INT*)malloc(n_entries * sizeof(CCTK_INT));
+ (CallList.Calls[ncall]).indep_gfs = (CCTK_INT*)malloc(n_entries *
+ sizeof(CCTK_INT));
+ n_elements = Util_TableGetIntArray(table_handle,
+ (FnList.Fns[call_number]).n_indeps,
+ tmp_indep_gfs,
+ "Independent GFs");
+ if (n_elements != n_entries)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+ /* Now we have to order the independent gfs correctly */
+
+ strlength = Util_TableGetString(table_handle,
+ 0, NULL,
+ "Independent variable names");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "Need the independent variable names");
+ }
+ local_indep_names =
+ (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(table_handle,
+ (strlength+1), local_indep_names,
+ "Independent variable names");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ tmpbuffer = EOS_StrSep(&local_indep_names, " ");
+ if (tmpbuffer == NULL) /* line is empty */
+ {
+ CCTK_WARN(0, "Error in the independent name string; empty???");
+ }
+ for (var = 0; var < n_entries; ++var)
+ {
+ while (*tmpbuffer == '\0')
+ {
+ tmpbuffer = EOS_StrSep(&local_indep_names, " ");
+ }
+
+ (CallList.Calls[ncall]).indep_gfs[var] = -1;
+ for (indep_var = 0; indep_var < n_entries; ++indep_var)
+ {
+ if ( CCTK_Equals((FnList.Fns[call_number]).indep_names[indep_var],
+ tmpbuffer) )
+ {
+ (CallList.Calls[ncall]).indep_gfs[var] = tmp_indep_gfs[indep_var];
+ }
+ }
+ if ( (CallList.Calls[ncall]).indep_gfs[var] < 0 )
+ {
+ CCTK_WARN(0, "Failed to set up the independent variables?");
+ }
+ tmpbuffer = EOS_StrSep(&local_indep_names, " ");
+ }
+
+ if (Util_TableQueryValueInfo(table_handle, &type_code, &n_entries,
+ "Dependent GFs"))
+ {
+ if (type_code != CCTK_VARIABLE_INT)
+ {
+ CCTK_WARN(0, "The dependent GF indices must be passed as "
+ "a CCTK_INT array.");
+ }
+ if (n_entries > (FnList.Fns[call_number]).n_deps)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The EOS function '%s' expects at most %d dependent"
+ " variables.\n"
+ "Your GF list contains %d entries.",
+ fn_name, (FnList.Fns[call_number]).n_deps,
+ n_entries);
+ }
+ tmp_dep_gfs = (CCTK_INT*)malloc(n_entries * sizeof(CCTK_INT));
+ (CallList.Calls[ncall]).dep_gfs =
+ (CCTK_INT*)malloc((FnList.Fns[call_number]).n_deps * sizeof(CCTK_INT));
+ (CallList.Calls[ncall]).which_deps_to_set =
+ (CCTK_INT*)malloc((FnList.Fns[call_number]).n_deps * sizeof(CCTK_INT));
+ n_elements = Util_TableGetIntArray(table_handle,
+ n_entries,
+ tmp_dep_gfs,
+ "Dependent GFs");
+ if (n_elements != n_entries)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ /* Now we have to order the dependent gfs correctly */
+
+ strlength = Util_TableGetString(table_handle,
+ 0, NULL,
+ "Dependent variable names");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "Need the dependent variable names");
+ }
+ local_dep_names =
+ (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(table_handle,
+ (strlength+1), local_dep_names,
+ "Dependent variable names");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ tmpbuffer = EOS_StrSep(&local_dep_names, " ");
+ if (tmpbuffer == NULL) /* line is empty */
+ {
+ CCTK_WARN(0, "Error in the independent name string; empty???");
+ }
+ for (dep_var = 0;
+ dep_var < (FnList.Fns[call_number]).n_deps;
+ ++dep_var)
+ {
+ (CallList.Calls[ncall]).dep_gfs[dep_var] = -1;
+ (CallList.Calls[ncall]).which_deps_to_set[dep_var] = 0;
+ }
+ for (var = 0; var < n_entries; ++var)
+ {
+ while (*tmpbuffer == '\0')
+ {
+ tmpbuffer = EOS_StrSep(&local_dep_names, " ");
+ }
+
+ for (dep_var = 0;
+ dep_var < (FnList.Fns[call_number]).n_deps;
+ ++dep_var)
+ {
+ if ( CCTK_Equals((FnList.Fns[call_number]).dep_names[dep_var],
+ tmpbuffer) )
+ {
+ (CallList.Calls[ncall]).dep_gfs[dep_var] = tmp_dep_gfs[var];
+ (CallList.Calls[ncall]).which_deps_to_set[dep_var] = 1;
+ }
+ }
+ tmpbuffer = EOS_StrSep(&local_dep_names, " ");
+ }
+ }
+ else
+ {
+ CCTK_WARN(0, "If you set the 'Independent GFs' key you should also\n"
+ "set the 'Dependent GFs' key.");
+ }
+ (CallList.Calls[ncall]).indep_vars =
+ (CCTK_REAL**)malloc((FnList.Fns[call_number]).n_indeps *
+ sizeof(CCTK_REAL*));
+ for (var = 0; var < (FnList.Fns[call_number]).n_indeps; ++var)
+ {
+ (CallList.Calls[ncall]).indep_vars[var] = NULL;
+ }
+ (CallList.Calls[ncall]).dep_vars =
+ (CCTK_REAL**)malloc((FnList.Fns[call_number]).n_deps *
+ sizeof(CCTK_REAL*));
+ for (var = 0; var < (FnList.Fns[call_number]).n_deps; ++var)
+ {
+ (CallList.Calls[ncall]).dep_vars[var] = NULL;
+ }
+ }
+ else /* Setting up a direct array call */
+ {
+ (CallList.Calls[ncall]).indep_gfs = NULL;
+ (CallList.Calls[ncall]).dep_gfs = NULL;
+
+ if (Util_TableQueryValueInfo(table_handle, &type_code, &n_entries,
+ "N array elements"))
+ {
+ if (type_code != CCTK_VARIABLE_INT)
+ {
+ CCTK_WARN(0, "The number of elements of the array in a direct "
+ "array call must be passed as a CCTK_INT.");
+ }
+ n_elements = Util_TableGetInt(table_handle,
+ &((CallList.Calls[ncall]).n_elems),
+ "N array elements");
+ }
+ else
+ {
+ CCTK_WARN(0, "If setting up a direct array call the number of "
+ "elements\n(key 'N array elements') must be set");
+ }
+
+ if (Util_TableQueryValueInfo(table_handle, &type_code, &n_entries,
+ "Independent arrays"))
+ {
+ if (type_code != CCTK_VARIABLE_POINTER)
+ {
+ CCTK_WARN(0, "The independent arrays in a direct "
+ "array call must be passed as as a CCTK_POINTER array.");
+ }
+ if (n_entries != (FnList.Fns[call_number]).n_indeps)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The EOS function '%s' expects %d independent variables.\n"
+ "Your direct call list only contains %d entries.",
+ fn_name, (FnList.Fns[call_number]).n_indeps,
+ n_entries);
+ }
+ tmp_indep_arrays = (CCTK_REAL**)malloc(n_entries * sizeof(CCTK_REAL*));
+ (CallList.Calls[ncall]).indep_vars =
+ (CCTK_REAL**)malloc(n_entries * sizeof(CCTK_REAL*));
+ n_elements =
+ Util_TableGetPointerArray(table_handle,
+ (FnList.Fns[call_number]).n_indeps,
+ (CCTK_POINTER*)tmp_indep_arrays,
+ "Independent arrays");
+ if (n_elements != n_entries)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+ /* Now we have to order the independent gfs correctly */
+
+ strlength = Util_TableGetString(table_handle,
+ 0, NULL,
+ "Independent variable names");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "Need the independent variable names");
+ }
+ local_indep_names =
+ (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(table_handle,
+ (strlength+1), local_indep_names,
+ "Independent variable names");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ tmpbuffer = EOS_StrSep(&local_indep_names, " ");
+ if (tmpbuffer == NULL) /* line is empty */
+ {
+ CCTK_WARN(0, "Error in the independent name string; empty???");
+ }
+ for (var = 0; var < n_entries; ++var)
+ {
+ while (*tmpbuffer == '\0')
+ {
+ tmpbuffer = EOS_StrSep(&local_indep_names, " ");
+ }
+
+ (CallList.Calls[ncall]).indep_vars[var] = NULL;
+ for (indep_var = 0; indep_var < n_entries; ++indep_var)
+ {
+ if ( CCTK_Equals((FnList.Fns[call_number]).indep_names[indep_var],
+ tmpbuffer) )
+ {
+ (CallList.Calls[ncall]).indep_vars[var] =
+ tmp_indep_arrays[indep_var];
+ }
+ }
+ if ( !((CallList.Calls[ncall]).indep_vars[var]) )
+ {
+ CCTK_WARN(0, "Failed to set up the independent variables?");
+ }
+ tmpbuffer = EOS_StrSep(&local_indep_names, " ");
+ }
+
+ }
+ else
+ {
+ CCTK_WARN(0, "If setting up a direct array call the independent "
+ "arrays\n(key 'Independent arrays') must be set");
+ }
+
+
+ if (Util_TableQueryValueInfo(table_handle, &type_code, &n_entries,
+ "Dependent arrays"))
+ {
+ if (type_code != CCTK_VARIABLE_POINTER)
+ {
+ CCTK_WARN(0, "The dependent arrays in a direct "
+ "array call must be passed as as a CCTK_POINTER array.");
+ }
+ if (n_entries >= (FnList.Fns[call_number]).n_deps)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The EOS function '%s' expects at most %d dependent "
+ "variables.\n"
+ "Your direct call list only contains %d entries.",
+ fn_name, (FnList.Fns[call_number]).n_deps,
+ n_entries);
+ }
+ tmp_dep_arrays = (CCTK_REAL**)malloc(n_entries * sizeof(CCTK_REAL*));
+ (CallList.Calls[ncall]).dep_vars =
+ (CCTK_REAL**)malloc((FnList.Fns[call_number]).n_deps *
+ sizeof(CCTK_REAL*));
+ (CallList.Calls[ncall]).which_deps_to_set =
+ (CCTK_INT*)malloc((FnList.Fns[call_number]).n_deps *
+ sizeof(CCTK_INT));
+ n_elements =
+ Util_TableGetPointerArray(table_handle,
+ n_entries,
+ (CCTK_POINTER*)tmp_dep_arrays,
+ "Dependent arrays");
+ if (n_elements != n_entries)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+ /* Now we have to order the dependent gfs correctly */
+
+ strlength = Util_TableGetString(table_handle,
+ 0, NULL,
+ "Dependent variable names");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "Need the dependent variable names");
+ }
+ local_dep_names =
+ (const char*)malloc((strlength+1) * sizeof(char));
+ ierr = Util_TableGetString(table_handle,
+ (strlength+1), local_dep_names,
+ "Dependent variable names");
+ if (ierr != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ tmpbuffer = EOS_StrSep(&local_dep_names, " ");
+ if (tmpbuffer == NULL) /* line is empty */
+ {
+ CCTK_WARN(0, "Error in the independent name string; empty???");
+ }
+ for (dep_var = 0; dep_var < n_entries; ++var)
+ {
+ while (*tmpbuffer == '\0')
+ {
+ tmpbuffer = EOS_StrSep(&local_dep_names, " ");
+ }
+
+ (CallList.Calls[ncall]).dep_vars[var] = NULL;
+ for (dep_var = 0;
+ dep_var < (FnList.Fns[call_number]).n_deps;
+ ++dep_var)
+ {
+ (CallList.Calls[ncall]).dep_vars[dep_var] = NULL;
+ (CallList.Calls[ncall]).which_deps_to_set[dep_var] = 0;
+ }
+ for (var = 0; var < n_entries; ++var)
+ {
+ while (*tmpbuffer == '\0')
+ {
+ tmpbuffer = EOS_StrSep(&local_dep_names, " ");
+ }
+
+ for (dep_var = 0;
+ dep_var < (FnList.Fns[call_number]).n_deps;
+ ++dep_var)
+ {
+ if ( CCTK_Equals((FnList.Fns[call_number]).dep_names[dep_var],
+ tmpbuffer) )
+ {
+ (CallList.Calls[ncall]).dep_vars[dep_var] = tmp_dep_arrays[var];
+ (CallList.Calls[ncall]).which_deps_to_set[dep_var] = 1;
+ }
+ }
+ tmpbuffer = EOS_StrSep(&local_dep_names, " ");
+ }
+ }
+
+ }
+ else
+ {
+ CCTK_WARN(0, "If setting up a direct array call the dependent "
+ "arrays\n(key 'Dependent arrays') must be set");
+ }
+
+ }
+
+
+#ifdef EOSBASE_DBG
+ printf("An eos call has been setup. The call handle was %d.\n"
+ "The eos name is '%s', corresponding to registered eos %d.\n"
+ "The registered structure really believes a fn number %d.\n",
+ ncall,
+ (FnList.Fns)[call_number].eos_name, call_number,
+ (CallList.Calls)[ncall].fn_number);
+ if ( (CallList.Calls)[ncall].indep_gfs)
+ {
+ for (var = 0; var < (FnList.Fns)[call_number].n_indeps; ++var)
+ {
+ printf("Independent gf number %d has index '%d' (name '%s').\n",
+ var, (CallList.Calls)[ncall].indep_gfs[var],
+ (FnList.Fns)[call_number].indep_names[var]);
+ }
+ for (var = 0; var < (FnList.Fns)[call_number].n_deps; ++var)
+ {
+ printf("Dependent gf number %d has index '%d' (to_set = %d, name '%s').\n",
+ var, (CallList.Calls)[ncall].dep_gfs[var],
+ (CallList.Calls)[ncall].which_deps_to_set[var],
+ (FnList.Fns)[call_number].dep_names[var]);
+ }
+ }
+#endif
+
+ return ncall;
+}
+
+ /*@@
+ @routine SetGFs
+ @date Fri Jun 10 05:08:20 2005
+ @author Ian Hawke
+ @desc
+ The aliased function call by the user thorn that actually sets
+ the GFs (in this case).
+ The call is passed on to the EOS thorn once the appropriate
+ information has been pulled out of the table.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+CCTK_INT SetGFs(const CCTK_POINTER_TO_CONST _GH, const CCTK_INT call_number)
+{
+
+ const cGH* const GH = (const cGH* const) _GH;
+
+ CCTK_INT ierr = 0;
+
+ CCTK_INT totalsize = 1;
+ CCTK_INT dim;
+ CCTK_INT fn_number, var;
+
+ for (dim = 0; dim < GH->cctk_dim; ++dim)
+ {
+ totalsize *= GH->cctk_lsh[dim];
+ }
+
+ fn_number = (CallList.Calls)[call_number].fn_number;
+
+ for (var = 0; var < (FnList.Fns)[fn_number].n_indeps; ++var)
+ {
+ (CallList.Calls)[call_number].indep_vars[var] =
+ (CCTK_REAL*)CCTK_VarDataPtrI(GH, 0,
+ (CallList.Calls)[call_number].indep_gfs[var]);
+ }
+
+ for (var = 0; var < (FnList.Fns)[fn_number].n_deps; ++var)
+ {
+ if ((CallList.Calls)[call_number].which_deps_to_set[var])
+ {
+ (CallList.Calls)[call_number].dep_vars[var] =
+ (CCTK_REAL*)CCTK_VarDataPtrI(GH, 0,
+ (CallList.Calls)[call_number].dep_gfs[var]);
+ }
+ else
+ {
+ (CallList.Calls)[call_number].dep_vars[var] = NULL;
+ }
+ }
+
+ ierr = ((FnList.Fns)[fn_number].EOS_fn)
+ ((FnList.Fns)[fn_number].param_table,
+ totalsize,
+ (CallList.Calls)[call_number].indep_vars,
+ (CallList.Calls)[call_number].which_deps_to_set,
+ (CallList.Calls)[call_number].dep_vars);
+
+ return ierr;
+}
+
+ /*@@
+ @routine SetArrays
+ @date Fri Jun 10 05:09:40 2005
+ @author Ian Hawke
+ @desc
+ The aliased function call by the user thorn that actually sets
+ the arrays (in this case).
+ The call is passed on to the EOS thorn once the appropriate
+ information has been pulled out of the table.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+CCTK_INT SetArrays(const CCTK_INT call_number)
+{
+
+ CCTK_INT ierr = 0;
+
+ CCTK_INT fn_number, totalsize;
+
+ fn_number = (CallList.Calls)[call_number].fn_number;
+
+ totalsize = (CallList.Calls)[call_number].n_elems;
+
+ ierr = ((FnList.Fns)[fn_number].EOS_fn)
+ ((FnList.Fns)[fn_number].param_table,
+ totalsize,
+ (CallList.Calls)[call_number].indep_vars,
+ (CallList.Calls)[call_number].which_deps_to_set,
+ (CallList.Calls)[call_number].dep_vars);
+
+ return ierr;
+}
+
+CCTK_INT SetInverseArrays(const CCTK_INT call_number,
+ const CCTK_INT table_handle)
+{
+
+ CCTK_INT ierr = 0, in_error = 1;
+ CCTK_INT fn_number, totalsize, i;
+ CCTK_INT unknown_indep_number, known_dep_number;
+ CCTK_INT strlength, strlength_recv;
+
+ CCTK_REAL guess_factor = 1.01, threshold = 1e-12;
+ CCTK_REAL *indep_min, *indep_max, *unknown_indep,
+ *known_result, *tmp_result, *max_result;
+
+ char *tmpbuffer;
+
+ fn_number = (CallList.Calls)[call_number].fn_number;
+
+ totalsize = (CallList.Calls)[call_number].n_elems;
+
+ /* Find out which independent variable needs setting */
+
+ strlength = Util_TableGetString(table_handle,
+ 0, NULL,
+ "Unknown independent name");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "We need the independent variable name that you"
+ "actually want to set\n (key: 'Unknown independent name')");
+ }
+ tmpbuffer =
+ (const char*)malloc((strlength+1) * sizeof(char));
+ strlength_recv = Util_TableGetString(table_handle,
+ (strlength+1), tmpbuffer,
+ "Unknown independent name");
+ if (strlength_recv != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ unknown_indep_number = -1;
+ for (i = 0; i < (FnList.Fns)[fn_number].n_indeps; ++i)
+ {
+ if (CCTK_Equals(tmpbuffer, (FnList.Fns)[fn_number].indep_names[i]))
+ {
+ unknown_indep_number = i;
+ }
+ }
+ if (unknown_indep_number < 0)
+ {
+ CCTK_WARN(0, "Unknown independent variable not recognized");
+ }
+
+#ifdef EOSBASE_DBG
+ printf("Inverse array call: unknown indep '%s' index %d.\n",
+ tmpbuffer, unknown_indep_number);
+#endif
+
+ /* Find out which dependent variable is actually known */
+
+ strlength = Util_TableGetString(table_handle,
+ 0, NULL,
+ "Known dependent name");
+ if (strlength < 1)
+ {
+ CCTK_WARN(0, "We need the dependent variable name that you"
+ "have already set\n (key: 'Known dependent name')");
+ }
+ tmpbuffer =
+ (const char*)malloc((strlength+1) * sizeof(char));
+ strlength_recv = Util_TableGetString(table_handle,
+ (strlength+1), tmpbuffer,
+ "Known dependent name");
+ if (strlength_recv != strlength)
+ {
+ CCTK_WARN(0, "What happened here?");
+ }
+
+ known_dep_number = -1;
+ for (i = 0; i < (FnList.Fns)[fn_number].n_deps; ++i)
+ {
+ if (CCTK_Equals(tmpbuffer, (FnList.Fns)[fn_number].dep_names[i]))
+ {
+ known_dep_number = i;
+ }
+ }
+ if (known_dep_number < 0)
+ {
+ CCTK_WARN(0, "Known dependent variable not recognized");
+ }
+
+#ifdef EOSBASE_DBG
+ printf("Inverse array call: known dep '%s' index %d.\n",
+ tmpbuffer, known_dep_number);
+#endif
+
+ /* Ensure that the 'known' variable is set */
+
+ (CallList.Calls)[call_number].which_deps_to_set[known_dep_number] = 1;
+
+ /* Juggle... */
+
+ unknown_indep =
+ (CallList.Calls)[call_number].indep_vars[unknown_indep_number];
+ known_result =
+ (CallList.Calls)[call_number].dep_vars[known_dep_number];
+
+ indep_min = (CCTK_REAL*)malloc(totalsize * sizeof(CCTK_REAL));
+ indep_max = (CCTK_REAL*)malloc(totalsize * sizeof(CCTK_REAL));
+ tmp_result = (CCTK_REAL*)malloc(totalsize * sizeof(CCTK_REAL));
+ max_result = (CCTK_REAL*)malloc(totalsize * sizeof(CCTK_REAL));
+
+ for (i = 0; i < totalsize; ++i)
+ {
+ indep_min[i] = unknown_indep[i] / guess_factor;
+ indep_max[i] = unknown_indep[i] * guess_factor;
+
+#ifdef EOSBASE_DBG
+ printf("Inverse array call: index %d (/%d), range [%g, %g].\n",
+ i, totalsize, indep_min[i], indep_max[i]);
+#endif
+
+ }
+
+ for (i = 0; i < totalsize; ++i)
+ {
+ unknown_indep[i] = indep_max[i];
+ }
+
+ (CallList.Calls)[call_number].dep_vars[known_dep_number] = max_result;
+ ierr = ((FnList.Fns)[fn_number].EOS_fn)
+ ((FnList.Fns)[fn_number].param_table,
+ totalsize,
+ (CallList.Calls)[call_number].indep_vars,
+ (CallList.Calls)[call_number].which_deps_to_set,
+ (CallList.Calls)[call_number].dep_vars);
+
+ for (i = 0; i < totalsize; ++i)
+ {
+ unknown_indep[i] = indep_min[i];
+ }
+
+ (CallList.Calls)[call_number].dep_vars[known_dep_number] = tmp_result;
+ ierr = ((FnList.Fns)[fn_number].EOS_fn)
+ ((FnList.Fns)[fn_number].param_table,
+ totalsize,
+ (CallList.Calls)[call_number].indep_vars,
+ (CallList.Calls)[call_number].which_deps_to_set,
+ (CallList.Calls)[call_number].dep_vars);
+
+ for (i = 0; i < totalsize; ++i)
+ {
+ if ( ((known_result[i] - tmp_result[i]) *
+ (known_result[i] - max_result[i])) > 0 )
+ {
+#ifdef EOSBASE_DBG
+ printf("Inverse array call: index %d (/%d), bracketing failed?\n"
+ "Range [%g, %g], result %g.\n",
+ i, totalsize, tmp_result[i], max_result[i], known_result[i]);
+#endif
+
+ CCTK_WARN(0, "Failed to bracket root!");
+ }
+ unknown_indep[i] = 0.5 * (indep_min[i] + indep_max[i]);
+ }
+
+
+ while (in_error)
+ {
+
+ ierr = ((FnList.Fns)[fn_number].EOS_fn)
+ ((FnList.Fns)[fn_number].param_table,
+ totalsize,
+ (CallList.Calls)[call_number].indep_vars,
+ (CallList.Calls)[call_number].which_deps_to_set,
+ (CallList.Calls)[call_number].dep_vars);
+
+ in_error = 0;
+
+ for (i = 0; i < totalsize; ++i)
+ {
+ if ( ((known_result[i] - tmp_result[i]) *
+ (known_result[i] - max_result[i])) < 0 )
+ {
+ indep_min[i] = unknown_indep[i];
+ }
+ else
+ {
+ indep_max[i] = unknown_indep[i];
+ max_result[i] = tmp_result[i];
+ }
+ unknown_indep[i] = 0.5 * (indep_min[i] + indep_max[i]);
+ if (indep_max[i] - indep_min[i] > threshold)
+ {
+ in_error = 1;
+ }
+ }
+
+ }
+
+ (CallList.Calls)[call_number].dep_vars[known_dep_number] = known_result;
+
+ free(indep_min); indep_min = NULL;
+ free(indep_max); indep_max = NULL;
+ free(tmp_result); tmp_result = NULL;
+ free(max_result); max_result = NULL;
+
+ return ierr;
+}
diff --git a/src/EOS_Utils.c b/src/EOS_Utils.c
new file mode 100755
index 0000000..815a665
--- /dev/null
+++ b/src/EOS_Utils.c
@@ -0,0 +1,68 @@
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+
+#include "util_String.h"
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+ /*@@
+ @routine EOS_StrSep
+ @date Wed Mar 2 14:57:50 2005
+ @author Ian Hawke
+ @desc
+ A wrapper to Util_StrSep that returns the last token if there
+ are no more delimiters. Note that the documentation is incorrect;
+ delim_set (here delim) cannot be a set but must be a single
+ character.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+
+const char * EOS_StrSep(const char ** string_ptr, const char * delim);
+
+const char * EOS_StrSep(const char ** string_ptr, const char * delim)
+{
+
+ const char * token;
+ const char ** string;
+
+ string = string_ptr;
+
+ if (string == NULL)
+ {
+ return NULL;
+ }
+
+ token = Util_StrSep(string_ptr, delim);
+
+ if ( (token == NULL) && (strlen(*string) > 0) &&
+ (!(CCTK_Equals(*string, "\n"))) )
+ {
+ string_ptr = string;
+ token = Util_StrSep(string_ptr, "\n");
+ if ( (token == NULL) && (strlen(*string) > 0) )
+ {
+ string_ptr = '\0';
+ token = *string;
+ }
+ }
+
+#ifdef EOS_GTR_DEBUG
+ printf("EOS_StrSep: token '%s' and string_ptr '%s' (%s)\n",
+ token, *string_ptr, *string);
+#endif
+
+ return token;
+}
diff --git a/src/EOS_Utils.h b/src/EOS_Utils.h
new file mode 100755
index 0000000..8aa6793
--- /dev/null
+++ b/src/EOS_Utils.h
@@ -0,0 +1,16 @@
+
+#ifndef _EOS_UTILS_H_
+#define _EOS_UTILS_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+const char * EOS_StrSep(const char ** string_ptr, const char * delim);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Eos_Utils.h */
diff --git a/src/make.code.defn b/src/make.code.defn
new file mode 100755
index 0000000..1617c8e
--- /dev/null
+++ b/src/make.code.defn
@@ -0,0 +1,9 @@
+# Main make.code.defn file for thorn EOSBase_General
+# $Header$
+
+# Source files in this directory
+SRCS = EOSBase_Register.c \
+ EOS_Utils.c
+
+# Subdirectories containing source files
+SUBDIRS =
diff --git a/test/test b/test/test
new file mode 100644
index 0000000..2a63253
--- /dev/null
+++ b/test/test
@@ -0,0 +1 @@
+again testing