diff options
author | tradke <tradke@3af55ef0-e5e4-43b4-b020-ca5761ff09b2> | 2004-06-14 11:12:42 +0000 |
---|---|---|
committer | tradke <tradke@3af55ef0-e5e4-43b4-b020-ca5761ff09b2> | 2004-06-14 11:12:42 +0000 |
commit | ca0c7731de7c3d2bc45175af5b521c539bd66228 (patch) | |
tree | 3e7fb5f604817d8c717e13a8cd692e96c08fac1c /src | |
parent | d754a1ddfe40636e42e2c0367c687b99f917fcd4 (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.c | 149 | ||||
-rw-r--r-- | src/Output1D.c | 378 | ||||
-rw-r--r-- | src/Output2D.c | 382 | ||||
-rw-r--r-- | src/Output3D.c | 383 | ||||
-rw-r--r-- | src/Startup.c | 251 | ||||
-rw-r--r-- | src/Write1D.c | 436 | ||||
-rw-r--r-- | src/Write2D.c | 371 | ||||
-rw-r--r-- | src/Write3D.c | 292 | ||||
-rw-r--r-- | src/ioSDFGH.h | 87 | ||||
-rw-r--r-- | src/make.code.defn | 6 |
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 |