diff options
author | tradke <tradke@94b1c47f-dcfd-45ef-a468-0854c0e9e350> | 2002-04-15 13:07:16 +0000 |
---|---|---|
committer | tradke <tradke@94b1c47f-dcfd-45ef-a468-0854c0e9e350> | 2002-04-15 13:07:16 +0000 |
commit | 8c87ce629147b4040461ed28048fb15ca1f4a2c4 (patch) | |
tree | b51c883c8449c2e60f9ff66f5962ca1400e6fc36 /src | |
parent | 88a045f23bf33bbe1e309f046b81508260ea723a (diff) |
Switch to the new Hyperslab API. You need to update CactusPUGH/PUGHSlab if
you haven't done so yet.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/IOASCII/trunk@105 94b1c47f-dcfd-45ef-a468-0854c0e9e350
Diffstat (limited to 'src')
-rw-r--r-- | src/Output1D.c | 77 | ||||
-rw-r--r-- | src/Output2D.c | 79 | ||||
-rw-r--r-- | src/Output3D.c | 81 | ||||
-rw-r--r-- | src/Startup.c | 31 | ||||
-rw-r--r-- | src/Write1D.c | 476 | ||||
-rw-r--r-- | src/Write2D.c | 830 | ||||
-rw-r--r-- | src/Write3D.c | 670 | ||||
-rw-r--r-- | src/ioASCIIGH.h | 27 |
8 files changed, 1162 insertions, 1109 deletions
diff --git a/src/Output1D.c b/src/Output1D.c index 8c18aed..4610b02 100644 --- a/src/Output1D.c +++ b/src/Output1D.c @@ -67,12 +67,6 @@ int IOASCII_Output1DGH (const cGH *GH) CheckSteerableParameters (myGH); - /* Return if no output is required */ - if (myGH->out1D_every <= 0) - { - return (0); - } - /* Loop over all variables */ for (vindex = retval = 0; vindex < CCTK_NumVars (); vindex++) { @@ -204,15 +198,9 @@ int IOASCII_TimeFor1D (const cGH *GH, int vindex) CheckSteerableParameters (myGH); - /* return if no output requested */ - if (myGH->out1D_every <= 0) - { - return (0); - } - /* Check if this variable should be output */ - if (myGH->do_out1D[vindex] && - GH->cctk_iteration % myGH->out1D_every == 0) + if (myGH->out1D_every[vindex] > 0 && + GH->cctk_iteration % myGH->out1D_every[vindex] == 0) { /* Check if this variable wasn't already output this iteration */ if (myGH->out1D_last[vindex] == GH->cctk_iteration) @@ -293,28 +281,22 @@ int IOASCII_TriggerOutput1D (const cGH *GH, int vindex) /* check if steerable parameters have changed */ static void CheckSteerableParameters (asciiioGH *myGH) { - int i, num_vars, out_old, times_set; + int i, num_vars; char *fullname, *msg; - static int out1D_vars_lastset = -1; DECLARE_CCTK_PARAMETERS - out_old = myGH->out1D_every; - /* How often to output */ - myGH->out1D_every = out_every > 0 ? out_every : -1; - if (out1D_every > 0) - { - myGH->out1D_every = out1D_every; - } + i = myGH->out1D_every_default; + myGH->out1D_every_default = out1D_every > 0 ? out1D_every : out_every; /* Report if frequency changed */ - if (myGH->out1D_every != out_old && ! CCTK_Equals (newverbose, "none")) + if (myGH->out1D_every_default != i && ! CCTK_Equals (newverbose, "none")) { - if (myGH->out1D_every > 0) + if (myGH->out1D_every_default > 0) { CCTK_VInfo (CCTK_THORNSTRING, "IOASCII_1D: Periodic output every %d " - "iterations", myGH->out1D_every); + "iterations", myGH->out1D_every_default); } else { @@ -323,20 +305,18 @@ static void CheckSteerableParameters (asciiioGH *myGH) } /* re-parse the 'out1D_vars' parameter if it was changed */ - times_set = CCTK_ParameterQueryTimesSet ("out1D_vars", CCTK_THORNSTRING); - if (times_set != out1D_vars_lastset) + if (strcmp (out1D_vars, myGH->out1D_vars) || myGH->out1D_every_default != i) { num_vars = CCTK_NumVars (); - memset (myGH->do_out1D, 0, num_vars); - CCTK_TraverseString (out1D_vars, SetOutputFlag, myGH->do_out1D, - CCTK_GROUP_OR_VAR); + memset (myGH->out1D_every, 0, num_vars * sizeof (int)); + CCTK_TraverseString (out1D_vars, SetOutputFlag, myGH, CCTK_GROUP_OR_VAR); - if (! CCTK_Equals (newverbose, "none")) + if (myGH->out1D_every_default == i || ! CCTK_Equals (newverbose, "none")) { msg = NULL; for (i = 0; i < num_vars; i++) { - if (myGH->do_out1D[i]) + if (myGH->out1D_every[i] > 0) { fullname = CCTK_FullName (i); if (! msg) @@ -359,9 +339,9 @@ static void CheckSteerableParameters (asciiioGH *myGH) } /* Save the last setting of 'out1D_vars' parameter */ - out1D_vars_lastset = times_set; + free (myGH->out1D_vars); + myGH->out1D_vars = strdup (out1D_vars); } - } @@ -393,18 +373,27 @@ static int CheckOutputVar (int vindex) for the given variable */ static void SetOutputFlag (int vindex, const char *optstring, void *arg) { - char *flags = (char *) arg; + char *endptr; + asciiioGH *myGH = (asciiioGH *) arg; if (CheckOutputVar (vindex) == 0) { - flags[vindex] = 1; - } - - if (optstring) - { - CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, - "SetOutputFlag: Optional string '%s' in variable name ignored", - optstring); + myGH->out1D_every[vindex] = myGH->out1D_every_default; + if (optstring) + { + endptr = "error"; + if (strncmp ("out_every=", optstring, 10) == 0) + { + myGH->out1D_every[vindex] = strtol (optstring + 10, &endptr, 10); + } + if (endptr && *endptr) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "SetOutputFlag: Optional string '%s' could not be parsed", + optstring); + myGH->out1D_every[vindex] = 0; + } + } } } diff --git a/src/Output2D.c b/src/Output2D.c index 721a067..0ccb68d 100644 --- a/src/Output2D.c +++ b/src/Output2D.c @@ -67,20 +67,13 @@ int IOASCII_Output2DGH (const cGH *GH) CheckSteerableParameters (myGH); - /* Return if no output is required */ - if (myGH->out2D_every <= 0) - { - return (0); - } - /* Loop over all variables */ for (vindex = retval = 0; vindex < CCTK_NumVars (); vindex++) { - /* Check if this variable should be output */ if (! IOASCII_TimeFor2D (GH, vindex)) { - continue; + continue; } /* Get the variable name for this index (for filename) */ @@ -205,14 +198,9 @@ int IOASCII_TimeFor2D (const cGH *GH, int vindex) CheckSteerableParameters (myGH); - /* return if no output requested */ - if (myGH->out2D_every <= 0) - { - return (0); - } - /* Check if this variable should be output */ - if (myGH->do_out2D[vindex] && (GH->cctk_iteration % myGH->out2D_every == 0)) + if (myGH->out2D_every[vindex] > 0 && + GH->cctk_iteration % myGH->out2D_every[vindex] == 0) { /* Check if variable wasn't already output this iteration */ if (myGH->out2D_last[vindex] == GH->cctk_iteration) @@ -294,29 +282,22 @@ int IOASCII_TriggerOutput2D (const cGH *GH, int vindex) /* check if steerable parameters have changed */ static void CheckSteerableParameters (asciiioGH *myGH) { - int i, out_old, times_set, num_vars; + int i, num_vars; char *fullname, *msg; - static int out2D_vars_lastset = -1; DECLARE_CCTK_PARAMETERS - out_old = myGH->out2D_every; - /* How often to output */ - myGH->out2D_every = out_every > 0 ? out_every : -1; - if (out2D_every > 0) - { - myGH->out2D_every = out2D_every; - } + i = myGH->out2D_every_default; + myGH->out2D_every_default = out2D_every > 0 ? out2D_every : out_every; /* Report if frequency changed */ - - if (myGH->out2D_every != out_old && ! CCTK_Equals (newverbose, "none")) + if (myGH->out2D_every_default != i && ! CCTK_Equals (newverbose, "none")) { - if (myGH->out2D_every >0) + if (myGH->out2D_every_default > 0) { CCTK_VInfo (CCTK_THORNSTRING, "IOASCII_2D: Periodic output every %d " - "iterations", myGH->out2D_every); + "iterations", myGH->out2D_every_default); } else { @@ -325,20 +306,18 @@ static void CheckSteerableParameters (asciiioGH *myGH) } /* re-parse the 'out2D_vars' parameter if it was changed */ - times_set = CCTK_ParameterQueryTimesSet ("out2D_vars", CCTK_THORNSTRING); - if (times_set != out2D_vars_lastset) + if (strcmp (out2D_vars, myGH->out2D_vars) || myGH->out2D_every_default != i) { num_vars = CCTK_NumVars (); - memset (myGH->do_out2D, 0, num_vars); - CCTK_TraverseString (out2D_vars, SetOutputFlag, myGH->do_out2D, - CCTK_GROUP_OR_VAR); + memset (myGH->out2D_every, 0, num_vars * sizeof (int)); + CCTK_TraverseString (out2D_vars, SetOutputFlag, myGH, CCTK_GROUP_OR_VAR); - if (! CCTK_Equals (newverbose, "none")) + if (myGH->out2D_every_default == i || ! CCTK_Equals (newverbose, "none")) { msg = NULL; for (i = 0; i < num_vars; i++) { - if (myGH->do_out2D[i]) + if (myGH->out2D_every[i]) { fullname = CCTK_FullName (i); if (! msg) @@ -361,7 +340,8 @@ static void CheckSteerableParameters (asciiioGH *myGH) } /* Save the last setting of 'out2D_vars' parameter */ - out2D_vars_lastset = times_set; + free (myGH->out2D_vars); + myGH->out2D_vars = strdup (out2D_vars); } } @@ -405,18 +385,27 @@ static int CheckOutputVar (int vindex) for the given variable */ static void SetOutputFlag (int vindex, const char *optstring, void *arg) { - char *flags = (char *) arg; + char *endptr; + asciiioGH *myGH = (asciiioGH *) arg; - /* Check the variable type */ if (CheckOutputVar (vindex) == 0) { - flags[vindex] = 1; - } - - if (optstring) - { - CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, - "Optional string '%s' in variable name ignored", optstring); + myGH->out2D_every[vindex] = myGH->out2D_every_default; + if (optstring) + { + endptr = "error"; + if (strncmp ("out_every=", optstring, 10) == 0) + { + myGH->out2D_every[vindex] = strtol (optstring + 10, &endptr, 10); + } + if (endptr && *endptr) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "SetOutputFlag: Optional string '%s' could not be parsed", + optstring); + myGH->out2D_every[vindex] = 0; + } + } } } diff --git a/src/Output3D.c b/src/Output3D.c index 7bd3b55..78d8354 100644 --- a/src/Output3D.c +++ b/src/Output3D.c @@ -67,20 +67,13 @@ int IOASCII_Output3DGH (const cGH *GH) CheckSteerableParameters (myGH); - /* Return if no output is required */ - if (myGH->out3D_every <= 0) - { - return (0); - } - /* Loop over all variables */ for (vindex = retval = 0; vindex < CCTK_NumVars (); vindex++) { - /* Check if this variable should be output */ if (! IOASCII_TimeFor3D (GH, vindex)) { - continue; + continue; } /* Get the variable name for this index (for filename) */ @@ -205,14 +198,9 @@ int IOASCII_TimeFor3D (const cGH *GH, int vindex) CheckSteerableParameters (myGH); - /* return if no output requested */ - if (myGH->out3D_every <= 0) - { - return (0); - } - /* Check if this variable should be output */ - if (myGH->do_out3D[vindex] && (GH->cctk_iteration % myGH->out3D_every == 0)) + if (myGH->out3D_every[vindex] > 0 && + GH->cctk_iteration % myGH->out3D_every[vindex] == 0) { /* Check if variable wasn't already output this iteration */ if (myGH->out3D_last[vindex] == GH->cctk_iteration) @@ -294,29 +282,22 @@ int IOASCII_TriggerOutput3D (const cGH *GH, int vindex) /* check if steerable parameters have changed */ static void CheckSteerableParameters (asciiioGH *myGH) { - int i, out_old, times_set, num_vars; + int i, num_vars; char *fullname, *msg; - static int out3D_vars_lastset = -1; DECLARE_CCTK_PARAMETERS - out_old = myGH->out3D_every; - /* How often to output */ - myGH->out3D_every = out_every > 0 ? out_every : -1; - if (out3D_every > 0) - { - myGH->out3D_every = out3D_every; - } + i = myGH->out3D_every_default; + myGH->out3D_every_default = out3D_every > 0 ? out3D_every : out_every; /* Report if frequency changed */ - - if (myGH->out3D_every != out_old && ! CCTK_Equals (newverbose, "none")) + if (myGH->out3D_every_default != i && ! CCTK_Equals (newverbose, "none")) { - if (myGH->out3D_every > 0) + if (myGH->out3D_every_default > 0) { CCTK_VInfo (CCTK_THORNSTRING, "IOASCII_3D: Periodic output every %d " - "iterations", myGH->out3D_every); + "iterations", myGH->out3D_every_default); } else { @@ -325,21 +306,18 @@ static void CheckSteerableParameters (asciiioGH *myGH) } /* re-parse the 'out3D_vars' parameter if it was changed */ - times_set = CCTK_ParameterQueryTimesSet ("out3D_vars", CCTK_THORNSTRING); - if (times_set != out3D_vars_lastset) + if (strcmp (out3D_vars, myGH->out3D_vars) || myGH->out3D_every_default != i) { num_vars = CCTK_NumVars (); - memset (myGH->do_out3D, 0, num_vars); - CCTK_TraverseString (out3D_vars, SetOutputFlag, myGH->do_out3D, - CCTK_GROUP_OR_VAR); + memset (myGH->out3D_every, 0, num_vars * sizeof (int)); + CCTK_TraverseString (out3D_vars, SetOutputFlag, myGH, CCTK_GROUP_OR_VAR); - if (CCTK_Equals (newverbose, "standard") || - CCTK_Equals (newverbose, "full")) + if (myGH->out3D_every_default == i || ! CCTK_Equals (newverbose, "none")) { msg = NULL; for (i = 0; i < num_vars; i++) { - if (myGH->do_out3D[i]) + if (myGH->out3D_every[i] > 0) { fullname = CCTK_FullName (i); if (! msg) @@ -362,9 +340,9 @@ static void CheckSteerableParameters (asciiioGH *myGH) } /* Save the last setting of 'out3D_vars' parameter */ - out3D_vars_lastset = times_set; + free (myGH->out3D_vars); + myGH->out3D_vars = strdup (out3D_vars); } - } @@ -407,18 +385,27 @@ static int CheckOutputVar (int vindex) for the given variable */ static void SetOutputFlag (int vindex, const char *optstring, void *arg) { - char *flags = (char *) arg; + char *endptr; + asciiioGH *myGH = (asciiioGH *) arg; - /* Check the variable type */ if (CheckOutputVar (vindex) == 0) { - flags[vindex] = 1; - } - - if (optstring) - { - CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, - "Optional string '%s' in variable name ignored", optstring); + myGH->out3D_every[vindex] = myGH->out3D_every_default; + if (optstring) + { + endptr = "error"; + if (strncmp ("out_every=", optstring, 10) == 0) + { + myGH->out3D_every[vindex] = strtol (optstring + 10, &endptr, 10); + } + if (endptr && *endptr) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "SetOutputFlag: Optional string '%s' could not be parsed", + optstring); + myGH->out3D_every[vindex] = 0; + } + } } } diff --git a/src/Startup.c b/src/Startup.c index de7dfb4..8d3494c 100644 --- a/src/Startup.c +++ b/src/Startup.c @@ -44,16 +44,16 @@ static void *IOASCII_SetupGH (tFleshConfig *config, void IOASCII_Startup (void) { /* check that thorn IOUtil was activated */ - if (CCTK_GHExtensionHandle ("IO") < 0) + if (CCTK_GHExtensionHandle ("IO") >= 0) + { + CCTK_RegisterGHExtensionSetupGH (CCTK_RegisterGHExtension ("IOASCII"), + IOASCII_SetupGH); + } + else { CCTK_WARN (1, "IOASCII_Startup: Thorn IOUtil was not activated. " "No IOASCII IO methods will be enabled."); - return; } - - CCTK_RegisterGHExtensionSetupGH (CCTK_RegisterGHExtension ("IOASCII"), - IOASCII_SetupGH); - } @@ -128,8 +128,7 @@ static void *IOASCII_SetupGH (tFleshConfig *config, CCTK_RegisterIOMethodTimeToOutput (i, IOASCII_TimeFor3D); CCTK_RegisterIOMethodTriggerOutput (i, IOASCII_TriggerOutput3D); - if (CCTK_Equals (newverbose, "standard") || - CCTK_Equals( newverbose, "full")) + if (! CCTK_Equals (newverbose, "none")) { CCTK_INFO ("I/O Method 'IOASCII_1D' registered"); CCTK_INFO ("IOASCII_1D: Output of 1D lines of grid functions/arrays " @@ -145,12 +144,12 @@ static void *IOASCII_SetupGH (tFleshConfig *config, /* allocate the GH extension and its components */ newGH = (asciiioGH *) malloc (sizeof (asciiioGH)); - if(newGH) + if (newGH) { numvars = CCTK_NumVars (); - newGH->do_out1D = (char *) malloc (numvars * sizeof (char)); - newGH->do_out2D = (char *) malloc (numvars * sizeof (char)); - newGH->do_out3D = (char *) malloc (numvars * sizeof (char)); + newGH->out1D_every = (int *) malloc (numvars * sizeof (int)); + newGH->out2D_every = (int *) malloc (numvars * sizeof (int)); + newGH->out3D_every = (int *) malloc (numvars * sizeof (int)); newGH->out1D_last = (int *) malloc (numvars * sizeof (int)); newGH->out2D_last = (int *) malloc (numvars * sizeof (int)); newGH->out3D_last = (int *) malloc (numvars * sizeof (int)); @@ -162,6 +161,13 @@ static void *IOASCII_SetupGH (tFleshConfig *config, newGH->out3D_last[i] = -1; } + newGH->out1D_vars = strdup (""); + newGH->out2D_vars = strdup (""); + newGH->out3D_vars = strdup (""); + newGH->out1D_every_default = 0; + newGH->out2D_every_default = 0; + newGH->out3D_every_default = 0; + newGH->filenameList1D = NULL; newGH->fileList_2D = NULL; newGH->fileList_3D = NULL; @@ -236,7 +242,6 @@ static void *IOASCII_SetupGH (tFleshConfig *config, CCTK_VInfo (CCTK_THORNSTRING, "IOASCII_3D: Output to directory '%s'", newGH->outdir3D); } - } else { diff --git a/src/Write1D.c b/src/Write1D.c index f8ad0f3..b497d89 100644 --- a/src/Write1D.c +++ b/src/Write1D.c @@ -16,17 +16,15 @@ @version $Id$ @@*/ -#include <stdlib.h> #include <math.h> /* sqrt(3) */ +#include <stdlib.h> #include <string.h> -#include <sys/types.h> -#include <sys/stat.h> /* stat(2) */ #include "cctk.h" #include "cctk_Parameters.h" #include "Hyperslab.h" +#include "CactusBase/IOUtil/src/ioGH.h" #include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h" -#include "CactusBase/IOUtil/src/ioutil_CheckpointRecovery.h" #include "ioASCIIGH.h" /* the rcs ID and its dummy function to use it */ @@ -43,29 +41,28 @@ CCTK_FILEVERSION(CactusBase_IOASCII_Write1D_c) /* Macro to output a 1D line (with coordinates if available) as typed data For readability, the macro definition implicitely uses the following variables (which are defined in the calling routine): - hdata, hstride, hsize, complex_fmt_string */ -#define WRITE_DATA(hstart, cctk_type, c_type, is_complex, format, file) \ + hdata, hstride, hsize, format[2] */ +#define WRITE_DATA(hstart, cctk_type, c_type, is_complex, fmt, file) \ { \ int _h; \ - const cctk_type *_typed_data = (const cctk_type *) hdata[0]; \ - const CCTK_REAL *_coord_data = (const CCTK_REAL *) hdata[1]; \ + const cctk_type *_hdata = (const cctk_type *) hdata[0]; \ + const CCTK_REAL *_coord = (const CCTK_REAL *) hdata[1]; \ \ \ for (_h = hstart; _h < hstride * hsize; _h += hstride) \ { \ - if (_coord_data) \ + if (_coord) \ { \ - fprintf (file, format, \ - (double) _coord_data[_h], (c_type) _typed_data[_h]); \ + fprintf (file, fmt, (double) _coord[_h], (c_type) _hdata[_h]); \ } \ else \ { \ - fprintf (file, format, _h, (c_type) _typed_data[_h]); \ + fprintf (file, fmt, _h, (c_type) _hdata[_h]); \ } \ \ if (is_complex && hstride == 1) \ { \ - fprintf (file, complex_fmt_string, (c_type) _typed_data[_h+1]); \ + fprintf (file, format[2], (c_type) _hdata[_h+1]); \ } \ fputc ('\n', file); \ } \ @@ -79,16 +76,14 @@ static void OpenFile (const cGH *GH, const char *fullname, const char *alias, const cGroup *gdata, - const int *Do_it, + const int *do_dir, const CCTK_REAL *coord_lower, int num_files, FILE *file[]); static void WriteData (int vtype, const char *header, - const char *data_fmt_int, - const char *data_fmt_real, - int hsize, - int hstride, + char format[3][30], + int hsize, int hstride, void *const *const hdata, FILE *const file[]); @@ -104,9 +99,11 @@ static void WriteData (int vtype, It writes to ASCII files suitable for gnuplot and xgraph. A header telling the physical time prefixes the output data. @enddesc - @calls IOUtil_RestartFromRecovery - IOUtil_AdvertiseFile - Hyperslab_GetHyperslab + @calls Hyperslab_DefineGlobalMappingByIndex + Hyperslab_FreeMapping + Hyperslab_GetList + OpenFile + WriteData @var GH @vdesc Pointer to CCTK GH @@ -132,24 +129,25 @@ static void WriteData (int vtype, @@*/ int IOASCII_Write1D (const cGH *GH, int vindex, const char *alias) { - asciiioGH *myGH; /* IOASCII extension handle */ - int Do_it[4]; /* flags indicating actual work */ - int coord_index[3]; /* x,y,z coordinate variable indices */ - int myproc; /* identify processor */ - int i, dir; /* Loopers */ - int groupindex; /* variable's group index */ - int have_coords; /* boolean for existance of coordinates */ - char coord_system[20]; /* name of the coordinate system */ - cGroup group_static_data; /* variable's group static data */ - cGroupDynamicData group_dynamic_data;/* variable's group dynamic data */ - char *fullname; /* variable's full name */ - char header[30]; /* header string preceding a dataset */ - char time_fmt_string[30]; /* time format string */ - char data_fmt_string_int[30]; /* data format string for int types */ - char data_fmt_string_real[30]; /* data format string for float types */ - FILE *file[8]; /* fds for x,y,z,d output (also COMPLEX)*/ - CCTK_REAL coord_lower[3], offset; - int hstride, hsize, num_files; + asciiioGH *myGH; + int do_dir[4], coord_index[3]; + int i, dir, myproc, groupindex, have_coords; +#if 0 + int lower, upper; +#endif + int hstride, num_files, num_requested_hslabs, num_returned_hslabs; + int *extent_int; + cGroup gdata; + char *fullname; + char coord_system[20], header[30], buffer[30]; + char format[3][30]; + FILE *file[8]; + CCTK_REAL offset; + CCTK_REAL coord_lower[3]; + CCTK_INT *origin, *direction, *extent; + CCTK_INT mapping, hsize; + CCTK_INT vindices[2]; + void *hdata[2]; DECLARE_CCTK_PARAMETERS @@ -178,18 +176,15 @@ int IOASCII_Write1D (const cGH *GH, int vindex, const char *alias) myGH = (asciiioGH *) CCTK_GHExtension (GH, "IOASCII"); /* get the variable's group information */ - CCTK_GroupData (groupindex, &group_static_data); - CCTK_GroupDynamicData (GH, groupindex, &group_dynamic_data); + CCTK_GroupData (groupindex, &gdata); /* see what slices should be output */ - Do_it[0] = out1D_x && group_static_data.dim >= 1; - Do_it[1] = out1D_y && group_static_data.dim >= 2; - Do_it[2] = out1D_z && group_static_data.dim >= 3; + 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_it[3] = out1D_d && - group_static_data.dim == 3 && - group_static_data.stagtype == 0; - if (out1D_d && ! Do_it[3] && myGH->out1D_last[vindex] < 0) + 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, "IOASCII_Write1D: No IOASCII_1D diagonal output for '%s' " @@ -198,7 +193,7 @@ int IOASCII_Write1D (const cGH *GH, int vindex, const char *alias) } /* return if nothing to do */ - if (! (Do_it[0] || Do_it[1] || Do_it[2] || Do_it[3])) + if (! (do_dir[0] || do_dir[1] || do_dir[2] || do_dir[3])) { free (fullname); return (0); @@ -206,12 +201,12 @@ int IOASCII_Write1D (const cGH *GH, int vindex, const char *alias) /* get the coordinate indices for CCTK_GF variables (CCTK_ARRAY variables never have coordinates associated) */ - have_coords = group_static_data.grouptype == CCTK_GF; + have_coords = gdata.grouptype == CCTK_GF; if (have_coords) { /* FIXME: this assumes a cartesian coordinate system */ - sprintf (coord_system, "cart%dd", group_static_data.dim); - for (i = 0; i < group_static_data.dim && i < 3; i++) + sprintf (coord_system, "cart%dd", gdata.dim); + for (i = 0; i < gdata.dim && i < 3; i++) { CCTK_CoordRange (GH, &coord_lower[i], &offset, i + 1, NULL, coord_system); coord_index[i] = CCTK_CoordIndex (i + 1, NULL, coord_system); @@ -247,187 +242,201 @@ int IOASCII_Write1D (const cGH *GH, int vindex, const char *alias) /* set header format string */ if (CCTK_Equals (out1D_style, "xgraph")) { - sprintf (time_fmt_string, "\n\n\"Time = %%%s\n", out_format); + sprintf (buffer, "\n\n\"Time = %%%s\n", out_format); } else { - sprintf (time_fmt_string, "\n#Time = %%%s\n", out_format); + sprintf (buffer, "\n#Time = %%%s\n", out_format); } - sprintf (header, time_fmt_string, GH->cctk_time); + sprintf (header, buffer, (double) GH->cctk_time); /* check whether to include physical time as separate column in the output */ i = 0; if (CCTK_Equals (out1D_style, "gnuplot f(t,x)")) { - sprintf (time_fmt_string, "%%%s\t\t", out_format); - sprintf (data_fmt_string_int, time_fmt_string, (double) GH->cctk_time); - sprintf (data_fmt_string_real, time_fmt_string, (double) GH->cctk_time); - i = strlen (data_fmt_string_int); + sprintf (buffer, "%%%s\t\t", out_format); + sprintf (format[0], buffer, (double) GH->cctk_time); + sprintf (format[1], buffer, (double) GH->cctk_time); + i = strlen (format[0]); } if (have_coords) { - sprintf (data_fmt_string_int + i, "%%%s\t\t%%d", out_format); - sprintf (data_fmt_string_real + i, "%%%s\t\t%%%s", out_format, out_format); + sprintf (format[0] + i, "%%%s\t\t%%d", out_format); + sprintf (format[1] + i, "%%%s\t\t%%%s", out_format, out_format); } else { - sprintf (data_fmt_string_int + i, "%%d\t\t%%d"); - sprintf (data_fmt_string_real + i, "%%d\t\t%%%s", out_format); + sprintf (format[0] + i, "%%d\t\t%%d"); + sprintf (format[1] + i, "%%d\t\t%%%s", out_format); } + sprintf (format[2], "\t\t%%%s", out_format); /* get the stride into the data and the (maximum) number of files to write */ - hstride = group_static_data.vartype == CCTK_VARIABLE_COMPLEX && + hstride = gdata.vartype == CCTK_VARIABLE_COMPLEX && CCTK_Equals (out1D_style, "xgraph") ? 2 : 1; num_files = hstride * 4; - /* Processor 0 opens the files with the appropriate name */ + /* processor 0 opens the files with the appropriate name */ myproc = CCTK_MyProc (GH); if (myproc == 0) { - OpenFile (GH, fullname, alias, &group_static_data, Do_it, + OpenFile (GH, fullname, alias, &gdata, do_dir, have_coords ? coord_lower : NULL, num_files, file); } - /* OK so actually do the I/O in each direction */ - for (dir = 0; dir < 4; dir++) - { - int length = -1; - int gsh[3]; - const int downsample = 1; - const int *origin; - const int zero_point[3] = {0, 0, 0}; - int directions[3]; - void *hdata[2]; + origin = (CCTK_INT *) calloc (3*gdata.dim, sizeof (CCTK_INT)); + direction = origin + 1*gdata.dim; + extent = origin + 2*gdata.dim; + extent_int = (int *) malloc (gdata.dim * sizeof (int)); + CCTK_GroupgshVI (GH, gdata.dim, extent_int, vindex); + /* now do the actual I/O looping over all directions */ + for (dir = 0; dir < 4; dir++) + { /* skip empty slices */ - if (! Do_it[dir]) + if (! do_dir[dir]) { continue; } - /* need to pass the extent for diagonals */ - if (dir < 3) + /* 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++) { - length = -1; + direction[i] = (dir == i || dir == 3) ? 1 : 0; } - else + + /* set the extent vector */ + for (i = 0; i < gdata.dim; i++) { - CCTK_GroupgshVI (GH, 3, gsh, vindex); - length = group_dynamic_data.gsh[0]; - if (length > group_dynamic_data.gsh[1]) - { - length = group_dynamic_data.gsh[1]; - } - if (length > group_dynamic_data.gsh[2]) - { - length = group_dynamic_data.gsh[2]; - } + extent[i] = extent_int[i]; } - if (group_static_data.grouptype == CCTK_GF) + /* set the origin of the line */ + if (gdata.grouptype == CCTK_GF && dir < 3) { - /* for GFs: get the coordinate's 1D data (in xyz direction only) */ - if (dir < 3) + for (i = 0; i < gdata.dim; i++) { - /* set the origin of the line */ - origin = myGH->spxyz[group_static_data.dim-1][dir]; - - /* set the direction vector for the 1D line */ - memset (directions, 0, sizeof (directions)); - directions[dir] = 1; - - if (have_coords) - { - if (Hyperslab_GetHyperslab (GH, 0, coord_index[dir], 0, 1, - origin, directions, &length, &downsample, - &hdata[1], &hsize) < 0) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "IOASCII_Write1D: Failed to extract hyperslab for" - "%c-coordinate", 'x' + dir); - } - } - else - { - hdata[1] = NULL; - } + origin[i] = myGH->spxyz[gdata.dim-1][dir][i]; + extent[i] -= origin[i]; + } +#if 0 + if (CCTK_CoordRangePhysIndex (GH, &lower, &upper, dir + 1, NULL, + coord_system) >= 0) + { +fprintf (stderr, "CCTK_CoordRangePhysIndex() resets origin/extent in dir %d from %d/%d to ", dir, origin[dir], extent[dir]); + origin[dir] = lower; extent[dir] = upper - lower + 1; +fprintf (stderr, "%d/%d\n", origin[dir], extent[dir]); } else { - /* set the origin of the line */ - origin = zero_point; - - /* set the direction vector for the diagonal 1D line */ - for (i = 0; i < 3; i++) - { - directions[i] = 1; - } - - /* coordinates are calculated by output processor */ - hdata[1] = NULL; + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOASCII_Write1D: failed to get physical coordinate ranges " + "for variable '%s'", fullname); } +#endif } - else + else /* origin for CCTK_ARRAYS and diagonals is always (0, 0, 0) */ { - /* set the origin of the line */ - /* FIXME: Should we define some slice center for arrays too ? */ - origin = zero_point; + memset (origin, 0, gdata.dim * sizeof (CCTK_INT)); - /* set the direction vector for the 1D line */ - for (i = 0; i < 3; i++) + /* for diagonals: get the extent as the minimum of points + in all direction */ + if (dir == 3) { - directions[i] = (dir == i || dir == 3) ? 1 : 0; + if (extent[0] > extent[1]) + { + extent[0] = extent[1]; + } + if (extent[0] > extent[2]) + { + extent[0] = extent[2]; + } } - - /* no coordinates are needed for arrays */ - hdata[1] = NULL; } - /* get the variable's 1D data */ - if (Hyperslab_GetHyperslab (GH, 0, vindex, 0, 1, origin, - directions, &length, &downsample, - &hdata[0], &hsize) < 0) + mapping = Hyperslab_DefineGlobalMappingByIndex (GH, vindex, 1, + direction, + origin, + extent, + NULL, /* downsample */ + -1, /* table handle */ + NULL /* conversion fn */, + &hsize); + if (mapping < 0) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "IOASCII_Write1D: Failed to extract hyperslab for " + "IOASCII_Write1D: Failed to define hyperslab mapping for " "variable '%s'", fullname); - if (hdata[1]) - { - free (hdata[1]); - } continue; } + if (hsize <= 0) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOASCII_Write1D: selected hyperslab has zero size for " + "variable '%s' direction %d", fullname, dir); + Hyperslab_FreeMapping (mapping); + continue; + } + + if (myproc == 0) + { + /* allocate hyperslab buffers */ + hdata[0] = malloc (hsize * CCTK_VarTypeSize (gdata.vartype)); + hdata[1] = have_coords ? malloc (hsize * sizeof (CCTK_REAL)) : 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, hdata, + NULL); + + /* release the mapping structure */ + Hyperslab_FreeMapping (mapping); - /* And write it out on processor 0 */ + /* And dump the data to file */ if (myproc == 0 && file[dir] != NULL) { - if (have_coords) + if (num_returned_hslabs != num_requested_hslabs) { - if (dir < 3) + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOASCII_Write1D: Failed to extract hyperslab for " + "variable '%s'", fullname); + } + else + { + if (have_coords) { - /* get the staggering offset for the xyz coordinates */ - offset = 0.5 * GH->cctk_delta_space[dir] * - CCTK_StaggerDirIndex (dir, group_static_data.stagtype); - for (i = 0; i < hsize; i++) + if (dir < 3) { - ((CCTK_REAL *) hdata[1])[i] += offset; + /* 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++) + { + ((CCTK_REAL *) hdata[1])[i] += offset; + } } - } - else - { - /* calculate the diagonal coordinates */ - offset = GH->cctk_delta_space[0] * sqrt (3); - hdata[1] = malloc (hsize * sizeof (CCTK_REAL)); - for (i = 0; i < hsize; i++) + else { - ((CCTK_REAL *) hdata[1])[i] = coord_lower[0]*sqrt (3) + i*offset; + /* calculate the diagonal coordinates */ + offset = GH->cctk_delta_space[0] * sqrt (3); + for (i = 0; i < hsize; i++) + { + ((CCTK_REAL *) hdata[1])[i] = coord_lower[0]*sqrt (3) + i*offset; + } } } - } - WriteData (group_static_data.vartype, header, data_fmt_string_int, - data_fmt_string_real, hsize, hstride, hdata, file + dir); + WriteData (gdata.vartype, header, format, hsize, hstride, hdata, + file + dir); + } /* close the output file(s) */ fclose (file[dir]); @@ -435,51 +444,66 @@ int IOASCII_Write1D (const cGH *GH, int vindex, const char *alias) { fclose (file[dir + 4]); } + } - /* clean up */ + /* clean up */ + if (myproc == 0) + { free (hdata[0]); if (hdata[1]) { 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 Wed 12 Dec 2001 + @author Thomas Radke + @desc + Opens a set of ASCII files for a given alias name. + If this is the first time through, it will create the files, + write some header information, and advertise them to IOUtil. + @enddesc + @@*/ static void OpenFile (const cGH *GH, const char *fullname, const char *alias, const cGroup *gdata, - const int *Do_it, + const int *do_dir, const CCTK_REAL *coord_lower, int num_files, FILE *file[]) { - int i, dir; + int i, dir, upper, lower, first_time_through; asciiioGH *myGH; - struct stat fileinfo; - const char *openmode; - static char *extensions[] = {"xl", "yl", "zl", "dl"}; - char *filename, *type_extension, buffer[128]; + const ioGH *ioUtilGH; + char comment_char; + char *filename, *type_extension; + const char *file_extension; + char slicename[20], buffer[128]; + char ylabel1_fmt_string[13], ylabel2_fmt_string[13]; ioAdvertisedFileDesc advertised_file; - char slicename[20]; /* name of current output slice */ - int upper, lower; - char comment_char; /* character starting a comment */ - const char *file_extension; /* filename extension */ - char ylabel1_fmt_string[13]; /* y-label format string */ - char ylabel2_fmt_string[13]; /* y-label format string */ + const char *extensions[] = {"xl", "yl", "zl", "dl"}; DECLARE_CCTK_PARAMETERS - /* get the handle for IOASCII extensions */ + /* get handles for IOUtil and IOASCII extensions */ myGH = (asciiioGH *) CCTK_GHExtension (GH, "IOASCII"); + ioUtilGH = (const ioGH *) CCTK_GHExtension (GH, "IO"); /* set comment character and file extension */ if (CCTK_Equals (out1D_style, "xgraph")) @@ -506,7 +530,7 @@ static void OpenFile (const cGH *GH, dir = i % 4; /* skip empty slices */ - if (! Do_it[dir]) + if (! do_dir[dir]) { continue; } @@ -590,34 +614,17 @@ static void OpenFile (const cGH *GH, } } - /* see if output file was already created */ - if (GetNamedData (myGH->filenameList1D, filename) == NULL) - { - /* if restart from recovery, existing files are opened in append mode */ - if (IOUtil_RestartFromRecovery (GH)) - { - openmode = stat (filename, &fileinfo) == 0 ? "a" : "w"; - } - else - { - openmode = "w"; - } - - /* just store a non-NULL pointer in database */ - StoreNamedData (&myGH->filenameList1D, filename, (void *) 1); - } - else - { - openmode = "a"; - } - - if (! (file[i] = fopen (filename, openmode))) + /* create the output file the first time through + If restart from recovery, existing files are opened in append mode. */ + first_time_through = GetNamedData (myGH->filenameList1D, filename) == NULL; + file[i] = fopen (filename, + ioUtilGH->recovered || ! first_time_through ? "a" : "w"); + if (! file[i]) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "IOASCII_Write1D: Cannot open 1D output file '%s'", - filename); + "IOASCII_Write1D: Cannot open 1D output file '%s'", filename); } - else if (*openmode == 'w') + else if (first_time_through) { /* advertise new files for downloading and add file info */ /* FIXME: this can go after the old filename scheme has gone */ @@ -689,86 +696,89 @@ static void OpenFile (const cGH *GH, } } } + + StoreNamedData (&myGH->filenameList1D, filename, file[i]); } } + free (filename); } +/*@@ + @routine WriteData + @date Wed 12 Dec 2001 + @author Thomas Radke + @desc + Writes the given hyperslabs into the appropriate output files. + @enddesc + @@*/ static void WriteData (int vtype, const char *header, - const char *data_fmt_string_int, - const char *data_fmt_string_real, - int hsize, - int hstride, + char format[3][30], + int hsize, int hstride, void *const *const hdata, FILE *const file[]) { - char complex_fmt_string[30]; - DECLARE_CCTK_PARAMETERS - - - sprintf (complex_fmt_string, "\t\t%%%s", out_format); - /* print out header */ fputs (header, file[0]); if (vtype == CCTK_VARIABLE_CHAR) { - WRITE_DATA (0, CCTK_BYTE, int, 0, data_fmt_string_int, file[0]); + WRITE_DATA (0, CCTK_BYTE, int, 0, format[0], file[0]); } else if (vtype == CCTK_VARIABLE_INT) { - WRITE_DATA (0, CCTK_INT, int, 0, data_fmt_string_int, file[0]); + WRITE_DATA (0, CCTK_INT, int, 0, format[0], file[0]); } else if (vtype == CCTK_VARIABLE_REAL) { - WRITE_DATA (0, CCTK_REAL, double, 0, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL, double, 0, format[1], file[0]); } else if (vtype == CCTK_VARIABLE_COMPLEX) { - WRITE_DATA (0, CCTK_REAL, double, 1, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL, double, 1, format[1], file[0]); if (hstride == 2) { /* print out header */ fputs (header, file[0 + 4]); - WRITE_DATA (1, CCTK_REAL, double, 1, data_fmt_string_real, file[4]); + WRITE_DATA (1, CCTK_REAL, double, 1, format[1], file[4]); } } #ifdef CCTK_INT2 else if (vtype == CCTK_VARIABLE_INT2) { - WRITE_DATA (0, CCTK_INT2, int, 0, data_fmt_string_int, file[0]); + WRITE_DATA (0, CCTK_INT2, int, 0, format[0], file[0]); } #endif #ifdef CCTK_INT4 else if (vtype == CCTK_VARIABLE_INT4) { - WRITE_DATA (0, CCTK_INT4, int, 0, data_fmt_string_int, file[0]); + WRITE_DATA (0, CCTK_INT4, int, 0, format[0], file[0]); } #endif #ifdef CCTK_INT8 else if (vtype == CCTK_VARIABLE_INT8) { - WRITE_DATA (0, CCTK_INT8, int, 0, data_fmt_string_int, file[0]); + WRITE_DATA (0, CCTK_INT8, int, 0, format[0], file[0]); } #endif #ifdef CCTK_REAL4 else if (vtype == CCTK_VARIABLE_REAL4) { - WRITE_DATA (0, CCTK_REAL4, double, 0, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL4, double, 0, format[1], file[0]); } else if (vtype == CCTK_VARIABLE_COMPLEX8) { - WRITE_DATA (0, CCTK_REAL4, double, 1, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL4, double, 1, format[1], file[0]); if (hstride == 2) { /* print out header */ fputs (header, file[0 + 4]); - WRITE_DATA (1, CCTK_REAL4, double, 1, data_fmt_string_real, file[0 + 4]); + WRITE_DATA (1, CCTK_REAL4, double, 1, format[1], file[0 + 4]); } } #endif @@ -776,16 +786,16 @@ static void WriteData (int vtype, #ifdef CCTK_REAL8 else if (vtype == CCTK_VARIABLE_REAL8) { - WRITE_DATA (0, CCTK_REAL8, double, 0, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL8, double, 0, format[1], file[0]); } else if (vtype == CCTK_VARIABLE_COMPLEX16) { - WRITE_DATA (0, CCTK_REAL8, double, 1, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL8, double, 1, format[1], file[0]); if (hstride == 2) { /* print out header */ fputs (header, file[0 + 4]); - WRITE_DATA (1, CCTK_REAL8, double, 1, data_fmt_string_real, file[0 + 4]); + WRITE_DATA (1, CCTK_REAL8, double, 1, format[1], file[0 + 4]); } } #endif @@ -793,16 +803,16 @@ static void WriteData (int vtype, #ifdef CCTK_REAL16 else if (vtype == CCTK_VARIABLE_REAL16) { - WRITE_DATA (0, CCTK_REAL16, double, 0, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL16, double, 0, format[1], file[0]); } else if (vtype == CCTK_VARIABLE_COMPLEX32) { - WRITE_DATA (0, CCTK_REAL16, double, 1, data_fmt_string_real, file[0]); + WRITE_DATA (0, CCTK_REAL16, double, 1, format[1], file[0]); if (hstride == 2) { /* print out header */ fputs (header, file[0 + 4]); - WRITE_DATA (1, CCTK_REAL16, double, 1, data_fmt_string_real, file[0 + 4]); + WRITE_DATA (1, CCTK_REAL16, double, 1, format[1], file[0 + 4]); } } #endif diff --git a/src/Write2D.c b/src/Write2D.c index 65fdebb..6442060 100644 --- a/src/Write2D.c +++ b/src/Write2D.c @@ -15,71 +15,76 @@ #include "cctk.h" #include "cctk_Parameters.h" #include "Hyperslab.h" +#include "CactusBase/IOUtil/src/ioGH.h" #include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h" -#include "CactusBase/IOUtil/src/ioutil_CheckpointRecovery.h" #include "ioASCIIGH.h" /* the rcs ID and its dummy function to use it */ static const char *rcsid = "$Id$"; CCTK_FILEVERSION(CactusBase_IOASCII_Write2D_c) -/* enable debug output */ -/*#define IOASCII_DEBUG 1*/ +/******************************************************************** + ******************** Macro Definitions ************************ + ********************************************************************/ +/* uncomment this to enable debugging output */ +/* #define DEBUG_IOASCII 1 */ /* macro to output a time slice as typed data */ -#define OUTPUT_TYPED_DATA(coord_i, coord_j, stagger_offset_i,stagger_offset_j,\ - cctk_type, c_type, data, hsize, is_cmplx_type, \ - have_coords, fmt_string, file) \ - { \ - int i, j; \ - const cctk_type *typed_data = (const cctk_type *) (data); \ +/* Macro to output a 2D slice (with coordinates if available) as typed data + For readability, the macro definition implicitely uses the following + variables (which are defined in the calling routine): + hdata, hsize, is_complex, format[2], file */ +#define WRITE_DATA(cctk_type, c_type, fmt) \ + { \ + int _i, _j; \ + const cctk_type *_hdata = (const cctk_type *) hdata[0]; \ + const CCTK_REAL *_coord[2]; \ + \ \ \ - /* output coordinates if available otherwise just the indices */ \ - if (have_coords) \ + _coord[0] = (const CCTK_REAL *) hdata[1]; \ + _coord[1] = (const CCTK_REAL *) hdata[2]; \ + for (_j = 0; _j < hsize[1]; _j++) \ + { \ + for (_i = 0; _i < hsize[0]; _i++) \ { \ - for (j = 0; j < hsize[1]; j++) \ + if (_coord[0]) \ { \ - for (i = 0; i < hsize[0]; i++) \ - { \ - fprintf (file, fmt_string, \ - (double) (*coord_i++ + stagger_offset_i), \ - (double) (*coord_j++ + stagger_offset_j), \ - (c_type) *typed_data++); \ - if (is_cmplx_type) \ - { \ - fprintf (file, "\t\t"); \ - fprintf (file, out_real_format, (double) *typed_data++); \ - } \ - fprintf (file, "\n"); \ - } \ - fprintf (file, "\n"); \ + fprintf (file, fmt, (double) *_coord[0]++, \ + (double) *_coord[1]++, (c_type) *_hdata++); \ } \ - coord_i -= hsize[0] * hsize[1]; \ - coord_j -= hsize[0] * hsize[1]; \ - } \ - else \ - { \ - for (j = 0; j < hsize[1]; j++) \ + else \ + { \ + fprintf (file, fmt, _i, _j, (c_type) *_hdata++); \ + } \ + \ + if (is_complex) \ { \ - for (i = 0; i < hsize[0]; i++) \ - { \ - fprintf (file, fmt_string, \ - (double) i, \ - (double) j, \ - (c_type) *typed_data++); \ - if (is_cmplx_type) \ - { \ - fprintf (file, "\t\t"); \ - fprintf (file, out_real_format, (double) *typed_data++); \ - } \ - fprintf (file, "\n"); \ - } \ - fprintf (file, "\n"); \ + fprintf (file, format[2], (c_type) *_hdata++); \ } \ + fputc ('\n', file); \ } \ - } + fputc ('\n', file); \ + } \ + } + + +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +static FILE **OpenFile (const cGH *GH, + const char *fullname, + const char *alias, + int dim, + const CCTK_REAL *coord_lower, + int maxdir); +static void WriteData (int vtype, + const char *header, + char format[3][30], + const CCTK_INT hsize[2], + void *const *const hdata, + FILE *file); /*@@ @@ -89,9 +94,11 @@ CCTK_FILEVERSION(CactusBase_IOASCII_Write2D_c) @desc Writes the 2D slices of a variable into separate ASCII files. @enddesc - @calls IOUtil_RestartFromRecovery - IOUtil_AdvertiseFile - Hyperslab_GetHyperslab + @calls Hyperslab_DefineGlobalMappingByIndex + Hyperslab_FreeMapping + Hyperslab_GetList + OpenFile + WriteData @var GH @vdesc Pointer to CCTK GH @@ -120,44 +127,34 @@ CCTK_FILEVERSION(CactusBase_IOASCII_Write2D_c) @@*/ int IOASCII_Write2D (const cGH *GH, int vindex, const char *alias) { - DECLARE_CCTK_PARAMETERS - int myproc; asciiioGH *myGH; - char header_fmt_string[30]; /* header format string */ - char zlabel_fmt_string[30]; /* z-label format string */ - char out_real_format[30]; /* data format string for a real type */ - char time_fmt_string[30]; /* time format string */ - char data_fmt_string_int[30]; /* data format string for int types */ - char data_fmt_string_real[30]; /* data format string for real types */ - int dir, maxdir; - int groupindex; - int have_coords; - cGroup groupinfo; - FILE **fdset_2D; /* array of output file pointers */ - int coord_index[3]; /* variable indices for xyz coordinates */ - CCTK_REAL coord_lower[3]; /* coordinates' minima */ - char coord_system[20]; /* name of the coordinate system */ - int origin[3]; /* the slice origin */ - CCTK_REAL dummy; - char *filename; + int i, total_hsize, num_requested_hslabs, num_returned_hslabs; + int dir, dir_i, dir_j, maxdir, myproc, groupindex, have_coords; + cGroup gdata; + int coord_index[3]; + CCTK_REAL coord_lower[3]; + char coord_system[20]; + char format[3][30]; + char header[30], buffer[30]; char *fullname; - char slicename[20]; - ioAdvertisedFileDesc advertised_file; - char buffer[128]; - static char *extensions[] = {"xy", "xz", "yz"}; - + int extent_int[3]; + CCTK_INT mapping; + CCTK_REAL offset[2]; + CCTK_INT vindices[3]; + CCTK_INT origin[3], extent[3], direction[6], hsize[2]; + void *hdata[3]; + FILE **fileset; + DECLARE_CCTK_PARAMETERS - /* to make the compiler happy */ - fdset_2D = NULL; - /* get the variable group information */ + /* get the variable name and group information */ + fullname = CCTK_FullName (vindex); groupindex = CCTK_GroupIndexFromVarI (vindex); - CCTK_GroupData (groupindex, &groupinfo); + CCTK_GroupData (groupindex, &gdata); /* check if variable has storage assigned */ if (! CCTK_QueryGroupStorageI (GH, groupindex)) { - fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "No IOASCII 2D output for '%s' (no storage)", fullname); free (fullname); @@ -168,34 +165,18 @@ int IOASCII_Write2D (const cGH *GH, int vindex, const char *alias) myGH = (asciiioGH *) CCTK_GHExtension (GH, "IOASCII"); /* get the number of slices to output */ - /* in general: maxdir = groupinfo.dim * (groupinfo.dim - 1) / 2; */ - maxdir = groupinfo.dim == 2 ? 1 : 3; - - /* set header and data format strings */ - sprintf (header_fmt_string, "\n\n#Time = %%%s\n", out_format); - sprintf (zlabel_fmt_string, " (%%c = %%%s),", out_format); - sprintf (out_real_format, "%%%s", out_format); - dir = 0; - if (CCTK_Equals (out2D_style, "gnuplot f(t,x,y)")) - { - sprintf (time_fmt_string, "%%%s\t\t", out_format); - sprintf (data_fmt_string_int, time_fmt_string, (double) GH->cctk_time); - sprintf (data_fmt_string_real, time_fmt_string, (double) GH->cctk_time); - dir = strlen (data_fmt_string_int); - } - sprintf (data_fmt_string_int + dir, "%%%s\t\t%%%s\t\t%%d", - out_format, out_format); - sprintf (data_fmt_string_real + dir, "%%%s\t\t%%%s\t\t%%%s", - out_format, out_format, out_format); + /* in general: maxdir = gdata.dim * (gdata.dim - 1) / 2; */ + maxdir = gdata.dim == 2 ? 1 : 3; - /* get the coordinate indices if we output a grid function */ - if (groupinfo.grouptype == CCTK_GF) + /* get the coordinate indices for CCTK_GF variables + (CCTK_ARRAY variables never have coordinates associated) */ + have_coords = gdata.grouptype == CCTK_GF; + if (have_coords) { - sprintf (coord_system, "cart%dd", groupinfo.dim); - have_coords = 1; - for (dir = 0; dir < groupinfo.dim && dir < 3; dir++) + sprintf (coord_system, "cart%dd", gdata.dim); + for (dir = 0; dir < gdata.dim && dir < 3; dir++) { - CCTK_CoordRange (GH, &coord_lower[dir], &dummy, dir+1, NULL,coord_system); + CCTK_CoordRange (GH, &coord_lower[dir], offset, dir+1, NULL,coord_system); coord_index[dir] = CCTK_CoordIndex (dir + 1, NULL, coord_system); have_coords &= coord_index[dir] >= 0; } @@ -207,173 +188,49 @@ int IOASCII_Write2D (const cGH *GH, int vindex, const char *alias) coord_system); } } + num_requested_hslabs = have_coords ? 3 : 1; + + /* set header and data format strings */ + sprintf (buffer, "\n\n#Time = %%%s\n", out_format); + sprintf (header, buffer, GH->cctk_time); + dir = 0; + if (CCTK_Equals (out2D_style, "gnuplot f(t,x,y)")) + { + sprintf (buffer, "%%%s\t\t", out_format); + sprintf (format[0], buffer, (double) GH->cctk_time); + sprintf (format[1], buffer, (double) GH->cctk_time); + dir = strlen (format[0]); + } + if (have_coords) + { + sprintf (format[0] + dir, "%%%s\t\t%%%s\t\t%%d", + out_format, out_format); + sprintf (format[1] + dir, "%%%s\t\t%%%s\t\t%%%s", + out_format, out_format, out_format); + } else { - /* CCTK_ARRAY variables never have coordinates associated */ - have_coords = 0; + sprintf (format[0] + dir, "%%d\t\t%%d\t\t%%d"); + sprintf (format[1] + dir, "%%d\t\t%%d\t\t%%%s", out_format); } - /* What processor are we on? */ + /* processor 0 opens the files on the first trip through */ myproc = CCTK_MyProc (GH); - - /* Open the files on the first trip through if we are proc. 0 */ if (myproc == 0) { - - /* see if output file for this alias name was already created */ - fdset_2D = (FILE **) GetNamedData (myGH->fileList_2D, alias); - if (fdset_2D == NULL) - { - fdset_2D = (FILE **) malloc (3 * sizeof (FILE *)); - filename = (char *) malloc (strlen (myGH->outdir2D) + strlen (alias) + - sizeof (slicename) + 20); - - /* get the variable's full name */ - fullname = CCTK_FullName (vindex); - - /* Open/Create files */ - for (dir = 0; dir < maxdir; dir++) - { - /* FIXME: this can go when we permanently switch the the - new filename scheme */ - if (new_filename_scheme) - { - if (groupinfo.dim == 2) - { - strcpy (slicename, "2D"); - } - else - { - /* give the slice origin as range [1 .. n] */ - sprintf (slicename, "%s_[%d]", extensions[dir], - myGH->sp2xyz[groupinfo.dim - 1][dir]); - } - - /* skip pathname if output goes into current directory */ - if (strcmp (myGH->outdir2D, ".")) - { - sprintf (filename, "%s/%s_%s.asc", myGH->outdir2D, alias,slicename); - } - else - { - sprintf (filename, "%s_%s.asc", alias, slicename); - } - } - else - { - /* skip pathname if output goes into current directory */ - if (strcmp (myGH->outdir2D, ".")) - { - if (groupinfo.dim == 2) - { - sprintf (filename, "%s/%s_2D.gnuplot", myGH->outdir2D, alias); - } - else - { - sprintf (filename, "%s/%s_2d_%s.gnuplot", myGH->outdir2D, alias, - extensions[dir]); - } - } - else - { - if (groupinfo.dim == 2) - { - sprintf (filename, "%s_2D.gnuplot", alias); - } - else - { - sprintf (filename, "%s_2d_%s.gnuplot", alias, extensions[dir]); - } - } - } - - /* if restart from recovery, try to open an existing file ... */ - fdset_2D[dir] = NULL; - if (IOUtil_RestartFromRecovery (GH)) - { - fdset_2D[dir] = fopen (filename, "a"); - } - - /* otherwise or if that failed, create a new one */ - if (! fdset_2D[dir]) - { - fdset_2D[dir] = fopen (filename, "w"); - } - if (! fdset_2D[dir]) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Cannot open 2D output file '%s'", filename); - return (-2); - } - - /* advertise the file for downloading and write file info */ - /* FIXME: this can go when we permanently switch the the - new filename scheme */ - advertised_file.slice = new_filename_scheme ? - slicename : extensions[dir]; - advertised_file.thorn = CCTK_THORNSTRING; - advertised_file.varname = fullname; - advertised_file.description = "Two-dimensional slice plots"; - advertised_file.mimetype = "application/gnuplot"; - - IOUtil_AdvertiseFile (GH, filename, &advertised_file); - - if (CCTK_Equals (out_fileinfo, "parameter filename") || - CCTK_Equals (out_fileinfo, "all")) - { - buffer[0] = 0; - CCTK_ParameterFilename (sizeof (buffer), buffer); - fprintf (fdset_2D[dir], "#Parameter file %s\n", buffer); - } - if (CCTK_Equals (out_fileinfo, "creation date") || - CCTK_Equals (out_fileinfo, "all")) - { - buffer[0] = 0; - Util_CurrentDate (sizeof (buffer), buffer); - fprintf (fdset_2D[dir], "#Created %s ", buffer); - Util_CurrentTime (sizeof (buffer), buffer); - fprintf (fdset_2D[dir], "%s\n", buffer); - } - if (CCTK_Equals (out_fileinfo, "axis labels") || - CCTK_Equals (out_fileinfo, "all")) - { - fprintf (fdset_2D[dir], "#x-label %c\n", extensions[dir][0]); - fprintf (fdset_2D[dir], "#y-label %c\n", extensions[dir][1]); - fprintf (fdset_2D[dir], "#z-label %s", advertised_file.varname); - if (groupinfo.dim != 2) - { - if (have_coords) - { - fprintf (fdset_2D[dir], zlabel_fmt_string, 'x' + (maxdir-dir-1), - coord_lower[maxdir-dir-1] + - GH->cctk_delta_space[maxdir-dir-1] * - myGH->sp2xyz[groupinfo.dim-1][dir]); - } - fprintf (fdset_2D[dir], " (%ci = %d)", - 'x' + (maxdir-dir-1), myGH->sp2xyz[groupinfo.dim-1][dir]); - } - fputc ('\n', fdset_2D[dir]); - } - } - - /* store file desriptors in database */ - StoreNamedData (&myGH->fileList_2D, alias, fdset_2D); - - free (filename); - free (fullname); - } + fileset = OpenFile (GH, fullname, alias, gdata.dim, + have_coords ? coord_lower : NULL, maxdir); } + else + { + fileset = NULL; + } + + CCTK_GroupgshVI (GH, 3, extent_int, vindex); + /* now do the actual I/O looping over all directions */ for (dir = 0; dir < maxdir; dir++) { - int dir_i, dir_j; - int directions[3]; - const int lengths[2] = {-1, -1}; - const int downsamples[2] = {1, 1}; - int hsize[2]; - CCTK_REAL *coord_data_i, *coord_data_j; - void *data; - /* get the directions to span the hyperslab */ if (dir == 0) { @@ -388,179 +245,372 @@ int IOASCII_Write2D (const cGH *GH, int vindex, const char *alias) dir_i = 1; dir_j = 2; /* yz */ } + /* set the extent vector */ + for (i = 0; i < 3; i++) + { + extent[i] = extent_int[i]; + } + /* set the origin using the slice center from IOUtil */ - memset (origin, 0, GH->cctk_dim * sizeof (int)); - origin[maxdir-dir-1] = myGH->sp2xyz[groupinfo.dim - 1][dir]; + memset (origin, 0, sizeof (origin)); + if (have_coords) + { + origin[maxdir-dir-1] = myGH->sp2xyz[gdata.dim - 1][dir]; + } - /* set the directions vector */ - memset (directions, 0, sizeof (directions)); - directions[maxdir-dir-1] = 1; + /* set the direction vector */ + memset (direction, 0, sizeof (direction)); + direction[dir_i] = direction[gdata.dim + dir_j] = 1; + + mapping = Hyperslab_DefineGlobalMappingByIndex (GH, vindex, 2, + direction, + origin, + extent, + NULL, /* downsample */ + -1, /* table handle */ + NULL /* conversion fn */, + hsize); + if (mapping < 0) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOASCII_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, + "IOASCII_Write2D: selected hyperslab has zero size for " + "variable '%s' direction %d", fullname, dir); + Hyperslab_FreeMapping (mapping); + continue; + } - /* get the coordinates for grid function output */ - if (have_coords) + if (myproc == 0) { - /* get the i-coordinate slice */ - if (Hyperslab_GetHyperslab (GH, 0, coord_index[dir_i], 0, 2, - origin, directions, lengths, downsamples, - (void **) &coord_data_i, hsize) < 0) + /* allocate hyperslab buffers */ + hdata[0] = malloc (total_hsize * CCTK_VarTypeSize (gdata.vartype)); + hdata[1] = have_coords ? malloc (2 * total_hsize * sizeof (CCTK_REAL)) : + NULL; + hdata[2] = (CCTK_REAL *) 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, hdata, + NULL); + + /* release the mapping structure */ + Hyperslab_FreeMapping (mapping); + + /* And dump the data to file */ + if (myproc == 0 && fileset) + { + 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++) + { + ((CCTK_REAL *) hdata[1])[i] += offset[0]; + ((CCTK_REAL *) hdata[2])[i] += offset[1]; + } + } + + WriteData (gdata.vartype, header, format, hsize, hdata, fileset[dir]); + } + else { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Failed to extract 2D hyperslab for %c-coordinate", - 'x' + dir_i); - return (-3); + "IOASCII_Write2D: Failed to extract hyperslab for " + "variable '%s'", fullname); } - /* get the j-coordinate slice */ - if (Hyperslab_GetHyperslab (GH, 0, coord_index[dir_j], 0, 2, - origin, directions, lengths, downsamples, - (void **) &coord_data_j, hsize) < 0) + /* clean up */ + free (hdata[0]); + if (hdata[1]) { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Failed to extract 2D hyperslab for %c-coordinate", - 'x' + dir_j); - free (coord_data_i); - return (-3); + 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 Wed 12 Dec 2001 + @author Thomas Radke + @desc + Opens a set of ASCII files for a given alias name. + If this is the first time through, it will create the files, + write some header information, and advertise them to IOUtil. + @enddesc + + @returntype FILE ** + @returndesc + the set of open file descriptors,<BR> + or NULL if a file couldn't be created + @endreturndesc + @@*/ +static FILE **OpenFile (const cGH *GH, + const char *fullname, + const char *alias, + int dim, + const CCTK_REAL *coord_lower, + int maxdir) +{ + int dir; + FILE **fileset; + char *filename; + asciiioGH *myGH; + const ioGH *ioUtilGH; + ioAdvertisedFileDesc advertised_file; + char slicename[30], zlabel_fmt_string[30], buffer[128]; + const char *extensions[] = {"xy", "xz", "yz"}; + DECLARE_CCTK_PARAMETERS + + + /* get handles for IOUtil and IOASCII extensions */ + myGH = (asciiioGH *) CCTK_GHExtension (GH, "IOASCII"); + ioUtilGH = (const ioGH *) CCTK_GHExtension (GH, "IO"); + + /* see if we are the first time through */ + fileset = (FILE **) GetNamedData (myGH->fileList_2D, alias); + if (fileset) + { + return (fileset); + } + + sprintf (zlabel_fmt_string, " (%%c = %%%s),", out_format); + fileset = (FILE **) malloc (3 * sizeof (FILE *)); + filename = (char *) malloc (strlen (myGH->outdir2D) + strlen (alias) + + sizeof (slicename) + 20); + + /* open/create files for each slice */ + for (dir = 0; dir < maxdir; dir++) + { + if (new_filename_scheme) + { + 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]); + } + + /* skip pathname if output goes into current directory */ + if (strcmp (myGH->outdir2D, ".")) + { + sprintf (filename, "%s/%s_%s.asc", myGH->outdir2D, alias, slicename); + } + else + { + sprintf (filename, "%s_%s.asc", alias, slicename); } } else { - /* grid arrays don't have coordinates assigned */ - coord_data_i = NULL; - coord_data_j = NULL; + /* skip pathname if output goes into current directory */ + if (strcmp (myGH->outdir2D, ".")) + { + if (dim == 2) + { + sprintf (filename, "%s/%s_2D.gnuplot", myGH->outdir2D, alias); + } + else + { + sprintf (filename, "%s/%s_2d_%s.gnuplot", myGH->outdir2D, alias, + extensions[dir]); + } + } + else + { + if (dim == 2) + { + sprintf (filename, "%s_2D.gnuplot", alias); + } + else + { + sprintf (filename, "%s_2d_%s.gnuplot", alias, extensions[dir]); + } + } } - /* get the variable slice */ - if (Hyperslab_GetHyperslab (GH, 0, vindex, 0, 2, origin, directions, - lengths, downsamples, &data, hsize) < 0) + /* if restart from recovery, try to open an existing file ... */ + fileset[dir] = fopen (filename, ioUtilGH->recovered ? "a" : "w"); + if (! fileset[dir]) { - fullname = CCTK_FullName (vindex); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Failed to extract 2D hyperslab for variable '%s'", fullname); - free (fullname); - if (coord_data_i) - { - free (coord_data_i); - } - if (coord_data_j) + "Cannot open 2D output file '%s'", filename); + free (fileset); + free (filename); + return (NULL); + } + + /* advertise the file for downloading and write file info */ + advertised_file.slice = new_filename_scheme ? slicename : extensions[dir]; + advertised_file.thorn = CCTK_THORNSTRING; + advertised_file.varname = fullname; + advertised_file.description = "Two-dimensional slice plots"; + advertised_file.mimetype = "application/gnuplot"; + + IOUtil_AdvertiseFile (GH, filename, &advertised_file); + + if (CCTK_Equals (out_fileinfo, "parameter filename") || + CCTK_Equals (out_fileinfo, "all")) + { + buffer[0] = 0; + CCTK_ParameterFilename (sizeof (buffer), buffer); + fprintf (fileset[dir], "#Parameter file %s\n", buffer); + } + if (CCTK_Equals (out_fileinfo, "creation date") || + CCTK_Equals (out_fileinfo, "all")) + { + buffer[0] = 0; + Util_CurrentDate (sizeof (buffer), buffer); + fprintf (fileset[dir], "#Created %s ", buffer); + Util_CurrentTime (sizeof (buffer), buffer); + fprintf (fileset[dir], "%s\n", buffer); + } + if (CCTK_Equals (out_fileinfo, "axis labels") || + CCTK_Equals (out_fileinfo, "all")) + { + fprintf (fileset[dir], "#x-label %c\n", extensions[dir][0]); + fprintf (fileset[dir], "#y-label %c\n", extensions[dir][1]); + fprintf (fileset[dir], "#z-label %s", advertised_file.varname); + if (dim != 2) { - free (coord_data_j); + if (coord_lower) + { + fprintf (fileset[dir], zlabel_fmt_string, 'x' + (maxdir-dir-1), + coord_lower[maxdir-dir-1] + + GH->cctk_delta_space[maxdir-dir-1] * + myGH->sp2xyz[dim-1][dir]); + } + fprintf (fileset[dir], " (%ci = %d)", + 'x' + (maxdir-dir-1), myGH->sp2xyz[dim-1][dir]); } - return (-3); + fputc ('\n', fileset[dir]); } + } - /* proc 0 writes */ - if (myproc == 0) - { - CCTK_REAL stagger_offset_i, stagger_offset_j; + /* store file desriptors in database */ + StoreNamedData (&myGH->fileList_2D, alias, fileset); + free (filename); - /* get the staggering offset for the coordinates */ - stagger_offset_i = CCTK_StaggerDirIndex (dir_i, groupinfo.stagtype) * - 0.5 * GH->cctk_delta_space[dir_i]; - stagger_offset_j = CCTK_StaggerDirIndex (dir_j, groupinfo.stagtype) * - 0.5 * GH->cctk_delta_space[dir_j]; + return (fileset); +} - /* print out header */ - fprintf (fdset_2D[dir], header_fmt_string, GH->cctk_time); - switch (groupinfo.vartype) - { - case CCTK_VARIABLE_CHAR: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_BYTE, int, data, hsize, - 0, have_coords, data_fmt_string_int,fdset_2D[dir]); - break; - - case CCTK_VARIABLE_INT: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_INT, int, data, hsize, - 0, have_coords, data_fmt_string_int,fdset_2D[dir]); - break; - - case CCTK_VARIABLE_REAL: - case CCTK_VARIABLE_COMPLEX: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_REAL, double, data, hsize, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX, - have_coords, data_fmt_string_real, fdset_2D[dir]); - break; +/*@@ + @routine WriteData + @date Wed 12 Dec 2001 + @author Thomas Radke + @desc + Writes the given hyperslabs into the appropriate output files. + @enddesc + @@*/ +static void WriteData (int vtype, + const char *header, + char format[3][30], + const CCTK_INT hsize[2], + void *const *const hdata, + FILE *file) +{ + int is_complex; + char complex_fmt_string[30]; + DECLARE_CCTK_PARAMETERS + + is_complex = strncmp (CCTK_VarTypeName (vtype), "CCTK_COMPLEX", 12) == 0; + sprintf (complex_fmt_string, "\t\t%%%s", out_format); + + /* print out header */ + fputs (header, file); + + if (vtype == CCTK_VARIABLE_CHAR) + { + WRITE_DATA (CCTK_BYTE, int, format[0]); + } + else if (vtype == CCTK_VARIABLE_INT) + { + WRITE_DATA (CCTK_INT, int, format[0]); + } + else if (vtype == CCTK_VARIABLE_REAL || vtype == CCTK_VARIABLE_COMPLEX) + { + WRITE_DATA (CCTK_REAL, double, format[1]); + } #ifdef CCTK_INT2 - case CCTK_VARIABLE_INT2: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_INT2, int, data, hsize, - 0, have_coords, data_fmt_string_int,fdset_2D[dir]); - break; + else if (vtype == CCTK_VARIABLE_INT2) + { + WRITE_DATA (CCTK_INT2, int, format[0]); + } #endif #ifdef CCTK_INT4 - case CCTK_VARIABLE_INT4: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_INT4, int, data, hsize, - 0, have_coords, data_fmt_string_int,fdset_2D[dir]); - break; + else if (vtype == CCTK_VARIABLE_INT4) + { + WRITE_DATA (CCTK_INT4, int, format[0]); + } #endif #ifdef CCTK_INT8 - case CCTK_VARIABLE_INT8: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_INT8, int, data, hsize, - 0, have_coords, data_fmt_string_int,fdset_2D[dir]); - break; + else if (vtype == CCTK_VARIABLE_INT8) + { + WRITE_DATA (CCTK_INT8, int, format[0]); + } #endif #ifdef CCTK_REAL4 - case CCTK_VARIABLE_REAL4: - case CCTK_VARIABLE_COMPLEX8: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_REAL4, double, data, hsize, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX8, - have_coords, data_fmt_string_real, fdset_2D[dir]); - break; + else if (vtype == CCTK_VARIABLE_REAL4 || vtype == CCTK_VARIABLE_COMPLEX8) + { + WRITE_DATA (CCTK_REAL4, double, format[1]); + } #endif #ifdef CCTK_REAL8 - case CCTK_VARIABLE_REAL8: - case CCTK_VARIABLE_COMPLEX16: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_REAL8, double, data, hsize, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX16, - have_coords, data_fmt_string_real, fdset_2D[dir]); - break; + else if (vtype == CCTK_VARIABLE_REAL8 || vtype == CCTK_VARIABLE_COMPLEX16) + { + WRITE_DATA (CCTK_REAL8, double, format[1]); + } #endif #ifdef CCTK_REAL16 - case CCTK_VARIABLE_REAL16: - case CCTK_VARIABLE_COMPLEX32: - OUTPUT_TYPED_DATA (coord_data_i, coord_data_j, stagger_offset_i, - stagger_offset_j, CCTK_REAL16, double, data, hsize, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX32, - have_coords, data_fmt_string_real, fdset_2D[dir]); - break; + else if (vtype == CCTK_VARIABLE_REAL16 || vtype == CCTK_VARIABLE_COMPLEX32) + { + WRITE_DATA (CCTK_REAL16, double, format[1]); + } #endif - default: - CCTK_WARN (1, "Unsupported variable type"); - break; - } - - /* keep the file open but flush it */ - fflush (fdset_2D[dir]); - - /* free the hyperslabs */ - free (data); - if (coord_data_i) - { - free (coord_data_i); - } - if (coord_data_j) - { - free (coord_data_j); - } - - } /* end of outputting the data by processor 0 */ - - } /* end of looping through xyz directions */ + else + { + CCTK_WARN (1, "Unsupported variable type"); + } - return (0); + /* keep the file open but flush it */ + fflush (file); } diff --git a/src/Write3D.c b/src/Write3D.c index e5c477b..0aee309 100644 --- a/src/Write3D.c +++ b/src/Write3D.c @@ -15,81 +15,77 @@ #include "cctk.h" #include "cctk_Parameters.h" #include "Hyperslab.h" +#include "CactusBase/IOUtil/src/ioGH.h" #include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h" -#include "CactusBase/IOUtil/src/ioutil_CheckpointRecovery.h" #include "ioASCIIGH.h" /* the rcs ID and its dummy function to use it */ -static const char *rcsid = "$Id$"; +static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusBase_IOASCII_Write3D_c) -/* enable debug output */ -/*#define IOASCII_DEBUG 1*/ - -/* macro to output a time volume as typed data */ -#define OUTPUT_TYPED_DATA(hsize, coord, stagger_offset, cctk_type, c_type, \ - data, have_coords, is_cmplx_type, fmt_string, file) \ - { \ - int _i, _j, _k; \ - const cctk_type *_typed_data = (const cctk_type *) (data); \ +/******************************************************************** + ******************** Macro Definitions ************************ + ********************************************************************/ +/* uncomment this to enable debugging output */ +/* #define DEBUG_IOASCII 1 */ + +/* Macro to output a 3D array (with coordinates if available) as typed data + For readability, the macro definition implicitely uses the following + variables (which are defined in the calling routine): + hdata, hsize, is_complex, format[2], file */ +#define WRITE_DATA(cctk_type, c_type, fmt) \ + { \ + int _i, _j, _k; \ + const cctk_type *_hdata = (const cctk_type *) hdata[0]; \ + const CCTK_REAL *_coord[3]; \ + \ \ \ - /* output coordinates if available otherwise just the indices */ \ - if (have_coords) \ + _coord[0] = (const CCTK_REAL *) hdata[1]; \ + _coord[1] = (const CCTK_REAL *) hdata[2]; \ + _coord[2] = (const CCTK_REAL *) hdata[3]; \ + for (_k = 0; _k < hsize[2]; _k++) \ + { \ + for (_j = 0; _j < hsize[1]; _j++) \ { \ - for (_k = 0; _k < hsize[2]; _k++) \ + for (_i = 0; _i < hsize[0]; _i++) \ { \ - for (_j = 0; _j < hsize[1]; _j++) \ + if (_coord[0]) \ { \ - for (_i = 0; _i < hsize[0]; _i++) \ - { \ - fprintf (file, fmt_string, \ - (double) (*coord[0]++ + stagger_offset[0]), \ - (double) (*coord[1]++ + stagger_offset[1]), \ - (double) (*coord[2]++ + stagger_offset[2]), \ - (c_type) *_typed_data++); \ - if (is_cmplx_type) \ - { \ - fprintf (file, "\t\t"); \ - fprintf (file, out_real_format, (double)*_typed_data++);\ - } \ - fprintf (file, "\n"); \ - } \ - fprintf (file, "\n"); \ + fprintf (file, fmt, \ + (double) *_coord[0]++, (double) *_coord[1]++, \ + (double) *_coord[2]++, (c_type) *_hdata++); \ } \ - } \ - coord[0] -= hsize[0] * hsize[1] * hsize[2]; \ - coord[1] -= hsize[0] * hsize[1] * hsize[2]; \ - coord[2] -= hsize[0] * hsize[1] * hsize[2]; \ - } \ - else \ - { \ - for (_k = 0; _k < hsize[2]; _k++) \ - { \ - for (_j = 0; _j < hsize[1]; _j++) \ + else \ + { \ + fprintf (file, fmt, (double) _i, (double) _j, (double) _k, \ + (c_type) *_hdata++); \ + } \ + \ + if (is_complex) \ { \ - for (_i = 0; _i < hsize[0]; _i++) \ - { \ - fprintf (file, fmt_string, \ - (double) _i, \ - (double) _j, \ - (double) _k, \ - (c_type) *_typed_data++); \ - if (is_cmplx_type) \ - { \ - fprintf (file, "\t\t"); \ - fprintf (file, out_real_format, (double)*_typed_data++);\ - } \ - fprintf (file, "\n"); \ - } \ - fprintf (file, "\n"); \ + fprintf (file, format[2], (c_type) *_hdata++); \ } \ + fputc ('\n', file); \ } \ + fputc ('\n', file); \ } \ - } + } \ + } +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +static FILE *OpenFile (const cGH *GH, const char *fullname, const char *alias); +static void WriteData (int vtype, + const char *header, + char format[3][30], + const CCTK_INT hsize[3], + void *const *const hdata, + FILE *file); + /*@@ @routine IOASCII_Write3D @date Wed 12 Dec 2001 @@ -97,8 +93,11 @@ CCTK_FILEVERSION(CactusBase_IOASCII_Write3D_c) @desc Writes the 3D volume of a variable into a gnuplot ASCII file. @enddesc - @calls IOUtil_RestartFromRecovery - IOUtil_AdvertiseFile + @calls Hyperslab_DefineGlobalMappingByIndex + Hyperslab_FreeMapping + Hyperslab_GetList + OpenFile + WriteData @var GH @vdesc Pointer to CCTK GH @@ -127,344 +126,375 @@ CCTK_FILEVERSION(CactusBase_IOASCII_Write3D_c) @@*/ int IOASCII_Write3D (const cGH *GH, int vindex, const char *alias) { - DECLARE_CCTK_PARAMETERS - int myproc, groupindex, dir, have_coords; - asciiioGH *myGH; - char header_fmt_string[30]; /* header format string */ - char out_real_format[30]; /* data format string for a real type */ - char time_fmt_string[30]; /* time format string */ - char data_fmt_string_int[30]; /* data format string for int types */ - char data_fmt_string_real[30]; /* data format string for real types */ - FILE **file; - int coord_index[3]; /* variable indices for xyz coordinates */ - CCTK_REAL coord_lower[3]; /* coordinates' minima */ - CCTK_REAL dummy; - char *filename; + int i, total_hsize; + int myproc, groupindex, have_coords; + int num_requested_hslabs, num_returned_hslabs; + char header[30], buffer[30]; + char format[3][30]; + FILE *file; + cGroup gdata; char *fullname; - cGroup groupinfo; - ioAdvertisedFileDesc advertised_file; - char buffer[128]; - const int directions[3] = {1, 1, 1}; - const int origin[3] = {0, 0, 0}; - const int lengths[3] = {-1, -1, -1}; - const int downsamples[3] = {1, 1, 1}; - int hsize[3]; - CCTK_REAL *coord_data[3], stagger_offset[3]; - void *data; - + void *hdata[4]; + int extent_int[3]; + CCTK_REAL offset[3]; + CCTK_INT mapping; + CCTK_INT vindices[4]; + CCTK_INT extent[3], hsize[3]; + const CCTK_INT origin[] = {0, 0, 0}, + direction[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + DECLARE_CCTK_PARAMETERS - /* to make the compiler happy */ - file = NULL; - filename = fullname = NULL; /* get the variable group information */ + fullname = CCTK_FullName (vindex); groupindex = CCTK_GroupIndexFromVarI (vindex); - CCTK_GroupData (groupindex, &groupinfo); + CCTK_GroupData (groupindex, &gdata); /* check if variable has storage assigned */ if (! CCTK_QueryGroupStorageI (GH, groupindex)) { - fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "No IOASCII 3D output for '%s' (no storage)", fullname); free (fullname); return (-1); } - /* Get the handle for IOASCII extensions */ - myGH = (asciiioGH *) CCTK_GHExtension (GH, "IOASCII"); - - /* set header and data format strings */ - sprintf (header_fmt_string, "\n\n#Time = %%%s\n", out_format); - sprintf (out_real_format, "%%%s", out_format); - dir = 0; - if (CCTK_Equals (out3D_style, "gnuplot f(t,x,y,z)")) - { - sprintf (time_fmt_string, "%%%s\t\t", out_format); - sprintf (data_fmt_string_int, time_fmt_string, (double) GH->cctk_time); - sprintf (data_fmt_string_real, time_fmt_string, (double) GH->cctk_time); - dir = strlen (data_fmt_string_int); - } - sprintf (data_fmt_string_int + dir, "%%%s\t\t%%%s\t\t%%d\t\t%%d", - out_format, out_format); - sprintf (data_fmt_string_real + dir, "%%%s\t\t%%%s\t\t%%%s\t\t%%%s", - out_format, out_format, out_format, out_format); - - /* get the coordinate indices if we output a grid function */ - if (groupinfo.grouptype == CCTK_GF) + /* get the coordinate indices for CCTK_GF variables + (CCTK_ARRAY variables never have coordinates associated) */ + vindices[0] = vindex; + have_coords = gdata.grouptype == CCTK_GF; + if (have_coords) { - have_coords = 1; - for (dir = 0; dir < 3; dir++) + for (i = 1; i <= 3; i++) { - CCTK_CoordRange (GH, &coord_lower[dir], &dummy, dir+1, NULL, "cart3d"); - coord_index[dir] = CCTK_CoordIndex (dir + 1, NULL, "cart3d"); - have_coords &= coord_index[dir] >= 0; + vindices[i] = CCTK_CoordIndex (i, NULL, "cart3d"); + have_coords &= vindices[i] >= 0; } if (! have_coords) { - CCTK_VWarn (8, __LINE__, __FILE__, CCTK_THORNSTRING, - "IOASCII_Write3D: No coordinate ranges found for '%s'", - "cart3d"); + CCTK_WARN (8, "IOASCII_Write3D: No coordinate ranges found for 'card3d'"); } } + num_requested_hslabs = have_coords ? 4 : 1; + + /* set header and data format strings */ + sprintf (buffer, "\n\n#Time = %%%s\n", out_format); + sprintf (header, buffer, (double) GH->cctk_time); + i = 0; + if (CCTK_Equals (out3D_style, "gnuplot f(t,x,y,z)")) + { + sprintf (buffer, "%%%s\t\t", out_format); + sprintf (format[0], buffer, (double) GH->cctk_time); + sprintf (format[1], buffer, (double) GH->cctk_time); + i = strlen (format[0]); + } + if (have_coords) + { + sprintf (format[0] + i, "%%%s\t\t%%%s\t\t%%d\t\t%%d", + out_format, out_format); + sprintf (format[1] + i, "%%%s\t\t%%%s\t\t%%%s\t\t%%%s", + out_format, out_format, out_format, out_format); + } else { - /* CCTK_ARRAY variables never have coordinates associated */ - have_coords = 0; + sprintf (format[0] + i, "%%d\t\t%%d\t\t%%d\t\t%%d"); + sprintf (format[1] + i, "%%d\t\t%%d\t\t%%%s\t\t%%%s", + out_format, out_format); } + sprintf (format[2], "\t\t%%%s", out_format); /* What processor are we on? */ myproc = CCTK_MyProc (GH); - /* Open the files on the first trip through if we are proc. 0 */ + /* Open the file on processor 0 */ + file = myproc == 0 ? OpenFile (GH, fullname, alias) : NULL; + + /* set the extent vector (copy from 'int' to 'CCTK_INT' */ + CCTK_GroupgshVI (GH, 3, extent_int, vindex); + for (i = 0; i < 3; i++) + { + extent[i] = extent_int[i]; + } + + /* get the hyperslab mapping */ + mapping = Hyperslab_DefineGlobalMappingByIndex (GH, vindex, 3, + direction, + origin, + extent, + NULL, /* downsample */ + -1, /* table handle */ + NULL /* conversion fn */, + hsize); + if (mapping < 0) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOASCII_Write3D: Failed to define hyperslab mapping for " + "variable '%s'", fullname); + free (fullname); + return (-1); + } + total_hsize = hsize[0] * hsize[1] * hsize[2]; + if (total_hsize <= 0) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOASCII_Write3D: selected hyperslab has zero size for " + "variable '%s'", fullname); + Hyperslab_FreeMapping (mapping); + free (fullname); + return (-1); + } + + if (myproc == 0) + { + /* allocate hyperslab buffers */ + hdata[0] = malloc (total_hsize * CCTK_VarTypeSize (gdata.vartype)); + hdata[1] = have_coords ? malloc (3 * total_hsize * sizeof (CCTK_REAL)) : + NULL; + hdata[2] = (CCTK_REAL *) hdata[1] + 1*total_hsize; + hdata[3] = (CCTK_REAL *) hdata[1] + 2*total_hsize; + } + + /* get the hyperslabs */ + num_returned_hslabs = Hyperslab_GetList (GH, mapping, num_requested_hslabs, + NULL, vindices, NULL, NULL, hdata, + NULL); + + /* And dump the data to file */ if (myproc == 0) { - /* see if output file for this alias name was already created */ - file = (FILE **) GetNamedData (myGH->fileList_3D, alias); - if (file == NULL) + if (num_returned_hslabs == num_requested_hslabs) { - file = (FILE **) malloc (sizeof (FILE *)); - filename = (char *) malloc (strlen (myGH->outdir3D) + strlen (alias) + 9); - - /* get the variable's full name */ - fullname = CCTK_FullName (vindex); - - /* Open/Create the file */ - /* skip pathname if output goes into current directory */ - if (strcmp (myGH->outdir3D, ".")) + if (have_coords) { - sprintf (filename, "%s/%s_3D.asc", myGH->outdir3D, alias); - } - else - { - sprintf (filename, "%s_3D.asc", alias); + /* 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++) + { + ((CCTK_REAL *) hdata[1])[i] += offset[0]; + ((CCTK_REAL *) hdata[2])[i] += offset[1]; + ((CCTK_REAL *) hdata[3])[i] += offset[2]; + } } - /* if restart from recovery, try to open an existing file ... */ - *file = NULL; - if (IOUtil_RestartFromRecovery (GH)) - { - *file = fopen (filename, "a"); - } + WriteData (gdata.vartype, header, format, hsize, hdata, file); + } + else + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOASCII_Write3D: Failed to extract hyperslab for " + "variable '%s'", fullname); + } - /* otherwise or if that failed, create a new one */ - if (! *file) - { - *file = fopen (filename, "w"); - } - if (! *file) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Cannot open 3D IOASCII output file '%s'", filename); - return (-2); - } + /* clean up */ + free (hdata[0]); + if (hdata[1]) + { + free (hdata[1]); + } + } /* end of outputting the data by processor 0 */ - /* advertise the file for downloading and write file info */ - /* FIXME: this can go when we permanently switch the the - new filename scheme */ - advertised_file.slice = ""; - advertised_file.thorn = CCTK_THORNSTRING; - advertised_file.varname = fullname; - advertised_file.description = "Full-dimensional variable contents"; - advertised_file.mimetype = "application/gnuplot"; + free (fullname); - IOUtil_AdvertiseFile (GH, filename, &advertised_file); + return (0); +} - if (CCTK_Equals (out_fileinfo, "parameter filename") || - CCTK_Equals (out_fileinfo, "all")) - { - buffer[0] = 0; - CCTK_ParameterFilename (sizeof (buffer), buffer); - fprintf (*file, "#Parameter file %s\n", buffer); - } - if (CCTK_Equals (out_fileinfo, "creation date") || - CCTK_Equals (out_fileinfo, "all")) - { - buffer[0] = 0; - Util_CurrentDate (sizeof (buffer), buffer); - fprintf (*file, "#Created %s ", buffer); - Util_CurrentTime (sizeof (buffer), buffer); - fprintf (*file, "%s\n", buffer); - } - if (CCTK_Equals (out_fileinfo, "axis labels") || - CCTK_Equals (out_fileinfo, "all")) - { - fprintf (*file, "#z-label %s\n", advertised_file.varname); - } - } - /* store file desriptors in database */ - StoreNamedData (&myGH->fileList_3D, alias, file); +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +/*@@ + @routine OpenFile + @date Wed 12 Dec 2001 + @author Thomas Radke + @desc + Opens an ASCII file for a given alias name. + If this is the first time through, it will create the file, + write some header information, and advertise it to IOUtil. + @enddesc - free (filename); - free (fullname); - } + @returntype FILE * + @returndesc + the file descriptor, or NULL if the file couldn't be created + @endreturndesc + @@*/ +static FILE *OpenFile (const cGH *GH, const char *fullname, const char *alias) +{ + FILE **file; + char *filename; + char buffer[128]; + asciiioGH *myGH; + const ioGH *ioUtilGH; + ioAdvertisedFileDesc advertised_file; + DECLARE_CCTK_PARAMETERS - /* get the coordinates for grid function output */ - if (have_coords) + + /* get handles for IOUtil and IOASCII extensions */ + myGH = (asciiioGH *) CCTK_GHExtension (GH, "IOASCII"); + ioUtilGH = (const ioGH *) CCTK_GHExtension (GH, "IO"); + + /* see if we are the first time through */ + file = (FILE **) GetNamedData (myGH->fileList_3D, alias); + if (file) { - /* get the i-coordinate volume */ - if (Hyperslab_GetHyperslab (GH, 0, coord_index[0], 0, 3, - origin, directions, lengths, downsamples, - (void **) &coord_data[0], hsize) < 0) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Failed to extract 3D hyperslab for x-coordinate"); - return (-3); - } + return (*file); + } - /* get the j-coordinate volume */ - if (Hyperslab_GetHyperslab (GH, 0, coord_index[1], 0, 3, - origin, directions, lengths, downsamples, - (void **) &coord_data[1], hsize) < 0) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Failed to extract 3D hyperslab for y-coordinate"); - free (coord_data[0]); - return (-3); - } + file = (FILE **) malloc (sizeof (FILE *)); + filename = (char *) malloc (strlen (myGH->outdir3D) + strlen (alias) + 9); - /* get the k-coordinate volume */ - if (Hyperslab_GetHyperslab (GH, 0, coord_index[2], 0, 3, - origin, directions, lengths, downsamples, - (void **) &coord_data[2], hsize) < 0) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Failed to extract 3D hyperslab for z-coordinate"); - free (coord_data[1]); - free (coord_data[0]); - return (-3); - } + /* Open/Create the file */ + /* skip pathname if output goes into current directory */ + if (strcmp (myGH->outdir3D, ".")) + { + sprintf (filename, "%s/%s_3D.asc", myGH->outdir3D, alias); } else { - /* grid arrays don't have coordinates assigned */ - coord_data[0] = coord_data[1] = coord_data[2] = NULL; + sprintf (filename, "%s_3D.asc", alias); } - /* get the variable volume */ - if (Hyperslab_GetHyperslab (GH, 0, vindex, 0, 3, origin, directions, - lengths, downsamples, &data, hsize) < 0) + /* if restart from recovery, try to open an existing file ... */ + *file = fopen (filename, ioUtilGH->recovered ? "a" : "w"); + if (! *file) { - fullname = CCTK_FullName (vindex); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Failed to extract 3D hyperslab for variable '%s'", fullname); - free (fullname); - for (dir = 0; dir < 3; dir++) - { - if (coord_data[dir]) - { - free (coord_data[dir]); - } - } - return (-3); + "Cannot open 3D IOASCII output file '%s'", filename); + return (NULL); } - /* proc 0 writes */ - if (myproc == 0) + /* 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/gnuplot"; + + IOUtil_AdvertiseFile (GH, filename, &advertised_file); + + if (CCTK_Equals (out_fileinfo, "parameter filename") || + CCTK_Equals (out_fileinfo, "all")) { - /* get the staggering offset for the coordinates */ - for (dir = 0; dir < 3; dir++) - { - stagger_offset[dir] = CCTK_StaggerDirIndex (dir, groupinfo.stagtype) * - 0.5 * GH->cctk_delta_space[dir]; - } + buffer[0] = 0; + CCTK_ParameterFilename (sizeof (buffer), buffer); + fprintf (*file, "#Parameter file %s\n", buffer); + } + if (CCTK_Equals (out_fileinfo, "creation date") || + CCTK_Equals (out_fileinfo, "all")) + { + buffer[0] = 0; + Util_CurrentDate (sizeof (buffer), buffer); + fprintf (*file, "#Created %s ", buffer); + Util_CurrentTime (sizeof (buffer), buffer); + fprintf (*file, "%s\n", buffer); + } + if (CCTK_Equals (out_fileinfo, "axis labels") || + CCTK_Equals (out_fileinfo, "all")) + { + fprintf (*file, "#z-label %s\n", advertised_file.varname); + } - /* print out header */ - fprintf (*file, header_fmt_string, GH->cctk_time); + /* store file desriptors in database */ + StoreNamedData (&myGH->fileList_3D, alias, file); + + free (filename); + + return (*file); +} - switch (groupinfo.vartype) - { - case CCTK_VARIABLE_CHAR: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_BYTE, int, - data, have_coords, 0, data_fmt_string_int, *file); - break; - - case CCTK_VARIABLE_INT: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_INT, int, - data, have_coords, 0, data_fmt_string_int, *file); - break; - - case CCTK_VARIABLE_REAL: - case CCTK_VARIABLE_COMPLEX: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_REAL, double, - data, have_coords, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX, - data_fmt_string_real, *file); - break; + +/*@@ + @routine WriteData + @date Wed 12 Dec 2001 + @author Thomas Radke + @desc + Writes the given hyperslab data into a file. + @enddesc + @@*/ +static void WriteData (int vtype, + const char *header, + char format[3][30], + const CCTK_INT hsize[3], + void *const *const hdata, + FILE *file) +{ + int is_complex; + + + if (file == NULL) + { + return; + } + + is_complex = strncmp (CCTK_VarTypeName (vtype), "CCTK_COMPLEX", 12) == 0; + + /* print out header */ + fputs (header, file); + + if (vtype == CCTK_VARIABLE_CHAR) + { + WRITE_DATA (CCTK_BYTE, int, format[0]); + } + else if (vtype == CCTK_VARIABLE_INT) + { + WRITE_DATA (CCTK_INT, int, format[0]); + } + else if (vtype == CCTK_VARIABLE_REAL || vtype == CCTK_VARIABLE_COMPLEX) + { + WRITE_DATA (CCTK_REAL, double, format[1]); + } #ifdef CCTK_INT2 - case CCTK_VARIABLE_INT2: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_INT2, int, - data, have_coords, 0, data_fmt_string_int, *file); - break; + else if (vtype == CCTK_VARIABLE_INT2) + { + WRITE_DATA (CCTK_INT2, int, format[0]); + } #endif #ifdef CCTK_INT4 - case CCTK_VARIABLE_INT4: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_INT4, int, - data, have_coords, 0, data_fmt_string_int, *file); - break; + else if (vtype == CCTK_VARIABLE_INT4) + { + WRITE_DATA (CCTK_INT4, int, format[0]); + } #endif #ifdef CCTK_INT8 - case CCTK_VARIABLE_INT8: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_INT8, int, - data, have_coords, 0, data_fmt_string_int, *file); - break; + else if (vtype == CCTK_VARIABLE_INT8) + { + WRITE_DATA (CCTK_INT8, int, format[0]); + } #endif #ifdef CCTK_REAL4 - case CCTK_VARIABLE_REAL4: - case CCTK_VARIABLE_COMPLEX8: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_REAL4, - double, data, have_coords, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX8, - data_fmt_string_real, *file); - break; + else if (vtype == CCTK_VARIABLE_REAL4 || vtype == CCTK_VARIABLE_COMPLEX8) + { + WRITE_DATA (CCTK_REAL4, double, format[1]); + } #endif #ifdef CCTK_REAL8 - case CCTK_VARIABLE_REAL8: - case CCTK_VARIABLE_COMPLEX16: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_REAL8, - double, data, have_coords, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX16, - data_fmt_string_real, *file); - break; + else if (vtype == CCTK_VARIABLE_REAL8 || vtype == CCTK_VARIABLE_COMPLEX16) + { + WRITE_DATA (CCTK_REAL8, double, format[1]); + } #endif #ifdef CCTK_REAL16 - case CCTK_VARIABLE_REAL16: - case CCTK_VARIABLE_COMPLEX32: - OUTPUT_TYPED_DATA (hsize, coord_data, stagger_offset, CCTK_REAL16, - double, data, have_coords, - groupinfo.vartype == CCTK_VARIABLE_COMPLEX32, - data_fmt_string_real, *file); - break; + else if (vtype == CCTK_VARIABLE_REAL16 || vtype == CCTK_VARIABLE_COMPLEX32) + { + WRITE_DATA (CCTK_REAL16, double, format[1]); + } #endif - default: - CCTK_WARN (1, "Unsupported variable type"); - break; - } - - /* keep the file open but flush it */ - fflush (*file); - - /* free the hyperslabs */ - free (data); - for (dir = 0; dir < 3; dir++) - { - if (coord_data[dir]) - { - free (coord_data[dir]); - } - } - - } /* end of outputting the data by processor 0 */ - + else + { + CCTK_WARN (1, "Unsupported variable type"); + } - return (0); + /* keep the file open but flush it */ + fflush (file); } diff --git a/src/ioASCIIGH.h b/src/ioASCIIGH.h index 1b9f705..19d5316 100644 --- a/src/ioASCIIGH.h +++ b/src/ioASCIIGH.h @@ -19,30 +19,23 @@ extern "C" typedef struct IOASCIIGH { - /* the number of times output */ - int out1D_every; - int out2D_every; - int out3D_every; + /* default number of times to output */ + int out1D_every_default, out2D_every_default, out3D_every_default; - /* flags indicating output for var [i] */ - char *do_out1D; - char *do_out2D; - char *do_out3D; + /* flags indicating output for var[i] */ + int *out1D_every, *out2D_every, *out3D_every; + + /* variables to output */ + char *out1D_vars, *out2D_vars, *out3D_vars; /* directories in which to output */ - char *outdir1D; - char *outdir2D; - char *outdir3D; + char *outdir1D, *outdir2D, *outdir3D; /* the last iteration output for var [i] */ - int *out1D_last; - int *out2D_last; - int *out3D_last; + int *out1D_last, *out2D_last, *out3D_last; /* database for names of output files that were already created */ - pNamedData *filenameList1D; - pNamedData *fileList_2D; - pNamedData *fileList_3D; + pNamedData *filenameList1D, *fileList_2D, *fileList_3D; /* for 1D lines, we define the index where to start the line: spxyz[maxdim][XYZdirection][xyzstart_index] */ |