/*@@ @file Write2D.c @date Tue Feb 3 19:06:12 1998 @author Paul Walker @desc Two dimensional slices into IEEEIO files on MPI distributed cactus data. @enddesc @history @hauthor Gabrielle Allen @hdate 26 Sep 1998 @hdesc Changed subroutine name (SliceTwoD -> Write2D), renamed IO parameters @hauthor Gabrielle Allen @hdate Oct 17 1998 @hdesc Added the IO_verbose parameter instead of an ifdef @hauthor Gabrielle Allen @hdate 19 Oct 1998 @hdesc Changed names ready for thorn_IO @hauthor Thomas Radke @hdate 16 Mar 1999 @hdesc Converted to Cactus 4.0 @hauthor Thomas Radke @hdate 17 Mar 1999 @hdesc Changed naming: IEEEIO -> IOFlexIO @hendhistory @version $Id$ @@*/ #include #include #include #include "cctk.h" #include "cctk_Parameters.h" #include "Hyperslab.h" #include "CactusBase/IOUtil/src/ioGH.h" #include "ioFlexGH.h" static const char *rcsid = "$Id$"; CCTK_FILEVERSION(CactusPUGHIO_IOFlexIO_Write2D_c) /*@@ @routine IOFlexIO_Write2D @date Sat March 6 1999 @author Gabrielle Allen @desc Writes the 2D data of a variable into separate IEEEIO files @enddesc @calledby IOFlexIO_Output2DVarAs IOFlexIO_TriggerOutput2D @history @endhistory @var GH @vdesc Pointer to CCTK GH @vtype const cGH * @vio in @vcomment @endvar @var vindex @vdesc index of variable to output @vtype int @vio in @vcomment @endvar @var alias @vdesc alias name of variable to output @vtype const char * @vio in @vcomment @endvar @@*/ int IOFlexIO_Write2D (const cGH *GH, int vindex, const char *alias) { DECLARE_CCTK_PARAMETERS int dir; /* looper for directions */ int myproc; /* my processor ID */ const ioGH *ioUtilGH; flexioGH *myGH; /* IOFlexIO's extensions */ int ioflex_type; /* IEEEIO output datatype */ int groupindex; /* variable's group index */ cGroup groupinfo; /* variable's group information */ CCTK_REAL min_ext[3], max_ext[3]; /* bounding box information */ CCTK_REAL min_ext_attr[2], max_ext_attr[2], delta_attr[2]; IOFile *IEEEfile_2D; /* file descriptors */ /* to make the compiler happy */ IEEEfile_2D = NULL; /* get the variable group indormation */ groupindex = CCTK_GroupIndexFromVarI (vindex); CCTK_GroupData (groupindex, &groupinfo); /* check if variable has storage assigned */ if (! CCTK_QueryGroupStorageI (GH, groupindex)) { char *fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "No IOFlexIO 2D output for '%s' (no storage)", fullname); free (fullname); return (-1); } /* Get the handles for IOUtil and IOFlexIO extensions */ myGH = (flexioGH *) GH->extensions[CCTK_GHExtensionHandle ("IOFlexIO")]; ioUtilGH = (const ioGH *) GH->extensions[CCTK_GHExtensionHandle ("IO")]; /* What processor are we on? */ myproc = CCTK_MyProc (GH); /* get the appropriate FlexIO data type */ if (groupinfo.vartype == CCTK_VARIABLE_CHAR) { ioflex_type = FLEXIO_CHAR; } else if (groupinfo.vartype == CCTK_VARIABLE_INT) { ioflex_type = FLEXIO_INT; } else if (groupinfo.vartype == CCTK_VARIABLE_REAL) { ioflex_type = FLEXIO_REAL; } else { CCTK_WARN (1, "Unsupported variable type in IOFlexIO_Write2D"); return (-2); } /* 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 */ IEEEfile_2D = (IOFile *) GetNamedData (myGH->fileList_2D, alias); if (IEEEfile_2D == NULL) { char *fname; IEEEfile_2D = (IOFile *) malloc (3 * sizeof (IOFile)); fname = (char *) malloc (strlen (myGH->outdir2D) + strlen (alias) + strlen (GH->identity) + 20); /* Open/Create files */ for (dir = 0; dir < 3; dir++) { int len; char buffer[128]; const char *extensions[3] = {"yz", "xz", "xy"}; sprintf (fname, "%s/%s_2d_%s%s.ieee", myGH->outdir2D, alias, extensions[dir], GH->identity); /* if restart from recovery, try to open an exisiting file ... */ IEEEfile_2D[dir] = NULL; if (ioUtilGH->recovered) { IEEEfile_2D[dir] = IEEEopen (fname, "a"); } /* otherwise or if that failed, create a new one */ if (! IOisValid (IEEEfile_2D[dir])) { IEEEfile_2D[dir] = IEEEopen (fname, "w"); } if (! IOisValid (IEEEfile_2D[dir])) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "IOFlexIO_Write2D: Cannot open 2D output file '%s'", fname); return (-3); } /* add the parameter filename and the creation date as file identification attributes */ if (CCTK_Equals (out_fileinfo, "parameter filename") || CCTK_Equals (out_fileinfo, "all")) { buffer[0] = 0; CCTK_ParameterFilename (sizeof (buffer), buffer); FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "parameter file", FLEXIO_CHAR, strlen (buffer) + 1, buffer)); } if (CCTK_Equals (out_fileinfo, "creation date") || CCTK_Equals (out_fileinfo, "all")) { buffer[0] = 0; Util_CurrentDate (sizeof (buffer), buffer); len = strlen (buffer) + 1; buffer[len-1] = ' '; Util_CurrentTime (sizeof (buffer) - len, buffer + len); FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "creation date", FLEXIO_CHAR, strlen (buffer) + 1, buffer)); } } /* store file desriptors in database */ StoreNamedData (&myGH->fileList_2D, alias, IEEEfile_2D); free (fname); } if (reuse_filehandles) { /* resume the files (reopen descriptors) This allows descriptor reuse without requiring expensive destruction and reallocation of the associated data structures */ if (verbose) { CCTK_VInfo (CCTK_THORNSTRING, "Resuming 2D output files for variable " "'%s'", CCTK_VarName (vindex)); } for (dir = 0; dir < 3; dir++) { FLEXIO_ERROR (IOresume (IEEEfile_2D[dir])); } } } /* get the coordinate ranges */ CCTK_CoordRange (GH, &min_ext[0], &max_ext[0], -1, "x", "cart3d"); CCTK_CoordRange (GH, &min_ext[1], &max_ext[1], -1, "y", "cart3d"); CCTK_CoordRange (GH, &min_ext[2], &max_ext[2], -1, "z", "cart3d"); /* loop over all 3 planes */ for (dir = 0; dir < 3; dir++) { int dir_i, dir_j; int directions[3], origin[3]; const int lengths[2] = {-1, -1}; const int downsamples[2] = {1, 1}; int data_hsizes[2]; void *data; /* get the directions to span the hyperslab */ if (dir == 0) { dir_i = 1; dir_j = 2; /* yz */ } else if (dir == 1) { dir_i = 0; dir_j = 2; /* xz */ } else { dir_i = 0; dir_j = 1; /* xy */ } /* set the origin using the slice center from IOUtil */ memset (origin, 0, GH->cctk_dim * sizeof (int)); origin[dir] = myGH->sp2xyz[groupinfo.dim-1][dir]; /* set the directions vector */ memset (directions, 0, sizeof (directions)); directions[dir] = 1; /* get the variable slice */ if (Hyperslab_GetHyperslab (GH, 0, vindex, 0, 2, origin, directions, lengths, downsamples, &data, data_hsizes) < 0) { char *fullname = CCTK_FullName (vindex); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Failed to extract 2D hyperslab for variable '%s'", fullname); free (fullname); return (-4); } /* processor 0 write the hyperslab data */ if (myproc == 0) { /* the data itself */ FLEXIO_ERROR (IOwrite (IEEEfile_2D[dir], ioflex_type, 2, data_hsizes, data)); free (data); /* Time, space, and coordinate attributes */ min_ext_attr[0] = min_ext[dir_i]; min_ext_attr[1] = min_ext[dir_j]; max_ext_attr[0] = max_ext[dir_i]; max_ext_attr[1] = max_ext[dir_j]; delta_attr[0] = GH->cctk_delta_space[dir_i]; delta_attr[1] = GH->cctk_delta_space[dir_j]; FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "time", FLEXIO_REAL, 1, &GH->cctk_time)); FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "origin", FLEXIO_REAL, 2, min_ext_attr)); FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "min_ext", FLEXIO_REAL, 2, min_ext_attr)); FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "max_ext", FLEXIO_REAL, 2, max_ext_attr)); FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "delta", FLEXIO_REAL, 2, delta_attr)); } } /* end of loop over all 3 planes */ if (reuse_filehandles && myproc == 0) { /* pause the files (close system descriptors) */ if (verbose) { CCTK_VInfo (CCTK_THORNSTRING, "Pausing 2D output files for variable '%s'", CCTK_VarName (vindex)); } for (dir = 0; dir < 3; dir++) { FLEXIO_ERROR (IOpause (IEEEfile_2D[dir])); } } return (0); }