/*@@ @file OutputInfo.c @date June 31 1999 @author Gabrielle Allen @desc Functions to deal with info output of variables @enddesc @version $Header$ @@*/ #include #include #include #include #include "cctk.h" #include "cctk_Parameters.h" #include "iobasicGH.h" /* the rcs ID and its dummy function to use it */ static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusBase_IOBasic_OutputInfo_c) /* uncomment the following to get some debugging output */ /* #define IO_DEBUG 1 */ /* the number at which to switch from decimal to exp notation */ #define DECIMAL_PRECISION 1.0e-8 #define DECIMAL_TOOBIG 1.0e+8 #define USE_DECIMAL_NOTATION(x) ((fabs (x) > DECIMAL_PRECISION) || \ ((x) == 0.0) || \ (fabs(x) < DECIMAL_TOOBIG)) /* prototypes of routines defined in this source file */ int IOBasic_OutputInfoGH (cGH *GH); int IOBasic_TimeForInfo (cGH *GH, int vindex); int IOBasic_TriggerOutputInfo (cGH *GH, int vindex); static void SetOutputFlag (int vindex, const char *optstring, void *arg); /* static variables */ static int print_header = 1; static int outInfo_vars_lastset = -1; /*@@ @routine IOBasic_OutputInfoGH @date June 31 1999 @author Gabrielle Allen @desc Loops over all variables and prints output if requested @enddesc @calls CCTK_GHExtension CCTK_ParameterQueryTimesSet CCTK_TraverseString CCTK_NumVars CCTK_VarName IOBasic_WriteInfo @var GH @vdesc Pointer to CCTK GH @vtype cGH * @vio in @endvar @returntype int @returndesc 0 for success @endreturndesc @@*/ int IOBasic_OutputInfoGH (cGH *GH) { DECLARE_CCTK_PARAMETERS int i; int ierr1; int ierr2; int times_set; const char *vname; iobasicGH *myGH; char ll[80], l1[1024], l2[1024], l3[1024]; /* Get the GH extensions for IOBasic */ myGH = (iobasicGH *) CCTK_GHExtension (GH, "IOBasic"); /* How often to output */ myGH->outInfo_every = out_every > 0 ? out_every : -1; if (outInfo_every > 0) { myGH->outInfo_every = outInfo_every; } /* Return if no output is required */ if (myGH->outInfo_every < 1 || GH->cctk_iteration % myGH->outInfo_every != 0) { return (0); } /* re-parse the 'outInfo_vars' parameter if it was changed and also print a header */ times_set = CCTK_ParameterQueryTimesSet ("outInfo_vars", CCTK_THORNSTRING); if (times_set != outInfo_vars_lastset) { memset (myGH->do_outInfo, 0, CCTK_NumVars ()); CCTK_TraverseString (outInfo_vars, SetOutputFlag, myGH->do_outInfo, CCTK_GROUP_OR_VAR); /* Save the last setting of 'outInfo_vars' parameter */ outInfo_vars_lastset = times_set; print_header = 1; } if (print_header) { print_header = 0; sprintf (l1," it | |"); sprintf (l2," | t |"); sprintf (l3,"----------------"); for (i = 0; i < CCTK_NumVars (); i++) { if (myGH->do_outInfo[i]) { sprintf (ll, " "); ll[25 - strlen (CCTK_VarName (i))] = '\0'; sprintf (l1, "%s %s%s |", l1, CCTK_VarName (i), ll); sprintf (l2, "%s Min Max |", l2); sprintf (l3, "%s----------------------------", l3); } } printf ("%s\n%s\n%s\n%s\n", l3, l1, l2, l3); fflush (stdout); } /* Print the iteration/timestep information for all variables */ if (USE_DECIMAL_NOTATION (GH->cctk_time)) { printf ("%4d |%9.3f|", GH->cctk_iteration, GH->cctk_time); } else { printf ("%4d |%7.3e|", GH->cctk_iteration, GH->cctk_time); } /* Loop over all variables */ for (i = 0; i < CCTK_NumVars (); i++) { /* Check this Variable should be output */ if (! myGH->do_outInfo[i]) { continue; } ierr1 = ierr2 = 0; /* Check variable not already output this iteration */ if (myGH->outInfo_last[i] != GH->cctk_iteration) { /* Get the variable name for this index (for filename) */ vname = CCTK_VarName (i); #ifdef IO_DEBUG printf("\nIn IO OutputInfoGH\n----------------\n"); printf(" Index = %d\n", i); printf(" Variable = -%s-\n", vname); printf(" Last output iteration was = %d\n", myGH->outInfo_last[i]); #endif /* Make the IO call */ ierr1 = IOBasic_WriteInfo (GH, &myGH->infovals[i][0], i, "minimum",vname); ierr2 = IOBasic_WriteInfo (GH, &myGH->infovals[i][1], i, "maximum",vname); /* Register GF as having info output this iteration */ myGH->outInfo_last[i] = GH->cctk_iteration; } if (ierr1 == 0) { /* finally print out the stuff */ if (USE_DECIMAL_NOTATION (myGH->infovals[i][0])) { printf ("%12.8f |", myGH->infovals[i][0]); } else { printf ("%10.6e |", myGH->infovals[i][0]); } } else { printf(" ----------- |"); } if (ierr2 == 0) { if (USE_DECIMAL_NOTATION (myGH->infovals[i][1])) { printf ("%12.8f |", myGH->infovals[i][1]); } else { printf ("%10.6e |", myGH->infovals[i][1]); } } else { printf(" ----------- |"); } } /* end of loop over all variables */ /* Add the new line */ printf ("\n"); fflush(stdout); return (0); } /*@@ @routine IOBasic_TimeForInfo @date June 31 1999 @author Gabrielle Allen @desc Decides if it is time to output a variable using info output @enddesc @calls CCTK_GHExtensionHandle CCTK_GroupTypeFromVarI CCTK_WARN CCTK_QueryGroupStorageI CCTK_GroupFromVar @var GH @vdesc Pointer to CCTK GH @vtype cGH * @vio in @endvar @var vindex @vdesc index of variable to output @vtype int @vio in @endvar @returntype int @returndesc true/false (1 or 0) if this variable should be output or not @endreturndesc @@*/ int IOBasic_TimeForInfo (cGH *GH, int vindex) { DECLARE_CCTK_PARAMETERS int retval; int times_set; iobasicGH *myGH; char *fullname; /* Default is do not do output */ retval = 0; /* Get the GH extensions for IOBasic */ myGH = (iobasicGH *) CCTK_GHExtension (GH, "IOBasic"); /* How often to output */ myGH->outInfo_every = out_every > 0 ? out_every : -1; if (outInfo_every > 0) { myGH->outInfo_every = outInfo_every; } /* return if no output requested */ if (myGH->outInfo_every <= 0) { return (0); } /* re-parse the 'outInfo_vars' parameter if it was changed and also print a header */ times_set = CCTK_ParameterQueryTimesSet ("outInfo_vars", CCTK_THORNSTRING); if (times_set != outInfo_vars_lastset) { memset (myGH->do_outInfo, 0, CCTK_NumVars ()); CCTK_TraverseString (outInfo_vars, SetOutputFlag, myGH->do_outInfo, CCTK_GROUP_OR_VAR); /* Save the last setting of 'outInfo_vars' parameter */ outInfo_vars_lastset = times_set; print_header = 1; } /* Check if this variable should be output */ if (myGH->do_outInfo[vindex] && (GH->cctk_iteration % myGH->outInfo_every == 0)) { /* Check GF not already output this iteration */ if (myGH->outInfo_last[vindex] == GH->cctk_iteration) { fullname = CCTK_FullName (vindex); CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, "Already done Info output for '%s' in current " "iteration (probably via triggers)", fullname); free (fullname); } else { retval = 1; } } return (retval); } /*@@ @routine IOBasic_TriggerOutputInfo @date June 31 1999 @author Gabrielle Allen @desc Triggers the output of a variable using IOBasic's info output @enddesc @calls CCTK_GHExtensionHandle IOBasic_WriteInfo @var GH @vdesc Pointer to CCTK GH @vtype cGH * @vio in @endvar @var vindex @vdesc index of variable to output @vtype int @vio in @endvar @returntype int @returndesc 0 for success @endreturndesc @@*/ int IOBasic_TriggerOutputInfo (cGH *GH, int vindex) { iobasicGH *myGH; const char *vname; /* Get the GH extension for IOBasic */ myGH = (iobasicGH *) CCTK_GHExtension (GH, "IOBasic"); vname = CCTK_VarName (vindex); /* Do the Info output */ #ifdef IO_DEBUG printf ("\nIn IO TriggerOutputInfo\n---------------------\n"); printf (" Index = %d\n", vindex); printf (" Variable = -%s-\n", vname); #endif IOBasic_WriteInfo (GH, &myGH->infovals[vindex][0], vindex, "minimum", vname); IOBasic_WriteInfo (GH, &myGH->infovals[vindex][1], vindex, "maximum", vname); /* Register variable as having Info output at this iteration */ myGH->outInfo_last[vindex] = GH->cctk_iteration; return (0); } /***************************************************************************/ /* local functions */ /***************************************************************************/ /* callback for CCTK_TraverseString() to set the output flag for the given variable */ static void SetOutputFlag (int vindex, const char *optstring, void *arg) { char *flags = (char *) arg; flags[vindex] = 1; if (optstring) { CCTK_VWarn (5, __LINE__, __FILE__, CCTK_THORNSTRING, "Optional string '%s' in variable name ignored", optstring); } }