/*@@ @file Output.c @date Tue Jan 9 1999 @author Gabrielle Allen @desc Functions to deal with IOFlexIO output of grid variables @enddesc @version $Id$ @@*/ #include #include #include #include "cctk.h" #include "cctk_Parameters.h" #include "util_String.h" #include "ioFlexGH.h" /* the rcs ID and its dummy function to use it */ static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusPUGHIO_IOFlexIO_Output_c) /*@@ @routine IOFlexIO_OutputGH @date Sat March 6 1999 @author Gabrielle Allen @desc Loops over all variables and outputs them if necessary @enddesc @calls IOFlexIO_TimeFor IOFlexIO_Write @var GH @vdesc pointer to CCTK GH @vtype const cGH * @vio in @endvar @returntype int @returndesc the number of variables which were output at this iteration (or 0 if it wasn't time to output yet) @endreturndesc @@*/ int IOFlexIO_OutputGH (const cGH *GH) { int vindex, retval; const flexioGH *myGH; retval = 0; myGH = CCTK_GHExtension (GH, "IOFlexIO"); /* loop over all variables */ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--) { if (IOFlexIO_TimeFor (GH, vindex) && IOFlexIO_Write (GH, vindex, CCTK_VarName (vindex)) == 0) { /* register variable as having output this iteration */ myGH->out_last[vindex] = GH->cctk_iteration; retval++; } } return (retval); } /*@@ @routine IOFlexIO_OutputVarAs @date Sat March 6 1999 @author Gabrielle Allen @desc Unconditional output of a variable using the IOFlexIO I/O method. @enddesc @calls IOUtil_ParseVarsForOutput IOFlexIO_Write IOUtil_FreeIORequest @var GH @vdesc pointer to CCTK GH @vtype const cGH * @vio in @endvar @var fullname @vdesc complete name of variable to output @vtype const char * @vio in @endvar @var alias @vdesc alias name of variable to output (used to generate output filename) @vtype const char * @vio in @endvar @returntype int @returndesc return code of @seeroutine IOFlexIO_Write @endreturndesc @@*/ int IOFlexIO_OutputVarAs (const cGH *GH, const char *fullname, const char*alias) { int vindex, oneshot, retval; const flexioGH *myGH; DECLARE_CCTK_PARAMETERS vindex = CCTK_VarIndex (fullname); if (CCTK_Equals (verbose, "full")) { CCTK_VInfo (CCTK_THORNSTRING, "IOFlexIO_OutputVarAs: (fullname, alias, " "index) = (%s, %s, %d)", fullname, alias, vindex); } /* check whether the variable already has an I/O request entry */ myGH = CCTK_GHExtension (GH, "IOFlexIO"); oneshot = myGH->requests[vindex] == NULL; if (oneshot) { IOUtil_ParseVarsForOutput (GH, CCTK_THORNSTRING, "IOFlexIO::out_vars", 0, fullname, 1, -1.0, myGH->requests); } /* do the output */ retval = IOFlexIO_Write (GH, vindex, alias); if (oneshot && myGH->requests[vindex]) { IOUtil_FreeIORequest (&myGH->requests[vindex]); } return (retval); } /*@@ @routine IOFlexIO_TimeFor @date Sat March 6 1999 @author Gabrielle Allen @desc Decides if it is time to output a variable using the IOFlexIO I/O method. @enddesc @calls IOFlexIO_CheckSteerableParameters @var GH @vdesc pointer to CCTK GH @vtype const cGH * @vio in @endvar @var vindex @vdesc index of variable @vtype int @vio in @endvar @returntype int @returndesc 1 if output should take place at this iteration, or
0 if not @endreturndesc @@*/ int IOFlexIO_TimeFor (const cGH *GH, int vindex) { int retval; char *fullname; flexioGH *myGH; myGH = CCTK_GHExtension (GH, "IOFlexIO"); IOFlexIO_CheckSteerableParameters (GH, myGH); /* check if this variable should be output */ retval = myGH->requests[vindex] && myGH->requests[vindex]->out_every > 0 && GH->cctk_iteration % myGH->requests[vindex]->out_every == 0; if (retval) { /* check if variable was not already output this iteration */ if (myGH->out_last[vindex] == GH->cctk_iteration) { fullname = CCTK_FullName (vindex); CCTK_VWarn (6, __LINE__, __FILE__, CCTK_THORNSTRING, "Already done IOFlexIO output for variable '%s' in current " "iteration (probably via triggers)", fullname); free (fullname); retval = 0; } } return (retval); } /*@@ @routine IOFlexIO_TriggerOutput @date Sat March 6 1999 @author Gabrielle Allen @desc Triggers the output a variable using the IOFlexIO I/O method. method @calls IOFlexIO_Write @var GH @vdesc pointer to CCTK GH @vtype const cGH * @vio in @endvar @var vindex @vdesc index of variable @vtype int @vio in @endvar @returntype int @returndesc return code of @seeroutine IOFlexIO_Write @endreturndesc @@*/ int IOFlexIO_TriggerOutput (const cGH *GH, int vindex) { int retval; const char *varname; const flexioGH *myGH; DECLARE_CCTK_PARAMETERS varname = CCTK_VarName (vindex); if (CCTK_Equals (verbose, "full")) { CCTK_VInfo (CCTK_THORNSTRING, "IOFlexIO_TriggerOutput: " "name, index = %s, %d", varname, vindex); } /* do the output */ retval = IOFlexIO_Write (GH, vindex, varname); if (retval == 0) { /* register variable as having output this iteration */ myGH = CCTK_GHExtension (GH, "IOFlexIO"); myGH->out_last[vindex] = GH->cctk_iteration; } return (retval); } /*@@ @routine IOFlexIO_CheckSteerableParameters @date Mon Oct 10 2000 @author Thomas Radke @desc Checks if IOFlexIO steerable parameters were changed and does appropriate re-evaluation. @enddesc @calls IOUtil_ParseVarsForOutput @var GH @vdesc pointer to CCTK GH @vtype const cGH * @vio in @endvar @var myGH @vdesc pointer to IOFlexIO GH @vtype flexioGH * @vio inout @endvar @@*/ void IOFlexIO_CheckSteerableParameters (const cGH *GH, flexioGH *myGH) { int i, vindex, num_vars; char *fullname, *msg; DECLARE_CCTK_PARAMETERS /* how often to output */ i = myGH->out_every_default; myGH->out_every_default = out_every >= 0 ? out_every : io_out_every; /* report if frequency changed */ if (myGH->out_every_default != i && ! CCTK_Equals (verbose, "none")) { if (myGH->out_every_default > 0) { CCTK_VInfo (CCTK_THORNSTRING, "Periodic IOFlexIO output every %d " "iterations", myGH->out_every_default); } else { CCTK_INFO ("Periodic IOFlexIO output turned off"); } } /* re-parse the 'IOFlexIO::out_vars' parameter if it was changed */ if (strcmp (out_vars, myGH->out_vars) || myGH->out_every_default != i) { IOUtil_ParseVarsForOutput (GH, CCTK_THORNSTRING, "IOFlexIO::out_vars", myGH->stop_on_parse_errors, out_vars, myGH->out_every_default, -1.0, myGH->requests); /*** FIXME: IEEEIO doesn't provide a COMPLEX datatype so we should map CCTK_COMPLEX to two REALs here. We have to check for this already here because if an IEEEIO file is created and nothing is written to it, it will crash at re-opening. ***/ num_vars = CCTK_NumVars (); for (vindex = 0; vindex < num_vars; vindex++) { if (myGH->requests[vindex] && strncmp (CCTK_VarTypeName (CCTK_VarTypeI (vindex)), "CCTK_VARIABLE_COMPLEX", 21) == 0) { fullname = CCTK_FullName (vindex); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "IOFlexIO output for complex variable '%s' not yet " "supported", fullname); free (fullname); IOUtil_FreeIORequest (&myGH->requests[vindex]); } } if (myGH->out_every_default == i || ! CCTK_Equals (verbose, "none")) { msg = NULL; for (vindex = 0; vindex < num_vars; vindex++) { if (myGH->requests[vindex]) { fullname = CCTK_FullName (vindex); if (! msg) { Util_asprintf (&msg, "Periodic IOFlexIO output requested for '%s'", fullname); } else { char *tmp = msg; Util_asprintf (&msg, "%s, '%s'", msg, fullname); free (tmp); } free (fullname); } } if (msg) { CCTK_INFO (msg); free (msg); } } /* save the last setting of 'IOFlexIO::out_vars' parameter */ free (myGH->out_vars); myGH->out_vars = strdup (out_vars); } }