/*@@ @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 "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 */ int total_hsize, mapping, dir_i, dir_j, retval; int extent_int[3], extent_flexio[2]; CCTK_INT origin[3], extent[2], direction[6], hsize[2]; void *data; char *fullname; /* to make the compiler happy */ IEEEfile_2D = NULL; /* get the variable group indormation */ groupindex = CCTK_GroupIndexFromVarI (vindex); CCTK_GroupData (groupindex, &groupinfo); fullname = CCTK_FullName (vindex); /* check if variable has storage assigned */ if (! CCTK_QueryGroupStorageI (GH, groupindex)) { 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->out2D_dir) + strlen (alias) + strlen (GH->identity) + 20); /* Open/Create files */ for (dir = 0; dir < 3; dir++) { int len; char buffer[128]; const char *extensions[3] = {"xy", "xz", "yz"}; sprintf (fname, "%s/%s_2d_%s%s.ieee", myGH->out2D_dir, 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 (CCTK_Equals (verbose, "full")) { 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"); /* get the extents of the variable */ CCTK_GroupgshVI (GH, 3, extent_int, vindex); /* loop over all 3 planes */ for (dir = 0; dir < 3; dir++) { /* get the directions to span the hyperslab */ if (dir == 0) { dir_i = 0; dir_j = 1; /* xy */ } else if (dir == 1) { dir_i = 0; dir_j = 2; /* xz */ } else { dir_i = 1; dir_j = 2; /* yz */ } /* set the extent vector */ extent[0] = extent_int[dir_i]; extent[1] = extent_int[dir_j]; extent_flexio[0] = extent_int[dir_i]; extent_flexio[1] = extent_int[dir_j]; /* set the origin using the slice center from IOUtil */ memset (origin, 0, sizeof (origin)); origin[3-dir-1] = myGH->sp2xyz[2][dir]; /* set the direction vector */ memset (direction, 0, sizeof (direction)); direction[dir_i] = direction[3 + dir_j] = 1; mapping = Hyperslab_GlobalMappingByIndex (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, "IOFlexIO_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, "IOFlexIO_Write2D: selected hyperslab has zero size for " "variable '%s' direction %d", fullname, dir); Hyperslab_FreeMapping (mapping); continue; } /* allocate hyperslab buffers */ if (myproc == 0) { data = malloc (total_hsize * CCTK_VarTypeSize (groupinfo.vartype)); } else { data = NULL; } /* get the variable slice */ retval = Hyperslab_Get (GH, mapping, 0, vindex, 0, -1, data); /* release the mapping structure */ Hyperslab_FreeMapping (mapping); /* processor 0 write the hyperslab data */ if (myproc == 0) { if (retval >= 0) { /* the data itself */ FLEXIO_ERROR (IOwrite (IEEEfile_2D[dir], ioflex_type, 2, extent_flexio, 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)); } else { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Failed to extract 2D hyperslab for variable '%s'", fullname); } free (data); } } /* end of loop over all 3 planes */ free (fullname); if (reuse_filehandles && myproc == 0) { /* pause the files (close system descriptors) */ if (CCTK_Equals (verbose, "full")) { 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); }