diff options
Diffstat (limited to 'src/WriteScalar.c')
-rw-r--r-- | src/WriteScalar.c | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/src/WriteScalar.c b/src/WriteScalar.c new file mode 100644 index 0000000..8528bb8 --- /dev/null +++ b/src/WriteScalar.c @@ -0,0 +1,416 @@ +/*@@ + @routine WriteScalar.c + @date 18th September 1999 + @author Gabrielle Allen + @desc + Dumps data for IOBasic's "Scalar" I/O method to output files + @enddesc +@@*/ + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> /* strlen(3) */ +#include <sys/types.h> +#include <sys/stat.h> /* stat(2) */ + +#include "cctk.h" +#include "cctk_Parameters.h" +#include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h" +#include "CactusBase/IOUtil/src/ioutil_CheckpointRecovery.h" +#include "iobasicGH.h" + +static const char *rcsid = "$Header$"; + +CCTK_FILEVERSION(CactusBase_IOBasic_WriteScalar_c) + + +static FILE *OpenScalarFile (cGH *GH, + int vindex, + const char *filename, + const char *slicename, + const char *description, + const char *aliasname); + + /*@@ + @routine IOBasic_WriteScalarGA + @date Mon Jun 19 2000 + @author Thomas Radke + @desc + Apply the given reduction operators on the CCTK_ARRAY or + CCTK_GF variable and output the result into a text file + suitable for postprocessing by either gluplot or xgraph. + @enddesc + + @calls CCTK_QueryGroupStorageI + CCTK_Reduce + CCTK_ReductionHandle + IOUtil_RestartFromRecovery + IOUtil_AdvertiseFile + + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH * + @vio in + @endvar + @var vindex + @vdesc CCTK index of the variable to output + @vtype int + @vio in + @endvar + @var alias + @vdesc alias name to use for building the output filename + @vtype const char * + @vio in + @endvar +@@*/ +void IOBasic_WriteScalarGA (cGH *GH, + int vindex, + const char *alias) +{ + DECLARE_CCTK_PARAMETERS + int ierr; + int reduction_handle; + iobasicGH *myGH; + FILE *file; + char *filename; + char *reduction_op; + char *string_start; + char *string_end; + char format_str[15]; + const char *file_extension; + char *fullname; + CCTK_REAL reduction_value; + union + { + char *non_const_ptr; + const char *const_ptr; + } reductions; + + + /* this union helps us to avoid compiler warning about discarding + the const qualifier from a pointer target type */ + reductions.const_ptr = outScalar_reductions; + + /* first, check if variable has storage assigned */ + if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (vindex))) + { + fullname = CCTK_FullName (vindex); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOBasic_WriteScalarGA: No scalar output for '%s' (no storage)", + fullname); + free (fullname); + return; + } + + /* set output format */ + sprintf (format_str, "%%%s\t%%%s\n", out_format, out_format); + + /* set the output file extension and the output style */ + file_extension = CCTK_Equals (outScalar_style, "gnuplot") ? ".asc" : ".xg"; + + /* get the GH extension handle for IOBasic */ + myGH = (iobasicGH *) CCTK_GHExtension (GH, "IOBasic"); + + /* allocate strings for the filename and the reduction operator */ + filename = (char *) malloc (strlen (myGH->outdirScalar) + strlen (alias) + + strlen (reductions.const_ptr) + + strlen (file_extension) + 3); + reduction_op = (char *) malloc (strlen (reductions.const_ptr) + 1); + + /* now loop over all reduction operators */ + string_start = reductions.non_const_ptr; + while (string_start && *string_start) + { + /* skip leading spaces */ + while (isspace ((int) *string_start)) + { + string_start++; + } + if (! *string_start) + { + break; + } + + /* advance to end of the operator string */ + string_end = string_start + 1; + while (*string_end && ! isspace ((int) *string_end)) + { + string_end++; + } + + /* copy the operator string */ + strncpy (reduction_op, string_start, string_end - string_start); + reduction_op[string_end - string_start] = 0; + string_start = string_end; + + /* get the reduction handle from the reduction operator */ + reduction_handle = CCTK_ReductionHandle (reduction_op); + if (reduction_handle < 0) + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOBasic_WriteScalarGA: Invalid reduction operator '%s'", + reduction_op); + continue; + } + + /* do the reduction (all processors) */ + ierr = CCTK_Reduce (GH, 0, reduction_handle, 1, CCTK_VARIABLE_REAL, + &reduction_value, 1, vindex); + + /* dump the reduction value to file by processor 0 */ + if (ierr == 0 && CCTK_MyProc (GH) == 0) + { + + /* build the filename */ + if (new_filename_scheme) + { + sprintf (filename, "%s%s_%s%s", myGH->outdirScalar, alias, + reduction_op, file_extension); + } + else + { + /* FIXME: this check can go if we switch to the new filename scheme */ + if (strcmp (reduction_op, "minimum") == 0) + { + file_extension = "min"; + } + else if (strcmp (reduction_op, "maximum") == 0) + { + file_extension = "max"; + } + else if (strcmp (reduction_op, "norm1") == 0) + { + file_extension = "nm1"; + } + else if (strcmp (reduction_op, "norm2") == 0) + { + file_extension = "nm2"; + } + else + { + file_extension = "unknown"; + } + sprintf (filename, "%s%s_%s.tl", myGH->outdirScalar, alias, + file_extension); + } + + file = OpenScalarFile (GH, vindex, filename, reduction_op, + "Reduction on Grid Arrays", alias); + if (file) + { + /* write the data and close the file */ + fprintf (file, format_str, GH->cctk_time, reduction_value); + fclose (file); + } + else + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOBasic_WriteScalarGA: Could not open output file '%s'", + filename); + } + } + } + + /* free allocated resources */ + free (reduction_op); + free (filename); +} + + + /*@@ + @routine IOBasic_WriteScalarGS + @date Mon Jun 19 2000 + @author Thomas Radke + @desc + Output the value of a CCTK_SCALAR variable into an ASCII file + suitable for postprocessing by either gluplot or xgraph. + @enddesc + + @calls CCTK_QueryGroupStorageI + CCTK_Reduce + CCTK_ReductionHandle + IOUtil_RestartFromRecovery + IOUtil_AdvertiseFile + + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH * + @vio in + @endvar + @var vindex + @vdesc CCTK index of the variable to output + @vtype int + @vio in + @endvar + @var alias + @vdesc alias name to use for building the output filename + @vtype const char * + @vio in + @endvar +@@*/ +void IOBasic_WriteScalarGS (cGH *GH, int vindex, const char *alias) +{ + DECLARE_CCTK_PARAMETERS + FILE *file; + void *data; + iobasicGH *myGH; + char *fullname, *filename; + char format_str_real[15], format_str_int[15]; + + + /* output is done by processor 0 only */ + if (CCTK_MyProc (GH) != 0) + { + return; + } + + /* first, check if variable has storage assigned */ + if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (vindex))) + { + fullname = CCTK_FullName (vindex); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOBasic_WriteScalarGS: No scalar output for '%s' (no storage)", + fullname); + free (fullname); + return; + } + + /* set the output format string for the desired notation */ + sprintf (format_str_real, "%%%s\t%%%s\n", out_format, out_format); + sprintf (format_str_int, "%%%s\t%%d\n", out_format); + + /* get the GH extensions for IOBasic */ + myGH = (iobasicGH *) CCTK_GHExtension (GH, "IOBasic"); + + /* build the output filename */ + filename = (char *) malloc (strlen (myGH->outdirScalar) + strlen (alias) + 4); + sprintf (filename, "%s%s.tl", myGH->outdirScalar, alias); + + file = OpenScalarFile (GH, vindex, filename, "tl", "Scalar value", alias); + if (file) + { + /* get the data pointer */ + data = CCTK_VarDataPtrI (GH, 0, vindex); + + switch (CCTK_VarTypeI (vindex)) + { + case CCTK_VARIABLE_REAL: + fprintf (file, format_str_real, GH->cctk_time, + (double) *(CCTK_REAL *) data); + break; + case CCTK_VARIABLE_INT: + fprintf (file, format_str_int, GH->cctk_time, + (int) *(CCTK_INT *) data); + break; + default: + CCTK_WARN (3, "Unsupported data type"); + break; + } + + /* close the output file */ + fclose (file); + } + else + { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "IOBasic_WriteScalarGS: Could not open output file '%s'", + filename); + } + + /* clean up */ + free (filename); +} + + +static FILE *OpenScalarFile (cGH *GH, + int vindex, + const char *filename, + const char *slicename, + const char *description, + const char *aliasname) +{ + DECLARE_CCTK_PARAMETERS + FILE *file; + char comment_char, buffer[128]; + ioAdvertisedFileDesc advertised_file; + iobasicGH *myGH; + char *openmode; + struct stat fileinfo; + + + /* get the GH extension handle for IOBasic */ + myGH = (iobasicGH *) CCTK_GHExtension (GH, "IOBasic"); + + /* see if output files for this alias name were already created */ + if (GetNamedData (myGH->filenameListScalar, filename) == NULL) + { + /* if restart from recovery, all existing files are opened + in append mode */ + if (IOUtil_RestartFromRecovery (GH)) + openmode = stat (filename, &fileinfo) == 0 ? "a" : "w"; + else + openmode = "w"; + } + else + { + openmode = "a"; + } + + /* open the output file with the given mode */ + file = fopen (filename, openmode); + if (file && *openmode == 'w') + { + if (CCTK_Equals (outScalar_style, "gnuplot")) + { + comment_char = '#'; + advertised_file.mimetype = "application/gnuplot"; + } + else + { + comment_char = '"'; /* this is for xgraph */ + advertised_file.mimetype = "application/x-graph"; + } + + /* just store a non-NULL pointer in database */ + StoreNamedData (&myGH->filenameListScalar, filename, (void *) 1); + + /* advertise the file for downloading */ + advertised_file.slice = strdup (slicename); + advertised_file.thorn = CCTK_THORNSTRING; + advertised_file.varname = CCTK_FullName (vindex); + advertised_file.description = strdup (description); + + IOUtil_AdvertiseFile (GH, filename, &advertised_file); + + /* write the file info and the header */ + if (CCTK_Equals (out_fileinfo, "parameter filename") || + CCTK_Equals (out_fileinfo, "all")) + { + buffer[0] = 0; + CCTK_ParameterFilename (sizeof (buffer), buffer); + fprintf (file, "%cParameter file %s\n", comment_char, buffer); + } + if (CCTK_Equals (out_fileinfo, "creation date") || + CCTK_Equals (out_fileinfo, "all")) + { + buffer[0] = 0; + Util_CurrentDate (sizeof (buffer), buffer); + fprintf (file, "%cCreated %s ", comment_char, 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, "%cx-label time\n", comment_char); + fprintf (file, "%cy-label %s\n", comment_char, advertised_file.varname); + } + fprintf (file, "%c%s v time\n", comment_char, aliasname); + + free (advertised_file.description); + free (advertised_file.varname); + free (advertised_file.slice); + } + + return (file); +} |