aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortradke <tradke@3af55ef0-e5e4-43b4-b020-ca5761ff09b2>2004-06-14 11:12:42 +0000
committertradke <tradke@3af55ef0-e5e4-43b4-b020-ca5761ff09b2>2004-06-14 11:12:42 +0000
commitca0c7731de7c3d2bc45175af5b521c539bd66228 (patch)
tree3e7fb5f604817d8c717e13a8cd692e96c08fac1c /src
parentd754a1ddfe40636e42e2c0367c687b99f917fcd4 (diff)
New I/O thorn for 1D/2D/3D output of datasets in SDF file format.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusIO/IOSDF/trunk@2 3af55ef0-e5e4-43b4-b020-ca5761ff09b2
Diffstat (limited to 'src')
-rw-r--r--src/ChooseOutput.c149
-rw-r--r--src/Output1D.c378
-rw-r--r--src/Output2D.c382
-rw-r--r--src/Output3D.c383
-rw-r--r--src/Startup.c251
-rw-r--r--src/Write1D.c436
-rw-r--r--src/Write2D.c371
-rw-r--r--src/Write3D.c292
-rw-r--r--src/ioSDFGH.h87
-rw-r--r--src/make.code.defn6
10 files changed, 2735 insertions, 0 deletions
diff --git a/src/ChooseOutput.c b/src/ChooseOutput.c
new file mode 100644
index 0000000..00ae902
--- /dev/null
+++ b/src/ChooseOutput.c
@@ -0,0 +1,149 @@
+/*@@
+ @file ChooseOutput.c
+ @author Thomas Radke
+ @date 12 June 2004
+ @desc
+ Choose what 1D slices and 2D planes to output by IOSDF.
+ @enddesc
+
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Header$";
+CCTK_FILEVERSION(CactusIO_IOSDF_ChooseOutput_c)
+
+
+/********************************************************************
+ ******************** Macro Definitions ************************
+ ********************************************************************/
+/* macro to choose origin according actual parameter settings:
+ 1. Indices from IOSDF
+ 2. Indices from IOUtil
+ 3. Coords from IOSDF
+ 4. Coords from IOUtil
+ */
+#define GET_SLICE(IOSDF_param, IOUtil_param, index, coord) \
+ { \
+ index = IOSDF_param##i >= 0 ? IOSDF_param##i : IOUtil_param##i; \
+ coord = IOSDF_param != -424242 ? IOSDF_param : IOUtil_param; \
+ }
+
+
+/*@@
+ @routine IOSDF_Choose1D
+ @author Thomas Radke
+ @date 12 June 2004
+ @desc
+ Use parameters to choose the 1D slices through the output data.
+ @enddesc
+
+ @calls IOUtil_1DLines
+
+ @var GH
+ @vdesc pointer to CCTK grid hierarchy
+ @vtype const cGH *
+ @vio in
+ @endvar
+@@*/
+void IOSDF_Choose1D (const cGH *GH)
+{
+ int i, j, maxdim;
+ ioSDFGH *myGH;
+ int *origin_index[3];
+ CCTK_REAL *origin_phys[3];
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* allocate arrays for origins */
+ origin_phys[0] = malloc (3 * 3 * sizeof (CCTK_REAL));
+ origin_phys[1] = origin_phys[0] + 3;
+ origin_phys[2] = origin_phys[1] + 3;
+ origin_index[0] = malloc (3 * 3 * sizeof (int));
+ origin_index[1] = origin_index[0] + 3;
+ origin_index[2] = origin_index[1] + 3;
+
+ /* get slice points */
+ GET_SLICE (out1D_xline_y, out_xline_y, origin_index[0][1], origin_phys[0][1]);
+ GET_SLICE (out1D_xline_z, out_xline_z, origin_index[0][2], origin_phys[0][2]);
+ GET_SLICE (out1D_yline_x, out_yline_x, origin_index[1][0], origin_phys[1][0]);
+ GET_SLICE (out1D_yline_z, out_yline_z, origin_index[1][2], origin_phys[1][2]);
+ GET_SLICE (out1D_zline_x, out_zline_x, origin_index[2][0], origin_phys[2][0]);
+ GET_SLICE (out1D_zline_y, out_zline_y, origin_index[2][1], origin_phys[2][1]);
+
+ maxdim = CCTK_MaxDim ();
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->spxyz = malloc (maxdim * sizeof (int **));
+
+ for (i = 0; i < maxdim; i++)
+ {
+ myGH->spxyz[i] = malloc ((i + 1) * sizeof (int *));
+
+ for (j = 0; j <= i; j++)
+ {
+ myGH->spxyz[i][j] = calloc (i + 1, sizeof (int));
+ }
+
+ if (i < 3)
+ {
+ IOUtil_1DLines (GH, i + 1, origin_index, origin_phys, myGH->spxyz[i]);
+ }
+ }
+
+ /* free allocated resources */
+ free (origin_phys[0]);
+ free (origin_index[0]);
+}
+
+
+/*@@
+ @routine IOSDF_Choose2D
+ @author Thomas Radke
+ @date 12 June 2004
+ @desc
+ Use parameters to choose the 2D slices through the output data.
+ @enddesc
+
+ @calls IOUtil_2DPlanes
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @@*/
+void IOSDF_Choose2D (const cGH *GH)
+{
+ int i, maxdim;
+ ioSDFGH *myGH;
+ int origin_index[3];
+ CCTK_REAL origin_phys[3];
+ DECLARE_CCTK_PARAMETERS
+
+
+ GET_SLICE (out2D_xyplane_z, out_xyplane_z, origin_index[0], origin_phys[0]);
+ GET_SLICE (out2D_xzplane_y, out_xzplane_y, origin_index[1], origin_phys[1]);
+ GET_SLICE (out2D_yzplane_x, out_yzplane_x, origin_index[2], origin_phys[2]);
+
+ maxdim = CCTK_MaxDim ();
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->sp2xyz = malloc (3 * sizeof (int *));
+
+ for (i = 0; i < maxdim; i++)
+ {
+ myGH->sp2xyz[i] = calloc (i + 1, sizeof (int));
+
+ if (i == 2)
+ {
+ IOUtil_2DPlanes (GH, i + 1, origin_index, origin_phys, myGH->sp2xyz[i]);
+ }
+ }
+}
diff --git a/src/Output1D.c b/src/Output1D.c
new file mode 100644
index 0000000..1f572f9
--- /dev/null
+++ b/src/Output1D.c
@@ -0,0 +1,378 @@
+ /*@@
+ @file Output1D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Functions to deal with 1D SDF output of variables
+ @enddesc
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_String.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Output1D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static int CheckOutputVar (int vindex);
+static void SetOutputFlag (int vindex, const char *optstring, void *arg);
+
+
+/*@@
+ @routine IOSDF_Output1DGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Loops over all variables and outputs them if necessary
+ @enddesc
+ @calls IOSDF_TimeFor1D
+ IOSDF_Write1D
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ the number of variables which were output at this iteration
+ (or 0 if it wasn't time to output yet)
+ @endreturndesc
+@@*/
+int IOSDF_Output1DGH (const cGH *GH)
+{
+ int vindex, retval;
+ const ioSDFGH *myGH;
+
+
+ retval = 0;
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* loop over all variables */
+ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--)
+ {
+ if (IOSDF_TimeFor1D (GH, vindex) &&
+ IOSDF_Write1D (GH, vindex, CCTK_VarName (vindex)) == 0)
+ {
+ /* register variable as having 1D output this iteration */
+ myGH->out1D_last[vindex] = GH->cctk_iteration;
+ retval++;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_Output1DVarAs
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Unconditional output of a variable
+ using the IOSDF output method
+ @enddesc
+ @calls IOSDF_Write1D
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var fullname
+ @vdesc complete name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ (used to generate output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write1D, or<BR>
+ -1 if variable cannot be output by IOSDF_1D
+ @endreturndesc
+@@*/
+int IOSDF_Output1DVarAs (const cGH *GH, const char *fullname, const char *alias)
+{
+ int vindex, retval;
+
+
+ retval = -1;
+ vindex = CCTK_VarIndex (fullname);
+ if (vindex < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "There is no such variable %s. Ignoring IOSDF 1D output.",
+ fullname);
+ }
+ else if (CheckOutputVar (vindex))
+ {
+ retval = IOSDF_Write1D (GH, vindex, alias);
+ }
+
+ return (retval);
+}
+
+
+ /*@@
+ @routine IOSDF_TimeFor1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Decides if it is time to output a variable
+ using the IO 1D output method
+ @enddesc
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 1 if output should take place at this iteration, or<BR>
+ 0 if not
+ @endreturndesc
+@@*/
+int IOSDF_TimeFor1D (const cGH *GH, int vindex)
+{
+ int retval;
+ char *fullname;
+ ioSDFGH *myGH;
+
+
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ IOSDF_CheckSteerableParameters1D (myGH);
+
+ /* check if this variable should be output */
+ retval = myGH->out1D_every[vindex] > 0 &&
+ GH->cctk_iteration % myGH->out1D_every[vindex] == 0;
+ if (retval)
+ {
+ /* check if this variable wasn't already output this iteration */
+ if (myGH->out1D_last[vindex] == GH->cctk_iteration)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Already done IOSDF 1D output for '%s' in current "
+ "iteration (probably via triggers)", fullname);
+ free (fullname);
+ retval = 0;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_TriggerOutput1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Triggers the output a variable
+ using the IOSDF output method method
+ @enddesc
+ @calls IOSDF_Write1D
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write1D
+ @endreturndesc
+@@*/
+int IOSDF_TriggerOutput1D (const cGH *GH, int vindex)
+{
+ int retval;
+ ioSDFGH *myGH;
+
+
+ retval = IOSDF_Write1D (GH, vindex, CCTK_VarName (vindex));
+ if (retval == 0)
+ {
+ /* register variables as having 1D output this iteration */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->out1D_last[vindex] = GH->cctk_iteration;
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_CheckSteerableParameters1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Check if steerable IOSDF 1D parameters have changed
+ @enddesc
+ @calls CCTK_TraverseString
+
+ @var myGH
+ @vdesc Pointer to IOSDF GH
+ @vtype ioSDFGH *
+ @vio inout
+ @endvar
+@@*/
+void IOSDF_CheckSteerableParameters1D (ioSDFGH *myGH)
+{
+ int i, num_vars;
+ char *fullname, *msg;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* how often to output */
+ i = myGH->out1D_every_default;
+ myGH->out1D_every_default = out1D_every >= 0 ? out1D_every : out_every;
+
+ /* report if frequency changed */
+ if (myGH->out1D_every_default != i && ! CCTK_Equals (verbose, "none"))
+ {
+ if (myGH->out1D_every_default > 0)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "Periodic 1D output every %d "
+ "iterations", myGH->out1D_every_default);
+ }
+ else
+ {
+ CCTK_INFO ("Periodic 1D output turned off");
+ }
+ }
+
+ /* re-parse the 'out1D_vars' parameter if it was changed */
+ if (strcmp (out1D_vars, myGH->out1D_vars) || myGH->out1D_every_default != i)
+ {
+ num_vars = CCTK_NumVars ();
+ memset (myGH->out1D_every, 0, num_vars * sizeof (CCTK_INT));
+ if (CCTK_TraverseString (out1D_vars, SetOutputFlag, myGH,
+ CCTK_GROUP_OR_VAR) < 0)
+ {
+ CCTK_WARN (myGH->stop_on_parse_errors ? 0 : 1,
+ "error while parsing parameter 'IOSDF::out1D_vars'");
+ }
+
+ if (myGH->out1D_every_default == i || ! CCTK_Equals (verbose, "none"))
+ {
+ msg = NULL;
+ for (i = 0; i < num_vars; i++)
+ {
+ if (myGH->out1D_every[i] > 0)
+ {
+ fullname = CCTK_FullName (i);
+ if (! msg)
+ {
+ Util_asprintf (&msg, "Periodic 1D output requested for "
+ "'%s'", fullname);
+ }
+ else
+ {
+ Util_asprintf (&msg, "%s, '%s'", msg, fullname);
+ }
+ free (fullname);
+ }
+ }
+ if (msg)
+ {
+ CCTK_INFO (msg);
+ free (msg);
+ }
+ }
+
+ /* save the last setting of 'out1D_vars' parameter */
+ free (myGH->out1D_vars);
+ myGH->out1D_vars = strdup (out1D_vars);
+ }
+}
+
+
+/**************************** local functions ******************************/
+/* check if this variable can be output (static conditions) */
+static int CheckOutputVar (int vindex)
+{
+ int groupindex;
+ cGroup groupinfo;
+ char *fullname;
+ const char *errormsg;
+
+
+ /* get the variable group information */
+ groupindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (groupindex, &groupinfo);
+
+ errormsg = NULL;
+ if (groupinfo.grouptype != CCTK_GF && groupinfo.grouptype != CCTK_ARRAY)
+ {
+ errormsg = "not a grid function or array";
+ }
+ else if (strncmp (CCTK_VarTypeName (groupinfo.vartype),
+ "CCTK_VARIABLE_REAL", 18) ||
+ CCTK_VarTypeSize (groupinfo.vartype) != sizeof (double))
+ {
+ errormsg = "not a double-precision floating-point grid function or array";
+ }
+
+ if (errormsg)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 1D output for '%s': %s", fullname, errormsg);
+ free (fullname);
+ }
+
+ return (errormsg == NULL);
+}
+
+
+/* callback for CCTK_TraverseString() to set the output flag
+ for the given variable */
+static void SetOutputFlag (int vindex, const char *optstring, void *arg)
+{
+ const ioSDFGH *myGH = arg;
+
+
+ if (CheckOutputVar (vindex))
+ {
+ myGH->out1D_every[vindex] = myGH->out1D_every_default;
+
+ if (optstring)
+ {
+ IOUtil_ParseOutputFrequency ("1D IOSDF", "IOSDF::out1D_vars",
+ myGH->stop_on_parse_errors,
+ vindex, optstring,
+ &myGH->out1D_every[vindex]);
+ }
+ }
+}
diff --git a/src/Output2D.c b/src/Output2D.c
new file mode 100644
index 0000000..5eb5161
--- /dev/null
+++ b/src/Output2D.c
@@ -0,0 +1,382 @@
+ /*@@
+ @file Output2D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Functions to deal with 2D SDF output of variables
+ @enddesc
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_String.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Output2D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static int CheckOutputVar (int vindex);
+static void SetOutputFlag (int vindex, const char *optstring, void *arg);
+
+
+/*@@
+ @routine IOSDF_Output2DGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Loops over all variables and outputs them if necessary
+ @enddesc
+ @calls IOSDF_TimeFor2D
+ IOSDF_Write2D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ the number of variables which were output at this iteration
+ (or 0 if it wasn't time to output yet)
+ @endreturndesc
+@@*/
+int IOSDF_Output2DGH (const cGH *GH)
+{
+ int vindex, retval;
+ const ioSDFGH *myGH;
+
+
+ retval = 0;
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* loop over all variables */
+ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--)
+ {
+ if (IOSDF_TimeFor2D (GH, vindex) &&
+ IOSDF_Write2D (GH, vindex, CCTK_VarName (vindex)) == 0)
+ {
+ /* register variable as having 2D output this iteration */
+ myGH->out2D_last[vindex] = GH->cctk_iteration;
+ retval++;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_Output2DVarAs
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Unconditional output of a variable
+ using the IOSDF 2D output method
+ @enddesc
+ @calls IOSDF_Write2D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var fullname
+ @vdesc complete name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ (used to generate output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write2D, or<BR>
+ -1 if variable cannot be output by IOSDF_2D
+ @endreturndesc
+@@*/
+int IOSDF_Output2DVarAs (const cGH *GH, const char *fullname, const char *alias)
+{
+ int vindex, retval;
+
+
+ retval = -1;
+ vindex = CCTK_VarIndex (fullname);
+ if (vindex<0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "There is no such variable %s. Ignoring IOSDF 2D output.",
+ fullname);
+ } else if (CheckOutputVar (vindex) == 0)
+ {
+ retval = IOSDF_Write2D (GH, vindex, alias);
+ }
+
+ return (retval);
+}
+
+
+ /*@@
+ @routine IOSDF_TimeFor2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Decides if it is time to output a variable
+ using the IOSDF 2D output method
+ @enddesc
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 1 if output should take place at this iteration, or<BR>
+ 0 if not
+ @endreturndesc
+@@*/
+int IOSDF_TimeFor2D (const cGH *GH, int vindex)
+{
+ int retval;
+ char *fullname;
+ ioSDFGH *myGH;
+
+
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ IOSDF_CheckSteerableParameters2D (myGH);
+
+ /* check if this variable should be output */
+ retval = myGH->out2D_every[vindex] > 0 &&
+ GH->cctk_iteration % myGH->out2D_every[vindex] == 0;
+ if (retval)
+ {
+ /* check if variable wasn't already output this iteration */
+ if (myGH->out2D_last[vindex] == GH->cctk_iteration)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Already done IOSDF 2D output for '%s' in current "
+ "iteration (probably via triggers)", fullname);
+ free (fullname);
+ retval = 0;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_TriggerOutput2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Triggers the output of a variable
+ using the IOSDF 2D output method
+ @enddesc
+ @calls IOSDF_Write2D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write2D
+ @endreturndesc
+@@*/
+int IOSDF_TriggerOutput2D (const cGH *GH, int vindex)
+{
+ int retval;
+ ioSDFGH *myGH;
+
+
+ /* do the 2D output */
+ retval = IOSDF_Write2D (GH, vindex, CCTK_VarName (vindex));
+ if (retval == 0)
+ {
+ /* register variable as having 2D output this iteration */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->out2D_last[vindex] = GH->cctk_iteration;
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_CheckSteerableParameters2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Check if steerable IOSDF 2D parameters have changed
+ @enddesc
+ @calls CCTK_TraverseString
+
+ @var myGH
+ @vdesc Pointer to IOSDF GH
+ @vtype ioSDFGH *
+ @vio inout
+ @endvar
+@@*/
+void IOSDF_CheckSteerableParameters2D (ioSDFGH *myGH)
+{
+ int i, num_vars;
+ char *fullname, *msg;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* how often to output */
+ i = myGH->out2D_every_default;
+ myGH->out2D_every_default = out2D_every >= 0 ? out2D_every : out_every;
+
+ /* report if frequency changed */
+ if (myGH->out2D_every_default != i && ! CCTK_Equals (verbose, "none"))
+ {
+ if (myGH->out2D_every_default > 0)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "Periodic 2D output every %d "
+ "iterations", myGH->out2D_every_default);
+ }
+ else
+ {
+ CCTK_INFO ("Periodic 2D output turned off");
+ }
+ }
+
+ /* re-parse the 'out2D_vars' parameter if it was changed */
+ if (strcmp (out2D_vars, myGH->out2D_vars) || myGH->out2D_every_default != i)
+ {
+ num_vars = CCTK_NumVars ();
+ memset (myGH->out2D_every, 0, num_vars * sizeof (CCTK_INT));
+ if (CCTK_TraverseString (out2D_vars, SetOutputFlag, myGH,
+ CCTK_GROUP_OR_VAR) < 0)
+ {
+ CCTK_WARN (myGH->stop_on_parse_errors ? 0 : 1,
+ "error while parsing parameter 'IOSDF::out2D_vars'");
+ }
+
+ if (myGH->out2D_every_default == i || ! CCTK_Equals (verbose, "none"))
+ {
+ msg = NULL;
+ for (i = 0; i < num_vars; i++)
+ {
+ if (myGH->out2D_every[i])
+ {
+ fullname = CCTK_FullName (i);
+ if (! msg)
+ {
+ Util_asprintf (&msg, "Periodic 2D output requested for "
+ "'%s'", fullname);
+ }
+ else
+ {
+ Util_asprintf (&msg, "%s, '%s'", msg, fullname);
+ }
+ free (fullname);
+ }
+ }
+ if (msg)
+ {
+ CCTK_INFO (msg);
+ free (msg);
+ }
+ }
+
+ /* save the last setting of 'out2D_vars' parameter */
+ free (myGH->out2D_vars);
+ myGH->out2D_vars = strdup (out2D_vars);
+ }
+}
+
+
+/**************************** local functions ******************************/
+/* check if this variable can be output (static conditions) */
+static int CheckOutputVar (int vindex)
+{
+ int groupindex;
+ cGroup groupinfo;
+ char *fullname;
+ const char *errormsg;
+
+
+ /* get the variable group information */
+ groupindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (groupindex, &groupinfo);
+
+ errormsg = NULL;
+ if (groupinfo.dim < 2 || groupinfo.dim > 3)
+ {
+ errormsg = "dim != [2,3]";
+ }
+ else if (groupinfo.grouptype != CCTK_GF && groupinfo.grouptype != CCTK_ARRAY)
+ {
+ errormsg = "not a grid function or array";
+ }
+ else if (strncmp (CCTK_VarTypeName (groupinfo.vartype),
+ "CCTK_VARIABLE_REAL", 18) ||
+ CCTK_VarTypeSize (groupinfo.vartype) != sizeof (double))
+ {
+ errormsg = "not a double-precision floating-point grid function or array";
+ }
+
+ if (errormsg)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 2D output for '%s': %s", fullname, errormsg);
+ free (fullname);
+ }
+
+ return (errormsg != NULL);
+}
+
+
+/* callback for CCTK_TraverseString() to set the output flag
+ for the given variable */
+static void SetOutputFlag (int vindex, const char *optstring, void *arg)
+{
+ const ioSDFGH *myGH = arg;
+
+
+ if (CheckOutputVar (vindex) == 0)
+ {
+ myGH->out2D_every[vindex] = myGH->out2D_every_default;
+
+ if (optstring)
+ {
+ IOUtil_ParseOutputFrequency ("2D IOSDF", "IOSDF::out2D_vars",
+ myGH->stop_on_parse_errors,
+ vindex, optstring,
+ &myGH->out2D_every[vindex]);
+ }
+ }
+}
diff --git a/src/Output3D.c b/src/Output3D.c
new file mode 100644
index 0000000..16e01a5
--- /dev/null
+++ b/src/Output3D.c
@@ -0,0 +1,383 @@
+ /*@@
+ @file Output3D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Functions to deal with 3D SDF output of variables
+ @enddesc
+ @version $Id$
+ @@*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_String.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Output3D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static int CheckOutputVar (int vindex);
+static void SetOutputFlag (int vindex, const char *optstring, void *arg);
+
+
+/*@@
+ @routine IOSDF_Output3DGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Loops over all variables and outputs them if necessary
+ @enddesc
+ @calls IOSDF_TimeFor3D
+ IOSDF_Write3D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ the number of variables which were output at this iteration
+ (or 0 if it wasn't time to output yet)
+ @endreturndesc
+@@*/
+int IOSDF_Output3DGH (const cGH *GH)
+{
+ int vindex, retval;
+ const ioSDFGH *myGH;
+
+
+ retval = 0;
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* loop over all variables */
+ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--)
+ {
+ if (IOSDF_TimeFor3D (GH, vindex) &&
+ IOSDF_Write3D (GH, vindex, CCTK_VarName (vindex)) == 0)
+ {
+ /* register variable as having 3D output this iteration */
+ myGH->out3D_last[vindex] = GH->cctk_iteration;
+ retval++;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_Output3DVarAs
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Unconditional output of a variable
+ using the IOSDF 3D output method
+ @enddesc
+ @calls IOSDF_Write3D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var fullname
+ @vdesc complete name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ (used to generate output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write3D, or<BR>
+ -1 if variable cannot be output by IOSDF_3D
+ @endreturndesc
+@@*/
+int IOSDF_Output3DVarAs (const cGH *GH, const char *fullname, const char *alias)
+{
+ int vindex, retval;
+
+
+ retval = -1;
+ vindex = CCTK_VarIndex (fullname);
+ if (vindex<0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "There is no such variable %s. Ignoring IOSDF 3D output.",
+ fullname);
+ } else if (CheckOutputVar (vindex) == 0)
+ {
+ retval = IOSDF_Write3D (GH, vindex, alias);
+ }
+
+ return (retval);
+}
+
+
+ /*@@
+ @routine IOSDF_TimeFor3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Decides if it is time to output a variable
+ using the IOSDF 3D output method
+ @enddesc
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 1 if output should take place at this iteration, or<BR>
+ 0 if not
+ @endreturndesc
+@@*/
+int IOSDF_TimeFor3D (const cGH *GH, int vindex)
+{
+ int retval;
+ char *fullname;
+ ioSDFGH *myGH;
+
+
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ IOSDF_CheckSteerableParameters3D (myGH);
+
+ /* check if this variable should be output */
+ retval = myGH->out3D_every[vindex] > 0 &&
+ GH->cctk_iteration % myGH->out3D_every[vindex] == 0;
+ if (retval)
+ {
+ /* check if variable wasn't already output this iteration */
+ if (myGH->out3D_last[vindex] == GH->cctk_iteration)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Already done IOSDF 3D output for '%s' in current "
+ "iteration (probably via triggers)", fullname);
+ free (fullname);
+ retval = 0;
+ }
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_TriggerOutput3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Triggers the output of a variable
+ using the IOSDF 3D output method
+ @enddesc
+ @calls IOSDF_Write3D
+
+ @var GH
+ @vdesc pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine IOSDF_Write3D
+ @endreturndesc
+@@*/
+int IOSDF_TriggerOutput3D (const cGH *GH, int vindex)
+{
+ int retval;
+ ioSDFGH *myGH;
+
+
+ /* do the 3D output */
+ retval = IOSDF_Write3D (GH, vindex, CCTK_VarName (vindex));
+ if (retval == 0)
+ {
+ /* register variables as having 3D output this iteration */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+ myGH->out3D_last[vindex] = GH->cctk_iteration;
+ }
+
+ return (retval);
+}
+
+
+/*@@
+ @routine IOSDF_CheckSteerableParameters3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Check if steerable IOSDF 3D parameters have changed
+ @enddesc
+ @calls CCTK_TraverseString
+
+ @var myGH
+ @vdesc Pointer to IOSDF GH
+ @vtype ioSDFGH *
+ @vio inout
+ @endvar
+@@*/
+void IOSDF_CheckSteerableParameters3D (ioSDFGH *myGH)
+{
+ int i, num_vars;
+ char *fullname, *msg;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* how often to output */
+ i = myGH->out3D_every_default;
+ myGH->out3D_every_default = out3D_every >= 0 ? out3D_every : out_every;
+
+ /* report if frequency changed */
+ if (myGH->out3D_every_default != i && ! CCTK_Equals (verbose, "none"))
+ {
+ if (myGH->out3D_every_default > 0)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING, "Periodic 3D output every %d "
+ "iterations", myGH->out3D_every_default);
+ }
+ else
+ {
+ CCTK_INFO ("Periodic 3D output turned off");
+ }
+ }
+
+ /* re-parse the 'out3D_vars' parameter if it was changed */
+ if (strcmp (out3D_vars, myGH->out3D_vars) || myGH->out3D_every_default != i)
+ {
+ num_vars = CCTK_NumVars ();
+ memset (myGH->out3D_every, 0, num_vars * sizeof (CCTK_INT));
+ if (CCTK_TraverseString (out3D_vars, SetOutputFlag, myGH,
+ CCTK_GROUP_OR_VAR) < 0)
+ {
+ CCTK_WARN (myGH->stop_on_parse_errors ? 0 : 1,
+ "error while parsing parameter 'IOSDF::out3D_vars'");
+ }
+
+ if (myGH->out3D_every_default == i || ! CCTK_Equals (verbose, "none"))
+ {
+ msg = NULL;
+ for (i = 0; i < num_vars; i++)
+ {
+ if (myGH->out3D_every[i] > 0)
+ {
+ fullname = CCTK_FullName (i);
+ if (! msg)
+ {
+ Util_asprintf (&msg, "Periodic 3D output requested for "
+ "'%s'", fullname);
+ }
+ else
+ {
+ Util_asprintf (&msg, "%s, '%s'", msg, fullname);
+ }
+ free (fullname);
+ }
+ }
+ if (msg)
+ {
+ CCTK_INFO (msg);
+ free (msg);
+ }
+ }
+
+ /* save the last setting of 'out3D_vars' parameter */
+ free (myGH->out3D_vars);
+ myGH->out3D_vars = strdup (out3D_vars);
+ }
+}
+
+
+/**************************** local functions ******************************/
+/* check if this variable can be output (static conditions) */
+static int CheckOutputVar (int vindex)
+{
+ int groupindex;
+ cGroup groupinfo;
+ char *fullname;
+ const char *errormsg;
+
+
+ /* get the variable group information */
+ groupindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (groupindex, &groupinfo);
+
+ /* check if variable is grid array type with 3 dimensions */
+ errormsg = NULL;
+ if (groupinfo.dim != 3)
+ {
+ errormsg = "dim != 3";
+ }
+ else if (groupinfo.grouptype != CCTK_GF && groupinfo.grouptype != CCTK_ARRAY)
+ {
+ errormsg = "not a grid function or array";
+ }
+ else if (strncmp (CCTK_VarTypeName (groupinfo.vartype),
+ "CCTK_VARIABLE_REAL", 18) ||
+ CCTK_VarTypeSize (groupinfo.vartype) != sizeof (double))
+ {
+ errormsg = "not a double-precision floating-point grid function or array";
+ }
+
+ if (errormsg)
+ {
+ fullname = CCTK_FullName (vindex);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 3D output for '%s': %s", fullname, errormsg);
+ free (fullname);
+ }
+
+ return (errormsg != NULL);
+}
+
+
+/* callback for CCTK_TraverseString() to set the output flag
+ for the given variable */
+static void SetOutputFlag (int vindex, const char *optstring, void *arg)
+{
+ const ioSDFGH *myGH = arg;
+
+
+ if (CheckOutputVar (vindex) == 0)
+ {
+ myGH->out3D_every[vindex] = myGH->out3D_every_default;
+
+ if (optstring)
+ {
+ IOUtil_ParseOutputFrequency ("3D IOSDF", "IOSDF::out3D_vars",
+ myGH->stop_on_parse_errors,
+ vindex, optstring,
+ &myGH->out3D_every[vindex]);
+ }
+ }
+}
diff --git a/src/Startup.c b/src/Startup.c
new file mode 100644
index 0000000..fbb8b79
--- /dev/null
+++ b/src/Startup.c
@@ -0,0 +1,251 @@
+ /*@@
+ @file Startup.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Startup routines for IOSDF.
+ @enddesc
+ @version $Id$
+ @@*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_IOMethods.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioutil_Utils.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Startup_c)
+
+
+/********************************************************************
+ ******************** Macro Definitions ************************
+ ********************************************************************/
+#define CREATE_OUTDIR(dim, dir) \
+ { \
+ const char *_dir = dir; \
+ \
+ \
+ /* check whether "dir" was set; if not default to "IO::out_dir" */ \
+ if (*_dir == 0) \
+ { \
+ _dir = out_dir; \
+ } \
+ \
+ /* omit the directory name if it's the current working dir */ \
+ if (strcmp (_dir, ".") == 0) \
+ { \
+ myGH->dir = strdup (""); \
+ } \
+ else \
+ { \
+ myGH->dir = malloc (strlen (_dir) + 2); \
+ sprintf (myGH->dir, "%s/", _dir); \
+ } \
+ \
+ /* create the directory */ \
+ i = IOUtil_CreateDirectory (GH, myGH->dir, 0, 0); \
+ if (i < 0) \
+ { \
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, \
+ "IOSDF_SetupGH: Problem creating directory '%s' " \
+ "for %dD output", myGH->dir, dim); \
+ } \
+ else if (i >= 0 && CCTK_Equals (verbose, "full")) \
+ { \
+ CCTK_VInfo (CCTK_THORNSTRING, "%dD output to directory '%s'", \
+ dim, myGH->dir); \
+ } \
+ }
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static void *IOSDF_SetupGH (tFleshConfig *config, int conv_level, cGH *GH);
+
+
+ /*@@
+ @routine IOSDF_Startup
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ The startup registration routine for IOSDF.
+ Registers the GH extensions needed for IOSDF
+ along with its setup routine.
+ @enddesc
+ @calls CCTK_RegisterGHExtension
+ CCTK_RegisterGHExtensionSetupGH
+@@*/
+void IOSDF_Startup (void)
+{
+ CCTK_RegisterGHExtensionSetupGH (CCTK_RegisterGHExtension ("IOSDF"),
+ IOSDF_SetupGH);
+}
+
+
+ /*@@
+ @routine IOSDF_Terminate
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ The termination routine for IOSDF.
+ Closes all open SDF output files.
+ @enddesc
+@@*/
+void IOSDF_Terminate (void)
+{
+ gft_close_all ();
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+ /*@@
+ @routine IOSDF_SetupGH
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Allocates and sets up IOSDF's GH extension structure
+ @enddesc
+
+ @calls CCTK_RegisterIOMethod
+ CCTK_RegisterIOMethodOutputGH
+ CCTK_RegisterIOMethodOutputVarAs
+ CCTK_RegisterIOMethodTimeToOutput
+ CCTK_RegisterIOMethodTriggerOutput
+
+ @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 *IOSDF_SetupGH (tFleshConfig *config, int conv_level, cGH *GH)
+{
+ int i, maxdim, numvars;
+ ioSDFGH *myGH;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* suppress compiler warnings about unused variables */
+ (void) (config + 0);
+ (void) (conv_level + 0);
+ (void) (GH + 0);
+
+ /* allocate the GH extension and its components */
+ myGH = malloc (sizeof (ioSDFGH));
+ if (! myGH)
+ {
+ CCTK_WARN (0, "IOSDF_SetupGH: Unable to allocate memory for GH");
+ }
+
+ /* register the IOSDF routines as output methods */
+ i = CCTK_RegisterIOMethod ("IOSDF_1D");
+ CCTK_RegisterIOMethodOutputGH (i, IOSDF_Output1DGH);
+ CCTK_RegisterIOMethodOutputVarAs (i, IOSDF_Output1DVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (i, IOSDF_TimeFor1D);
+ CCTK_RegisterIOMethodTriggerOutput (i, IOSDF_TriggerOutput1D);
+
+ /* only register N-D IOSDF I/O methods
+ if at least N-dimensional grid variables are defined by thorns */
+ maxdim = CCTK_MaxDim ();
+ if (maxdim >= 2)
+ {
+ i = CCTK_RegisterIOMethod ("IOSDF_2D");
+ CCTK_RegisterIOMethodOutputGH (i, IOSDF_Output2DGH);
+ CCTK_RegisterIOMethodOutputVarAs (i, IOSDF_Output2DVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (i, IOSDF_TimeFor2D);
+ CCTK_RegisterIOMethodTriggerOutput (i, IOSDF_TriggerOutput2D);
+ }
+
+ if (maxdim >= 3)
+ {
+ i = CCTK_RegisterIOMethod ("IOSDF_3D");
+ CCTK_RegisterIOMethodOutputGH (i, IOSDF_Output3DGH);
+ CCTK_RegisterIOMethodOutputVarAs (i, IOSDF_Output3DVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (i, IOSDF_TimeFor3D);
+ CCTK_RegisterIOMethodTriggerOutput (i, IOSDF_TriggerOutput3D);
+ }
+
+ numvars = CCTK_NumVars ();
+ myGH->out1D_every = malloc (numvars * sizeof (CCTK_INT));
+ myGH->out2D_every = malloc (numvars * sizeof (CCTK_INT));
+ myGH->out3D_every = malloc (numvars * sizeof (CCTK_INT));
+ myGH->out1D_last = malloc (numvars * sizeof (int));
+ myGH->out2D_last = malloc (numvars * sizeof (int));
+ myGH->out3D_last = malloc (numvars * sizeof (int));
+
+ for (i = 0; i < numvars; i++)
+ {
+ myGH->out1D_last[i] = -1;
+ myGH->out2D_last[i] = -1;
+ myGH->out3D_last[i] = -1;
+ }
+
+ myGH->out1D_vars = strdup ("");
+ myGH->out2D_vars = strdup ("");
+ myGH->out3D_vars = strdup ("");
+ myGH->out1D_every_default = out1D_every - 1;
+ myGH->out2D_every_default = out2D_every - 1;
+ myGH->out3D_every_default = out3D_every - 1;
+
+ myGH->fileList_1D = NULL;
+ myGH->fileList_2D = NULL;
+ myGH->fileList_3D = NULL;
+
+ myGH->stop_on_parse_errors = strict_io_parameter_check;
+ if (! CCTK_Equals (verbose, "none"))
+ {
+ CCTK_INFO ("I/O Method 'IOSDF_1D' registered: output of 1D lines of grid "
+ "functions/arrays to SDF files");
+ }
+ IOSDF_CheckSteerableParameters1D (myGH);
+ if (maxdim >= 2)
+ {
+ if (! CCTK_Equals (verbose, "none"))
+ {
+ CCTK_INFO ("I/O Method 'IOSDF_2D' registered: output of 2D planes of "
+ "grid functions/arrays to SDF files");
+ }
+ IOSDF_CheckSteerableParameters2D (myGH);
+ }
+ if (maxdim >= 3)
+ {
+ if (! CCTK_Equals (verbose, "none"))
+ {
+ CCTK_INFO ("I/O Method 'IOSDF_3D' registered: output of 3D grid "
+ "functions/arrays to SDF files");
+ }
+ IOSDF_CheckSteerableParameters3D (myGH);
+ }
+ myGH->stop_on_parse_errors = 0;
+
+ /* make sure all output directories exist */
+ CREATE_OUTDIR (1, out1D_dir);
+ CREATE_OUTDIR (2, out2D_dir);
+ CREATE_OUTDIR (3, out3D_dir);
+
+ return (myGH);
+}
diff --git a/src/Write1D.c b/src/Write1D.c
new file mode 100644
index 0000000..debf166
--- /dev/null
+++ b/src/Write1D.c
@@ -0,0 +1,436 @@
+/*@@
+ @file Write1D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Output one-dimensional lines in SDF file format.
+ @enddesc
+ @version $Id$
+@@*/
+
+#include <math.h> /* sqrt(3) */
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_Table.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Header$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Write1D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static char *OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ const cGroup *gdata,
+ int dir);
+
+
+/*@@
+ @routine IOSDF_Write1D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ This routine does 1D line output along the orthogonals
+ and the diagonal (in case of a cubed grid).
+ <p>
+ It writes to SDF files suitable for gnuplot and xgraph.
+ A header telling the physical time prefixes the output data.
+ @enddesc
+ @calls Hyperslab_GlobalMappingByIndex
+ Hyperslab_FreeMapping
+ Hyperslab_GetList
+ OpenFile
+ WriteData
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc global index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name (used for creating the output filename)
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 0 for success, or<BR>
+ -1 if variable has no storage assigned
+ @endreturndesc
+@@*/
+int IOSDF_Write1D (const cGH *GH, int vindex, const char *alias)
+{
+ ioSDFGH *myGH;
+ int do_dir[4], coord_index[3];
+ int i, dir, myproc, gindex, have_coords, mapping;
+ int num_requested_hslabs, num_returned_hslabs;
+ int *extent_int;
+ cGroup gdata;
+ char *fullname, *groupname, *filename;
+ CCTK_INT coord_system_handle, coord_handles[3];
+ double offset;
+ CCTK_REAL coord_lower[3];
+ CCTK_INT downsample[4];
+ CCTK_INT *origin, *direction;
+ CCTK_INT hsize, extent;
+ CCTK_INT vindices[2];
+ double *hdata[2];
+ const double dtime = GH->cctk_time;
+ const char *coordnames[] = {"x", "y", "z", "d"};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get the variable's group index and its full name */
+ gindex = CCTK_GroupIndexFromVarI (vindex);
+ fullname = CCTK_FullName (vindex);
+
+ /* check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, gindex))
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: No IOSDF_1D output for '%s' (no storage)",
+ fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* get the handle for IOSDF extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* get the variable's group information */
+ CCTK_GroupData (gindex, &gdata);
+
+ /* see what slices should be output */
+ do_dir[0] = out1D_x && gdata.dim >= 1;
+ do_dir[1] = out1D_y && gdata.dim >= 2;
+ do_dir[2] = out1D_z && gdata.dim >= 3;
+ /* diagonal slice is done only if variable is non-staggered and 3D */
+ do_dir[3] = out1D_d && gdata.dim == 3 && gdata.stagtype == 0;
+ if (out1D_d && ! do_dir[3] && myGH->out1D_last[vindex] < 0)
+ {
+ CCTK_VWarn (3, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: No IOSDF_1D diagonal output for '%s' "
+ "(only implemented for non-staggered 3D variables)",
+ fullname);
+ }
+
+ /* return if nothing to do */
+ if (! (do_dir[0] || do_dir[1] || do_dir[2] || do_dir[3]))
+ {
+ free (fullname);
+ return (0);
+ }
+
+ /* get the coordinate system associated with this grid variable */
+ groupname = CCTK_GroupName (gindex);
+ coord_system_handle = Coord_GroupSystem (GH, groupname);
+ free (groupname);
+
+ dir = gdata.dim < 3 ? gdata.dim : 3;
+
+ have_coords = coord_system_handle >= 0 &&
+ Util_TableGetIntArray (coord_system_handle, dir,
+ coord_handles, "COORDINATES") >= 0;
+ if (have_coords)
+ {
+ /* get the coordinate functions and coordinate physical minimum */
+ for (i = 0; i < dir; i++)
+ {
+ coord_index[i] = -1;
+ coord_lower[i] = 0;
+ Util_TableGetInt (coord_handles[i], &coord_index[i], "GAINDEX");
+ Util_TableGetReal (coord_handles[i], &coord_lower[i], "COMPMIN");
+ have_coords &= coord_index[i] >= 0;
+ }
+ }
+
+ myproc = CCTK_MyProc (GH);
+
+ origin = calloc (2*gdata.dim, sizeof (CCTK_INT));
+ direction = origin + gdata.dim;
+ extent_int = malloc ((gdata.dim + 1) * sizeof (int));
+
+ /* set downsampling vector from I/O parameters */
+ downsample[0] = out_downsample_x;
+ downsample[1] = out_downsample_y;
+ downsample[2] = out_downsample_z;
+ downsample[3] = 1;
+
+ /* get the variable's extents, compute the extent for 3D-diagonals as the
+ minimum of grid points in each direction */
+ CCTK_GroupgshVI (GH, gdata.dim, extent_int, vindex);
+ if (gdata.dim == 3)
+ {
+ extent_int[3] = extent_int[0] < extent_int[1] ?
+ extent_int[0] : extent_int[1];
+ if (extent_int[2] < extent_int[3])
+ {
+ extent_int[3] = extent_int[2];
+ }
+ }
+ /* get the total number of grid points to check for zero-sized variables */
+ for (dir = 0, hsize = 1; dir < gdata.dim; dir++)
+ {
+ hsize *= extent_int[dir];
+ }
+
+ /* now do the actual I/O looping over all directions */
+ for (dir = 0; dir < 4; dir++)
+ {
+ if (hsize <= 0)
+ {
+ continue;
+ }
+
+ /* skip empty slices */
+ if (! do_dir[dir])
+ {
+ continue;
+ }
+
+ /* processor 0 opens the files with the appropriate name */
+ filename = NULL;
+ if (myproc == 0)
+ {
+ filename = OpenFile (GH, fullname, alias, &gdata, dir);
+ }
+
+ /* get the number of hyperslabs to extract
+ (ie. whether to get a coordinate hyperslab too or not) */
+ num_requested_hslabs = have_coords && dir < 3 ? 2 : 1;
+
+ /* set the direction vector */
+ for (i = 0; i < gdata.dim; i++)
+ {
+ direction[i] = (dir == i || dir == 3) ? 1 : 0;
+ }
+
+ /* set the extent */
+ extent = extent_int[dir];
+
+ /* set the origin of the line */
+ if (gdata.grouptype == CCTK_GF && dir < 3)
+ {
+ for (i = 0; i < gdata.dim; i++)
+ {
+ origin[i] = myGH->spxyz[gdata.dim-1][dir][i];
+ }
+ extent -= origin[dir];
+
+ /* correct extent in the case of staggered grids */
+ if (CCTK_StaggerDirIndex(dir,gdata.stagtype)==1)
+ {
+ --extent;
+ }
+ }
+ else /* origin for CCTK_ARRAYS is always (0, 0, 0) */
+ {
+ memset (origin, 0, gdata.dim * sizeof (CCTK_INT));
+ }
+
+ mapping = Hyperslab_GlobalMappingByIndex (GH, vindex, 1,
+ direction, origin, &extent,
+ &downsample[dir],
+ -1, /* table handle */
+ NULL /* conversion fn */,
+ &hsize);
+ if (mapping < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: Failed to define hyperslab mapping for "
+ "variable '%s'", fullname);
+ continue;
+ }
+ if (hsize <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: selected hyperslab has zero size for "
+ "variable '%s' direction %d", fullname, dir);
+ Hyperslab_FreeMapping (mapping);
+ continue;
+ }
+
+ /* allocate hyperslab buffers on I/O processor */
+ hdata[0] = hdata[1] = NULL;
+ if (myproc == 0)
+ {
+ hdata[0] = malloc (hsize * sizeof (double));
+ hdata[1] = have_coords ? malloc (hsize * sizeof (double)) : NULL;
+ }
+
+ /* get the hyperslabs */
+ vindices[0] = vindex;
+ vindices[1] = coord_index[dir];
+ num_returned_hslabs = Hyperslab_GetList (GH, mapping, num_requested_hslabs,
+ NULL, vindices, NULL, NULL,
+ (void **) hdata, NULL);
+
+ /* release the mapping structure */
+ Hyperslab_FreeMapping (mapping);
+
+ /* And dump the data to file */
+ if (num_returned_hslabs != num_requested_hslabs)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write1D: Failed to extract hyperslab for "
+ "variable '%s'", fullname);
+ }
+ else if (filename)
+ {
+ if (have_coords)
+ {
+ if (dir < 3)
+ {
+ /* get the staggering offset for the xyz coordinates */
+ offset = 0.5 * GH->cctk_delta_space[dir] *
+ CCTK_StaggerDirIndex (dir, gdata.stagtype);
+ for (i = 0; i < hsize; i++)
+ {
+ hdata[1][i] += offset;
+ }
+ }
+ else
+ {
+ /* calculate the diagonal coordinates */
+ offset = GH->cctk_delta_space[0] * sqrt (3);
+ for (i = 0; i < hsize; i++)
+ {
+ hdata[1][i] = coord_lower[0]*sqrt (3) + i*offset;
+ }
+ }
+ }
+
+ extent_int[0] = hsize;
+ i = have_coords ? gft_out_full (filename, dtime, extent_int,
+ coordnames[dir], 1, hdata[1], hdata[0]):
+ gft_out_brief (filename, dtime, extent_int,
+ 1, hdata[0]);
+ if (i <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error writing to 1D IOSDF output file '%s'", filename);
+ }
+ }
+
+ /* clean up */
+ free (hdata[0]);
+ free (hdata[1]);
+ } /* end of loop through all directions */
+
+ /* free allocated resources */
+ free (origin);
+ free (fullname);
+ free (extent_int);
+
+ return (0);
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+/*@@
+ @routine OpenFile
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Opens a set of SDF files for a given alias name.
+ If this is the first time through, it will advertise them
+ to IOUtil.
+ @enddesc
+ @@*/
+static char *OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ const cGroup *gdata,
+ int dir)
+{
+ ioSDFGH *myGH;
+ int upper, lower;
+ char *filename, *nameddata;
+ char slicename[40];
+ ioAdvertisedFileDesc advertised_file;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get handle for and IOSDF GH extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ nameddata = malloc (strlen (alias) + 3);
+ sprintf (nameddata, "%s_%d", alias, dir);
+ filename = GetNamedData (myGH->fileList_1D, nameddata);
+ if (filename)
+ {
+ free (nameddata);
+ return (filename);
+ }
+
+ /* get the indices into spxyz[] */
+ lower = (dir + 1) % 3;
+ upper = (dir + 2) % 3;
+ if (upper < lower)
+ {
+ upper = lower;
+ lower = 0;
+ }
+
+ if (dir < 3)
+ {
+ if (gdata->dim == 1)
+ {
+ strcpy (slicename, "1D");
+ }
+ else if (gdata->dim == 2)
+ {
+ /* give the slice origin as range [1 .. n] */
+ sprintf (slicename, "%c_%d", 'x' + dir,
+ gdata->grouptype == CCTK_GF ?
+ myGH->spxyz[gdata->dim-1][dir][lower] : 0);
+ }
+ else
+ {
+ /* give the slice origin as range [1 .. n] */
+ sprintf (slicename, "%c_%d_%d", 'x' + dir,
+ gdata->grouptype == CCTK_GF ?
+ myGH->spxyz[gdata->dim-1][dir][lower] : 0,
+ gdata->grouptype == CCTK_GF ?
+ myGH->spxyz[gdata->dim-1][dir][upper] : 0);
+ }
+ }
+ else
+ {
+ sprintf (slicename, "%dD_diagonal", gdata->dim);
+ }
+
+ filename = malloc (strlen (myGH->out1D_dir) + strlen (alias) +
+ sizeof (slicename) + 6);
+ sprintf (filename, "%s%s_%s.sdf", myGH->out1D_dir, alias, slicename);
+ StoreNamedData (&myGH->fileList_1D, nameddata, filename);
+ free (nameddata);
+
+ /* advertise the output file */
+ advertised_file.slice = slicename;
+ advertised_file.thorn = CCTK_THORNSTRING;
+ advertised_file.varname = fullname;
+ advertised_file.description = "One-dimensional line plots";
+ advertised_file.mimetype = "application/sdf";
+
+ IOUtil_AdvertiseFile (GH, filename, &advertised_file);
+
+ return (filename);
+}
diff --git a/src/Write2D.c b/src/Write2D.c
new file mode 100644
index 0000000..551e0c8
--- /dev/null
+++ b/src/Write2D.c
@@ -0,0 +1,371 @@
+/*@@
+ @file Write2D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Output two-dimensional slices in SDF file format.
+ @enddesc
+ @version $Id$
+ @@*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_Table.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Id$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Write2D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static char **OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ int dim,
+ int maxdir);
+
+
+/*@@
+ @routine IOSDF_Write2D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Writes the 2D slices of a variable into separate SDF files.
+ @enddesc
+ @calls Hyperslab_GlobalMappingByIndex
+ Hyperslab_FreeMapping
+ Hyperslab_GetList
+ OpenFile
+ WriteData
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 0 for success, or<BR>
+ -1 if variable has no storage assigned<BR>
+ -2 if output file couldn't be opened<BR>
+ -3 if hyperslab for coordinates and/or variable couldn't be
+ extracted
+ @endreturndesc
+@@*/
+int IOSDF_Write2D (const cGH *GH, int vindex, const char *alias)
+{
+ ioSDFGH *myGH;
+ int i, total_hsize, num_requested_hslabs, num_returned_hslabs;
+ int dir, dir_i, dir_j, maxdir, myproc, gindex, have_coords;
+ int mapping;
+ cGroup gdata;
+ int coord_index[3];
+ CCTK_INT coord_system_handle, coord_handles[3];
+ char *fullname, *groupname;
+ int extent_int[3];
+ double offset[2];
+ CCTK_INT vindices[3], origin[3], extent[2], direction[6], downsample[2],
+ hsize[2];
+ double *hdata[3];
+ char **filenames;
+ const double dtime = GH->cctk_time;
+ const char *coordnames[] = {"x|y", "x|z", "y|z"};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get the variable name and group information */
+ fullname = CCTK_FullName (vindex);
+ gindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (gindex, &gdata);
+
+ /* check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, gindex))
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 2D output for '%s' (no storage)", fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* get the handle for IOSDF extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* get the number of slices to output */
+ /* in general: maxdir = gdata.dim * (gdata.dim - 1) / 2; */
+ maxdir = gdata.dim == 2 ? 1 : 3;
+
+ /* get the coordinate system associated with this grid variable */
+ groupname = CCTK_GroupName (gindex);
+ coord_system_handle = Coord_GroupSystem (GH, groupname);
+ free (groupname);
+
+ dir = gdata.dim < 3 ? gdata.dim : 3;
+
+ have_coords = coord_system_handle >= 0 &&
+ Util_TableGetIntArray (coord_system_handle, dir,
+ coord_handles, "COORDINATES") >= 0;
+ if (have_coords)
+ {
+ /* get the coordinate functions and coordinate physical minimum */
+ for (i = 0; i < dir; i++)
+ {
+ coord_index[i] = -1;
+ Util_TableGetInt (coord_handles[i], &coord_index[i], "GAINDEX");
+ have_coords &= coord_index[i] >= 0;
+ }
+ }
+ num_requested_hslabs = have_coords ? 3 : 1;
+
+ /* processor 0 opens the files on the first trip through */
+ filenames = NULL;
+ myproc = CCTK_MyProc (GH);
+ if (myproc == 0)
+ {
+ filenames = OpenFile (GH, fullname, alias, gdata.dim, maxdir);
+ }
+
+ /* get the extents of the variable */
+ CCTK_GroupgshVI (GH, gdata.dim, extent_int, vindex);
+
+ /* get the total number of grid points to check for zero-sized variables */
+ for (dir = 0, hsize[0] = 1; dir < gdata.dim; dir++)
+ {
+ hsize[0] *= extent_int[dir];
+ }
+
+ /* now do the actual I/O looping over all directions */
+ for (dir = 0; dir < maxdir; dir++)
+ {
+ if (hsize[0] <= 0)
+ {
+ continue;
+ }
+
+ /* get the directions to span the hyperslab */
+ if (dir == 0)
+ {
+ dir_i = 0; dir_j = 1; /* xy */
+ downsample[0] = out_downsample_x; downsample[1] = out_downsample_y;
+ }
+ else if (dir == 1)
+ {
+ dir_i = 0; dir_j = 2; /* xz */
+ downsample[0] = out_downsample_x; downsample[1] = out_downsample_z;
+ }
+ else
+ {
+ dir_i = 1; dir_j = 2; /* yz */
+ downsample[0] = out_downsample_y; downsample[1] = out_downsample_z;
+ }
+
+ /* set the extent vector */
+ extent[0] = extent_int[dir_i];
+ extent[1] = extent_int[dir_j];
+
+ /* set the origin using the slice center from IOUtil */
+ memset (origin, 0, sizeof (origin));
+ if (have_coords)
+ {
+ origin[maxdir-dir-1] = myGH->sp2xyz[gdata.dim-1][dir];
+ }
+
+ /* set the direction vector */
+ memset (direction, 0, sizeof (direction));
+ direction[dir_i] = direction[gdata.dim + dir_j] = 1;
+
+ mapping = Hyperslab_GlobalMappingByIndex (GH, vindex, 2,
+ direction, origin, extent,
+ downsample,
+ -1, /* table handle */
+ NULL /* conversion fn */,
+ hsize);
+ if (mapping < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write2D: Failed to define hyperslab mapping for "
+ "variable '%s'", fullname);
+ continue;
+ }
+ total_hsize = hsize[0] * hsize[1];
+ if (total_hsize <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write2D: selected hyperslab has zero size for "
+ "variable '%s' direction %d", fullname, dir);
+ Hyperslab_FreeMapping (mapping);
+ continue;
+ }
+
+ hdata[0] = hdata[1] = hdata[2];
+ if (myproc == 0)
+ {
+ /* allocate hyperslab buffers */
+ hdata[0] = malloc (total_hsize * sizeof (double));
+ hdata[1] = have_coords ? malloc (2 * total_hsize * sizeof(double)) : NULL;
+ hdata[2] = hdata[1] + total_hsize;
+ }
+
+ /* get the hyperslabs */
+ vindices[0] = vindex;
+ vindices[1] = coord_index[dir_i];
+ vindices[2] = coord_index[dir_j];
+ num_returned_hslabs = Hyperslab_GetList (GH, mapping, num_requested_hslabs,
+ NULL, vindices, NULL, NULL,
+ (void **) hdata, NULL);
+
+ /* release the mapping structure */
+ Hyperslab_FreeMapping (mapping);
+
+ /* and dump the data to file */
+ if (filenames)
+ {
+ if (num_returned_hslabs == num_requested_hslabs)
+ {
+ if (have_coords)
+ {
+ /* get the staggering offset for the coordinates */
+ offset[0] = 0.5 * GH->cctk_delta_space[dir_i] *
+ CCTK_StaggerDirIndex (dir_i, gdata.stagtype);
+ offset[1] = 0.5 * GH->cctk_delta_space[dir_j] *
+ CCTK_StaggerDirIndex (dir_j, gdata.stagtype);
+ for (i = 0; i < total_hsize; i++)
+ {
+ hdata[1][i] += offset[0];
+ hdata[2][i] += offset[1];
+ }
+ }
+
+ extent[0] = hsize[0];
+ extent[1] = hsize[1];
+
+ i = have_coords ? gft_out_full (filenames[dir], dtime, extent_int,
+ coordnames[dir], 2, hdata[1], hdata[0]):
+ gft_out_brief (filenames[dir], dtime, extent_int,
+ 2, hdata[0]);
+ if (i <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error writing to 2D IOSDF output file '%s'",
+ filenames[dir]);
+ }
+ }
+ else
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write2D: Failed to extract hyperslab for "
+ "variable '%s'", fullname);
+ }
+
+ /* clean up */
+ free (hdata[0]);
+ free (hdata[1]);
+
+ } /* end of outputting the data by processor 0 */
+
+ } /* end of looping through xyz directions */
+
+ free (fullname);
+
+ return (0);
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+/*@@
+ @routine OpenFile
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Opens a set of SDF files for a given alias name.
+ If this is the first time through, it will advertise them
+ to IOUtil.
+ @enddesc
+
+ @returntype char **
+ @returndesc
+ the set of full filenames
+ @endreturndesc
+ @@*/
+static char **OpenFile (const cGH *GH,
+ const char *fullname,
+ const char *alias,
+ int dim,
+ int maxdir)
+{
+ int dir;
+ char **filenames;
+ ioSDFGH *myGH;
+ ioAdvertisedFileDesc advertised_file;
+ char slicename[30];
+ const char *extensions[] = {"xy", "xz", "yz"};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get handle for IOSDF GH extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* see if we are the first time through */
+ filenames = GetNamedData (myGH->fileList_2D, alias);
+ if (filenames)
+ {
+ return (filenames);
+ }
+
+ filenames = malloc (maxdir * sizeof (char **));
+
+ /* open/create files for each slice */
+ for (dir = 0; dir < maxdir; dir++)
+ {
+ filenames[dir] = malloc (strlen (myGH->out2D_dir) + strlen (alias) +
+ sizeof (slicename) + 20);
+
+ if (dim == 2)
+ {
+ strcpy (slicename, "2D");
+ }
+ else
+ {
+ /* give the slice origin as range [1 .. n] */
+ sprintf (slicename, "%s_%d", extensions[dir],
+ myGH->sp2xyz[dim-1][dir]);
+ }
+
+ sprintf (filenames[dir], "%s%s_%s.sdf", myGH->out2D_dir, alias, slicename);
+
+ /* advertise the file for downloading and write file info */
+ advertised_file.slice = slicename;
+ advertised_file.thorn = CCTK_THORNSTRING;
+ advertised_file.varname = fullname;
+ advertised_file.description = "Two-dimensional slice plots";
+ advertised_file.mimetype = "application/sdf";
+
+ IOUtil_AdvertiseFile (GH, filenames[dir], &advertised_file);
+ }
+
+ /* store file desriptors in database */
+ StoreNamedData (&myGH->fileList_2D, alias, filenames);
+
+ return (filenames);
+}
diff --git a/src/Write3D.c b/src/Write3D.c
new file mode 100644
index 0000000..f07ef55
--- /dev/null
+++ b/src/Write3D.c
@@ -0,0 +1,292 @@
+/*@@
+ @file Write3D.c
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Three-dimensional output of variables in SDF file format.
+ @enddesc
+ @version $Id$
+ @@*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "util_Table.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h"
+#include "ioSDFGH.h"
+
+/* the rcs ID and its dummy function to use it */
+static const char *rcsid = "$Header$";
+CCTK_FILEVERSION(CactusIO_IOSDF_Write3D_c)
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static char *OpenFile (const cGH *GH, const char *fullname, const char *alias);
+
+/*@@
+ @routine IOSDF_Write3D
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Writes the 3D volume of a variable into a gnuplot SDF file.
+ @enddesc
+ @calls Hyperslab_GlobalMappingByIndex
+ Hyperslab_FreeMapping
+ Hyperslab_GetList
+ OpenFile
+
+ @var GH
+ @vdesc Pointer to CCTK GH
+ @vtype const cGH *
+ @vio in
+ @endvar
+ @var vindex
+ @vdesc index of variable to output
+ @vtype int
+ @vio in
+ @endvar
+ @var alias
+ @vdesc alias name of variable to output
+ @vtype const char *
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ 0 for success, or<BR>
+ -1 if variable has no storage assigned<BR>
+ -2 if output file couldn't be opened<BR>
+ -3 if hyperslab for coordinates and/or variable couldn't be
+ extracted
+ @endreturndesc
+@@*/
+int IOSDF_Write3D (const cGH *GH, int vindex, const char *alias)
+{
+ int i, total_hsize;
+ int myproc, gindex, have_coords;
+ int num_requested_hslabs, num_returned_hslabs;
+ cGroup gdata;
+ CCTK_INT coord_system_handle, coord_handles[3];
+ char *fullname, *groupname, *filename;
+ double *hdata[4];
+ int extent_int[3];
+ double offset[3];
+ int mapping;
+ CCTK_INT vindices[4], extent[3], downsample[3], hsize[3];
+ const double dtime = GH->cctk_time;
+ const CCTK_INT origin[] = {0, 0, 0},
+ direction[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get the variable group information */
+ fullname = CCTK_FullName (vindex);
+ gindex = CCTK_GroupIndexFromVarI (vindex);
+ CCTK_GroupData (gindex, &gdata);
+
+ /* check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, gindex))
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOSDF 3D output for '%s' (no storage)", fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* get the coordinate system associated with this grid variable */
+ vindices[0] = vindex;
+ groupname = CCTK_GroupName (gindex);
+ coord_system_handle = Coord_GroupSystem (GH, groupname);
+ free (groupname);
+
+ have_coords = coord_system_handle >= 0 &&
+ Util_TableGetIntArray (coord_system_handle, 3,
+ coord_handles, "COORDINATES") >= 0;
+ if (have_coords)
+ {
+ /* get the coordinate functions and coordinate physical minimum */
+ for (i = 1; i <= 3; i++)
+ {
+ vindices[i] = -1;
+ Util_TableGetInt (coord_handles[i-1], &vindices[i], "GAINDEX");
+ have_coords &= vindices[i] >= 0;
+ }
+ }
+ num_requested_hslabs = have_coords ? 4 : 1;
+
+ /* What processor are we on? */
+ myproc = CCTK_MyProc (GH);
+
+ /* Open the file on processor 0 */
+ filename = myproc == 0 ? OpenFile (GH, fullname, alias) : NULL;
+
+ /* get the total number of grid points to check for zero-sized variables */
+ /* set the extent vector (copy from 'int' to 'CCTK_INT') */
+ CCTK_GroupgshVI (GH, 3, extent_int, vindex);
+ for (i = 0, total_hsize = 1; i < 3; i++)
+ {
+ total_hsize *= extent_int[i];
+ extent[i] = extent_int[i];
+ }
+ if (total_hsize <= 0)
+ {
+ free (fullname);
+ return (0);
+ }
+
+ downsample[0] = out_downsample_x;
+ downsample[1] = out_downsample_y;
+ downsample[2] = out_downsample_z;
+
+ /* get the hyperslab mapping */
+ mapping = Hyperslab_GlobalMappingByIndex (GH, vindex, 3,
+ direction, origin, extent,
+ downsample,
+ -1, /* table handle */
+ NULL /* conversion fn */,
+ hsize);
+ if (mapping < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write3D: Failed to define hyperslab mapping for "
+ "variable '%s'", fullname);
+ free (fullname);
+ return (-1);
+ }
+ for (i = 0, total_hsize = 1; i < 3; i++)
+ {
+ extent_int[i] = hsize[i];
+ total_hsize *= hsize[i];
+ }
+ if (total_hsize <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write3D: selected hyperslab has zero size for "
+ "variable '%s'", fullname);
+ Hyperslab_FreeMapping (mapping);
+ free (fullname);
+ return (-1);
+ }
+
+ hdata[0] = hdata[1] = hdata[2] = hdata[3];
+ if (myproc == 0)
+ {
+ /* allocate hyperslab buffers */
+ hdata[0] = malloc (total_hsize * sizeof (double));
+ hdata[1] = have_coords ? malloc (3 * total_hsize * sizeof (double)) : NULL;
+ hdata[2] = hdata[1] + 1*total_hsize;
+ hdata[3] = hdata[1] + 2*total_hsize;
+ }
+
+ /* get the hyperslabs */
+ num_returned_hslabs = Hyperslab_GetList (GH, mapping, num_requested_hslabs,
+ NULL, vindices, NULL, NULL,
+ (void **) hdata, NULL);
+
+ /* And dump the data to file */
+ if (myproc == 0)
+ {
+ if (num_returned_hslabs == num_requested_hslabs)
+ {
+ if (have_coords)
+ {
+ /* get the staggering offset for the coordinates */
+ for (i = 0; i < 3; i++)
+ {
+ offset[i] = 0.5 * GH->cctk_delta_space[i] *
+ CCTK_StaggerDirIndex (i, gdata.stagtype);
+ }
+ for (i = 0; i < total_hsize; i++)
+ {
+ hdata[1][i] += offset[0];
+ hdata[2][i] += offset[1];
+ hdata[3][i] += offset[2];
+ }
+ }
+
+ i = have_coords ? gft_out_full (filename, dtime, extent_int, "x|y|z", 3,
+ hdata[1], hdata[0]) :
+ gft_out_brief (filename, dtime, extent_int, 3,hdata[0]);
+ if (i <= 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error writing to 3D IOSDF output file '%s'", filename);
+ }
+ }
+ else
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOSDF_Write3D: Failed to extract hyperslab for "
+ "variable '%s'", fullname);
+ }
+
+ /* clean up */
+ free (hdata[0]);
+ free (hdata[1]);
+ } /* end of outputting the data by processor 0 */
+
+ free (fullname);
+
+ return (0);
+}
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+/*@@
+ @routine OpenFile
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ Opens an SDF file for a given alias name.
+ If this is the first time through, it will advertise it
+ to IOUtil.
+ @enddesc
+
+ @returntype char *
+ @returndesc
+ the full filename of the SDF output file
+ @endreturndesc
+ @@*/
+static char *OpenFile (const cGH *GH, const char *fullname, const char *alias)
+{
+ char *filename;
+ ioSDFGH *myGH;
+ ioAdvertisedFileDesc advertised_file;
+ DECLARE_CCTK_PARAMETERS
+
+
+ /* get handle for IOSDF GH extensions */
+ myGH = CCTK_GHExtension (GH, "IOSDF");
+
+ /* see if we are the first time through */
+ filename = GetNamedData (myGH->fileList_3D, alias);
+ if (! filename)
+ {
+ filename = malloc (strlen (myGH->out3D_dir) + strlen (alias) + 9);
+
+ /* open/create the file */
+ sprintf (filename, "%s%s_3D.sdf", myGH->out3D_dir, alias);
+
+ /* advertise the file for downloading and write file info */
+ advertised_file.slice = "";
+ advertised_file.thorn = CCTK_THORNSTRING;
+ advertised_file.varname = fullname;
+ advertised_file.description = "Full-dimensional variable contents";
+ advertised_file.mimetype = "application/sdf";
+
+ IOUtil_AdvertiseFile (GH, filename, &advertised_file);
+
+ /* store filename in database */
+ StoreNamedData (&myGH->fileList_3D, alias, filename);
+ }
+
+ return (filename);
+}
diff --git a/src/ioSDFGH.h b/src/ioSDFGH.h
new file mode 100644
index 0000000..e31867b
--- /dev/null
+++ b/src/ioSDFGH.h
@@ -0,0 +1,87 @@
+ /*@@
+ @header ioSDFGH.h
+ @date Sat 12 June 2004
+ @author Thomas Radke
+ @desc
+ The extensions to the GH structure from IOSDF.
+ @version $Header$
+ @@*/
+
+#ifndef _IOSDF_IOSDFGH_H_
+#define _IOSDF_IOSDFGH_H_ 1
+
+#include "StoreNamedData.h"
+#include "bbhutil.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct IOSDFGH
+{
+ /* default number of times to output */
+ int out1D_every_default, out2D_every_default, out3D_every_default;
+
+ /* number of times to output every variable */
+ CCTK_INT *out1D_every, *out2D_every, *out3D_every;
+
+ /* lists of variables to output */
+ char *out1D_vars, *out2D_vars, *out3D_vars;
+
+ /* directories in which to output */
+ char *out1D_dir, *out2D_dir, *out3D_dir;
+
+ /* the last iteration output for var [i] */
+ int *out1D_last, *out2D_last, *out3D_last;
+
+ /* database for names of output files that were already created */
+ pNamedData *fileList_1D, *fileList_2D, *fileList_3D;
+
+ /* for 1D lines, we define the index where to start the line:
+ spxyz[maxdim][XYZdirection][xyzstart_index] */
+ int ***spxyz;
+
+ /* for 2D planes, we define the index where to locate the plane
+ sp2xyz[maxdim][perpendicular direction] */
+ int **sp2xyz;
+
+ /* stop on I/O parameter parsing errors ? */
+ int stop_on_parse_errors;
+
+} ioSDFGH;
+
+
+/* prototypes of functions to be registered as I/O methods */
+int IOSDF_Output1DGH (const cGH *GH);
+int IOSDF_TriggerOutput1D (const cGH *GH, int);
+int IOSDF_TimeFor1D (const cGH *GH, int);
+int IOSDF_Output1DVarAs (const cGH *GH, const char *var, const char *alias);
+int IOSDF_Output2DGH (const cGH *GH);
+int IOSDF_TriggerOutput2D (const cGH *GH, int);
+int IOSDF_TimeFor2D (const cGH *GH, int);
+int IOSDF_Output2DVarAs (const cGH *GH, const char *var, const char *alias);
+int IOSDF_Output3DGH (const cGH *GH);
+int IOSDF_TriggerOutput3D (const cGH *GH, int);
+int IOSDF_TimeFor3D (const cGH *GH, int);
+int IOSDF_Output3DVarAs (const cGH *GH, const char *var, const char *alias);
+
+/* other function prototypes */
+void IOSDF_Startup (void);
+
+int IOSDF_Write1D (const cGH *GH, int vindex, const char *alias);
+int IOSDF_Write2D (const cGH *GH, int vindex, const char *alias);
+int IOSDF_Write3D (const cGH *GH, int vindex, const char *alias);
+
+void IOSDF_Choose1D (const cGH *GH);
+void IOSDF_Choose2D (const cGH *GH);
+
+void IOSDF_CheckSteerableParameters1D (ioSDFGH *myGH);
+void IOSDF_CheckSteerableParameters2D (ioSDFGH *myGH);
+void IOSDF_CheckSteerableParameters3D (ioSDFGH *myGH);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* _IOSDF_IOSDFGH_H_ */
diff --git a/src/make.code.defn b/src/make.code.defn
new file mode 100644
index 0000000..8bf6eb1
--- /dev/null
+++ b/src/make.code.defn
@@ -0,0 +1,6 @@
+# Main make.code.defn file for thorn IOSDF
+# $Header$
+
+# Source files in this directory
+SRCS = Startup.c ChooseOutput.c Output1D.c Write1D.c Output2D.c Write2D.c \
+ Output3D.c Write3D.c