/*@@ @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 "util_Table.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 */ 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, coord_system_handle, retval; int extent_int[3], extent_flexio[2]; CCTK_INT origin[3], extent[2], direction[6], hsize[2], coord_handles[3]; CCTK_INT4 itmp; void *data; char *fullname, *groupname; /* 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 handle for IOFlexIO extension */ myGH = GH->extensions[CCTK_GHExtensionHandle ("IOFlexIO")]; /* What processor are we on? */ myproc = CCTK_MyProc (GH); /* get the appropriate FlexIO data type */ if (groupinfo.vartype == CCTK_VARIABLE_BYTE) { ioflex_type = FLEXIO_BYTE; } 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 = malloc (3 * sizeof (IOFile)); fname = 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 (! IO_TruncateOutputFiles (GH)) { 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", 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", 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 */ groupname = CCTK_GroupNameFromVarI (vindex); coord_system_handle = -1; if (CCTK_IsFunctionAliased ("Coord_GroupSystem")) { coord_system_handle = Coord_GroupSystem (GH, groupname); } free (groupname); if (coord_system_handle >= 0 && Util_TableGetIntArray (coord_system_handle, 3, coord_handles, "COORDINATES") >= 0) { for (dir = 0; dir < 3; dir++) { Util_TableGetReal (coord_handles[dir], &min_ext[dir], "COMPMIN"); Util_TableGetReal (coord_handles[dir], &max_ext[dir], "COMPMAX"); } } /* 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 */ data = NULL; if (myproc == 0) { data = malloc (total_hsize * CCTK_VarTypeSize (groupinfo.vartype)); } /* 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], "name", CHAR, strlen (fullname) + 1, fullname)); itmp = GH->cctk_iteration; FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "iteration", FLEXIO_INT4, 1, &itmp)); itmp = 0; FLEXIO_ERROR (IOwriteAttribute (IEEEfile_2D[dir], "timelevel", FLEXIO_INT4, 1, &itmp)); 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); }