/*@@ @file Output2D.c @date Tue Jan 9 1999 @author Gabrielle Allen @desc Functions to deal with output of 2D planes of grid variables. @enddesc @version $Id$ @@*/ #include #include #include "cctk.h" #include "cctk_Parameters.h" #include "util_String.h" #include "ioFlexGH.h" static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusPUGHIO_IOFlexIO_Output2D_c) /* prototypes of routines defined in this source file */ static int CheckOutputVar (int vindex, int warn); static void SetOutputFlag (int vindex, const char *optstring, void *arg); /*@@ @routine IOFlexIO_Output2DGH @date Sat March 6 1999 @author Gabrielle Allen @desc Loops over all variables and outputs them if necessary @enddesc @calledby CCTK_OutputGH ("IOFlexIO_2D") @history @endhistory @var GH @vdesc Pointer to CCTK GH @vtype const cGH * @vio in @vcomment @endvar @@*/ int IOFlexIO_Output2DGH (const cGH *GH) { int vindex, retval; const flexioGH *myGH; retval = 0; myGH = (const flexioGH *) CCTK_GHExtension (GH, "IOFlexIO"); /* loop over all variables */ for (vindex = CCTK_NumVars () - 1; vindex >= 0; vindex--) { if (IOFlexIO_TimeFor2D (GH, vindex) && CheckOutputVar (vindex, 0) && IOFlexIO_Write2D (GH, vindex, CCTK_VarName (vindex)) == 0) { /* register variable as having 2D output this iteration */ myGH->out2D_last[vindex] = GH->cctk_iteration; retval++; } } return (retval); } /*@@ @routine IOFlexIO_Output2DVarAs @date Sat March 6 1999 @author Gabrielle Allen @desc unconditional output of a variable using the IO 2D output method @enddesc @calledby IOFlexIO_Output2DGH, CCTK_OutputVarAsByMethod ("IOFlexIO_2D") @history @endhistory @var GH @vdesc Pointer to CCTK GH @vtype const cGH * @vio in @vcomment @endvar @var fullname @vdesc complete name of variable to output @vtype const char * @vio in @vcomment @endvar @var alias @vdesc alias name of variable to output (used to generate output filename) @vtype const char * @vio in @vcomment @endvar @@*/ int IOFlexIO_Output2DVarAs (const cGH *GH, const char *fullname, const char *alias) { int vindex, retval; DECLARE_CCTK_PARAMETERS vindex = CCTK_VarIndex (fullname); if (CCTK_Equals (verbose, "full")) { CCTK_VInfo (CCTK_THORNSTRING, "IOFlexIO_Output2DVarAs: " "fullname, alias, index = (%s, %s, %d)", fullname,alias,vindex); } /* do the 2D output */ retval = -1; if (CheckOutputVar (vindex, 1)) { retval = IOFlexIO_Write2D (GH, vindex, alias); } return (retval); } /*@@ @routine IOFlexIO_TimeFor2D @date Sat March 6 1999 @author Gabrielle Allen @desc Decides if it is time to output a variable using the IO 2D output method @enddesc @calledby IOFlexIO_Output2DGH @history @endhistory @var GH @vdesc Pointer to CCTK GH @vtype const cGH * @vio in @vcomment @endvar @var vindex @vdesc index of variable @vtype int @vio in @vcomment @endvar @@*/ int IOFlexIO_TimeFor2D (const cGH *GH, int vindex) { int result; char *fullname; flexioGH *myGH; /* default is not do any output */ result = 0; myGH = (flexioGH *) CCTK_GHExtension (GH, "IOFlexIO"); IOFlexIO_CheckSteerableParameters2D (myGH); /* check if this variable should be output */ if (myGH->out2D_every[vindex] > 0 && GH->cctk_iteration % myGH->out2D_every[vindex] == 0) { /* check if variable wasn't already output this iteration */ if (myGH->out2D_last [vindex] == GH->cctk_iteration) { fullname = CCTK_FullName (vindex); CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, "Already done 2D FlexIO output for variable '%s' in current " "iteration (probably via triggers)", fullname); free (fullname); } else { result = 1; } } return (result); } /*@@ @routine IOFlexIO_TriggerOutput2D @date Sat March 6 1999 @author Gabrielle Allen @desc Triggers the output a variable using the IO 2D output method @enddesc @calledby CCTK scheduler @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 @@*/ int IOFlexIO_TriggerOutput2D (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_TriggerOutput2D: " "name, index = (%s, %d)", varname, vindex); } /* do the 2D output */ retval = IOFlexIO_Write2D (GH, vindex, varname); if (retval == 0) { /* register variable as having 2D output this iteration */ myGH = (const flexioGH *) CCTK_GHExtension (GH, "IOFlexIO"); myGH->out2D_last [vindex] = GH->cctk_iteration; } return (retval); } /*@@ @routine IOFlexIO_CheckSteerableParameters2D @date Tue 8 June 2004 @author Thomas Radke @desc Check if steerable IOFlexIO 2D parameters have changed @enddesc @calls CCTK_TraverseString @var myGH @vdesc Pointer to IOFlexIO GH @vtype flexioGH * @vio inout @endvar @@*/ void IOFlexIO_CheckSteerableParameters2D (flexioGH *myGH) { int i, num_vars; char *fullname, *msg; DECLARE_CCTK_PARAMETERS /* how often to output */ i = myGH->out2D_every_default; myGH->out2D_every_default = out2D_every >= 0 ? out2D_every : io_out_every; /* report if frequency changed */ if (myGH->out2D_every_default != i && ! CCTK_Equals (verbose, "none")) { if (myGH->out2D_every_default > 0) { CCTK_VInfo (CCTK_THORNSTRING, "IOFlexIO_2D: Periodic output every %d " "iterations", myGH->out2D_every_default); } else { CCTK_INFO ("IOFlexIO_2D: Periodic output turned off"); } } /* re-parse the 'IOFlexIO::out2D_vars' parameter if it was changed */ if (strcmp (out2D_vars, myGH->out2D_vars) || myGH->out2D_every_default != i) { num_vars = CCTK_NumVars (); memset (myGH->out2D_every, 0, num_vars * sizeof (CCTK_INT)); if (CCTK_TraverseString (out2D_vars, SetOutputFlag, myGH, CCTK_GROUP_OR_VAR) < 0) { CCTK_WARN (myGH->stop_on_parse_errors ? 0 : 1, "error while parsing parameter 'IOFlexIO::out2D_vars'"); } if (myGH->out2D_every_default == i || ! CCTK_Equals (verbose, "none")) { msg = NULL; for (i = 0; i < num_vars; i++) { if (myGH->out2D_every[i] > 0) { fullname = CCTK_FullName (i); if (! msg) { Util_asprintf (&msg, "IOFlexIO_2D: Periodic 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::out2D_vars' parameter */ free (myGH->out2D_vars); myGH->out2D_vars = strdup (out2D_vars); } } /**************************** local functions ******************************/ /* check if this variable can be output (static conditions) */ static int CheckOutputVar (int vindex, int warn) { int retval; char *fullname; /* check the group dimension */ retval = CCTK_GroupDimFromVarI (vindex) == 3; if (! retval && warn) { fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "No IOFlexIO 2D output for '%s' (dim != 3)", fullname); free (fullname); } return (retval); } /* callback for CCTK_TraverseString() to set the output flag for the given variable */ static void SetOutputFlag (int vindex, const char *optstring, void *arg) { const flexioGH *myGH = (const flexioGH *) arg; /* check the variable type */ if (CheckOutputVar (vindex, 1)) { myGH->out2D_every[vindex] = myGH->out2D_every_default; if (optstring) { IOUtil_ParseOutputFrequency ("2D IOFlexIO", "IOFlexIO::out2D_vars", myGH->stop_on_parse_errors, vindex, optstring, &myGH->out2D_every[vindex], NULL); } } }