aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortradke <tradke@ff385933-4943-42dc-877b-ffc776028de6>2003-06-12 09:24:40 +0000
committertradke <tradke@ff385933-4943-42dc-877b-ffc776028de6>2003-06-12 09:24:40 +0000
commit74bbad1a068191bdc4b1c6bd792eb0f8c9716d58 (patch)
tree92a1f055bdb3a81fd4be68c0decf7aa56ed78e13 /src
parent4348d097c65b8dc034203603407b557096633807 (diff)
Added an integer grid function NaNChecker::NaNmask which is used as a bitmask
to mark locations of NaNs found in grid functions. The mask is output as an HDF5 file and can then be visualized in OpenDX. Setting the mask and outputting it is activated by default. It can be switched off with NaNChecker::out_NaNmask = "no". git-svn-id: http://svn.cactuscode.org/arrangements/CactusUtils/NaNChecker/trunk@39 ff385933-4943-42dc-877b-ffc776028de6
Diffstat (limited to 'src')
-rw-r--r--src/NaNCheck.c216
1 files changed, 155 insertions, 61 deletions
diff --git a/src/NaNCheck.c b/src/NaNCheck.c
index c1176a0..4368143 100644
--- a/src/NaNCheck.c
+++ b/src/NaNCheck.c
@@ -53,7 +53,7 @@ void CCTK_FCALL CCTK_FNAME (NaNChecker_SetVarsToNaN)
static void CheckForNaN (int vindex, const char *optstring, void *arg);
static void SetToNaN (int vindex, const char *optstring, void *arg);
static void PrintWarning (const char *error_type,
- int verbose,
+ int verbose,
int linear_index,
int fp_type,
const CCTK_REAL *const coords[],
@@ -70,12 +70,20 @@ typedef struct
int report_max;
const char *action_if_found;
int count;
+ CCTK_INT *NaNmask;
+ int bitmask;
#ifdef HAVE_FINITE
enum {CHECK_FOR_NAN = 0, CHECK_FOR_INF = 1, CHECK_FOR_BOTH = 2} check_for;
#endif
} t_nanchecker_info;
+/********************************************************************
+ ******************** Static Variables ************************
+ ********************************************************************/
+static int last_iteration_output = -1;
+
+
/*@@
@routine NaNChecker_NaNCheck
@author Thomas Radke
@@ -101,44 +109,87 @@ typedef struct
@@*/
int NaNChecker_NaNCheck (const cGH *GH)
{
- int retval;
+ int i, nelems, retval;
+ const char *method;
t_nanchecker_info info;
DECLARE_CCTK_PARAMETERS
- if (GH->cctk_iteration % check_every == 0)
+ if (GH->cctk_iteration % check_every)
{
- info.GH = GH;
- info.report_max = report_max;
- info.action_if_found = action_if_found;
- if (CCTK_EQUALS(verbose,"all"))
- {
- info.verbose = 1;
- }
- else
+ return (0);
+ }
+ if (GH->cctk_iteration == last_iteration_output)
+ {
+ CCTK_WARN (2, "Already called NaNChecker I/O method at this iteration");
+ return (0);
+ }
+
+ info.GH = GH;
+ info.count = 0;
+ info.bitmask = 0;
+ info.report_max = report_max;
+ info.action_if_found = action_if_found;
+ info.verbose = CCTK_Equals (verbose, "all");
+
+ info.NaNmask = out_NaNmask ?
+ CCTK_VarDataPtr (GH, 0, "NaNChecker::NaNmask") : NULL;
+ if (info.NaNmask)
+ {
+ /* zero out the NaN mask */
+ for (i = 0, nelems = 1; i < GH->cctk_dim; i++)
{
- info.verbose = 0;
+ nelems *= GH->cctk_lsh[i];
}
+ memset (info.NaNmask, 0, nelems * sizeof (CCTK_INT));
+ }
+
#ifdef HAVE_FINITE
- if (CCTK_Equals (check_for, "NaN"))
+ if (CCTK_Equals (check_for, "NaN"))
+ {
+ info.check_for = CHECK_FOR_NAN;
+ }
+ else if (CCTK_Equals (check_for, "Inf"))
+ {
+ info.check_for = CHECK_FOR_INF;
+ }
+ else
+ {
+ info.check_for = CHECK_FOR_BOTH;
+ }
+#endif
+
+ retval = CCTK_TraverseString (check_vars, CheckForNaN, &info,
+ CCTK_GROUP_OR_VAR);
+
+ /* save the iteration of the last call */
+ last_iteration_output = GH->cctk_iteration;
+
+ if (info.count > 0)
+ {
+ /* if NaNs were found then output NaN mask with the 'IOHDF5' I/O method */
+ if (info.NaNmask && info.bitmask)
{
- info.check_for = CHECK_FOR_NAN;
+ if (info.verbose)
+ {
+ CCTK_INFO ("Write out NaN mask using the 'IOHDF5' I/O method");
+ }
+ CCTK_OutputVarAsByMethod (GH, "NaNChecker::NaNmask[downsample={1 1 1}]",
+ "IOHDF5", "NaNmask");
}
- else if (CCTK_Equals (check_for, "Inf"))
+
+ if (CCTK_Equals (info.action_if_found, "terminate"))
{
- info.check_for = CHECK_FOR_INF;
+ CCTK_WARN (1, "'action_if_found' parameter is set to 'terminate' - "
+ "scheduling graceful termination of Cactus");
+ CCTK_TerminateNext (NULL);
}
- else
+ else if (CCTK_Equals (info.action_if_found, "abort"))
{
- info.check_for = CHECK_FOR_BOTH;
+ CCTK_WARN (1, "'action_if_found' parameter is set to 'abort' - "
+ "aborting Cactus now");
+ CCTK_Abort (NULL, 0);
}
-#endif
- retval = CCTK_TraverseString (check_vars, CheckForNaN, &info,
- CCTK_GROUP_OR_VAR);
- }
- else
- {
- retval = 0;
}
return (retval);
@@ -191,8 +242,9 @@ int NaNChecker_NaNCheck (const cGH *GH)
@returndesc
the total number of NaN values found, or<BR>
-1 if a NULL pointer was passed for 'GH' and/or 'vars',<BR>
- -2 if an unknow keyword was passed in 'action_if_found',<BR>
- -3 if the 'vars' string couldn't be parsed
+ -2 if NaNChecker was already called at this iteration,<BR>
+ -3 if an unknow keyword was passed in 'action_if_found',<BR>
+ -4 if the 'vars' string couldn't be parsed
@endreturndesc
@@*/
int NaNChecker_CheckVarsForNaN (const cGH *GH,
@@ -208,6 +260,11 @@ int NaNChecker_CheckVarsForNaN (const cGH *GH,
{
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
"NULL pointer passed for 'GH' and/or 'vars' argument");
+ return (-2);
+ }
+ if (GH->cctk_iteration == last_iteration_output)
+ {
+ CCTK_WARN (2, "Already called NaNChecker I/O method at this iteration");
return (-1);
}
@@ -218,13 +275,16 @@ int NaNChecker_CheckVarsForNaN (const cGH *GH,
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
"Unknown keyword '%s' for 'action_if_found' argument",
action_if_found);
- return (-2);
+ return (-3);
}
info.GH = GH;
+ info.count = 0;
+ info.bitmask = 0;
+ info.verbose = 0;
info.report_max = report_max;
info.action_if_found = action_if_found;
- info.count = 0;
+
#ifdef HAVE_FINITE
if (CCTK_Equals (check_for, "NaN"))
{
@@ -245,11 +305,42 @@ int NaNChecker_CheckVarsForNaN (const cGH *GH,
info.check_for = CHECK_FOR_BOTH;
}
#endif
+
if (CCTK_TraverseString (vars, CheckForNaN, &info, CCTK_GROUP_OR_VAR) < 0)
{
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
"Couldn't traverse 'vars' string '%s'", vars);
- return (-3);
+ return (-4);
+ }
+
+ /* save the iteration of the last call */
+ last_iteration_output = GH->cctk_iteration;
+
+ if (info.count > 0)
+ {
+ /* if NaNs were found then output NaN mask with the 'IOHDF5' I/O method */
+ if (info.NaNmask && info.bitmask)
+ {
+ if (info.verbose)
+ {
+ CCTK_INFO ("Write out NaN mask using the 'IOHDF5' I/O method");
+ }
+ CCTK_OutputVarAsByMethod (GH, "NaNChecker::NaNmask[downsample={1 1 1}]",
+ "IOHDF5", "NaNmask");
+ }
+
+ if (CCTK_Equals (info.action_if_found, "terminate"))
+ {
+ CCTK_WARN (1, "'action_if_found' parameter is set to 'terminate' - "
+ "scheduling graceful termination of Cactus");
+ CCTK_TerminateNext (NULL);
+ }
+ else if (CCTK_Equals (info.action_if_found, "abort"))
+ {
+ CCTK_WARN (1, "'action_if_found' parameter is set to 'abort' - "
+ "aborting Cactus now");
+ CCTK_Abort (NULL, 0);
+ }
}
return (info.count);
@@ -389,7 +480,7 @@ void CCTK_FCALL CCTK_FNAME (NaNChecker_SetVarsToNaN)
@endvar
@@*/
static void PrintWarning (const char *error_type,
- int verbose,
+ int verbose,
int linear_index,
int fp_type,
const CCTK_REAL *const coords[],
@@ -422,7 +513,7 @@ static void PrintWarning (const char *error_type,
{
/* assume max. 10 characters per index number and 40 characters per
coordinate value (including separators) */
- index_string = (char *) malloc (5 * 10 * gdata->dim);
+ index_string = malloc (5 * 10 * gdata->dim);
coord_string = index_string + 10 * gdata->dim;
amended_index = linear_index;
@@ -440,7 +531,7 @@ static void PrintWarning (const char *error_type,
(amended_index % gdata->lsh[i]) + gdata->lbnd[i] + 1);
if (coords)
{
- sprintf (coord_string, "%s, %5.3e", coord_string,
+ sprintf (coord_string, "%s, %5.3e", coord_string,
(double) coords[i][linear_index]);
}
}
@@ -449,16 +540,16 @@ static void PrintWarning (const char *error_type,
{
if (coords)
{
- CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
- "%s caught in %svariable '%s' at index (%s) with coordinates "
- "(%s)", error_type, complex_part, fullname, index_string,
- coord_string);
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "%s caught in %svariable '%s' at index (%s) with coordinates "
+ "(%s)", error_type, complex_part, fullname, index_string,
+ coord_string);
}
else
{
- CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
- "%s caught in %svariable '%s' at (%s)",
- error_type, complex_part, fullname, index_string);
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "%s caught in %svariable '%s' at (%s)",
+ error_type, complex_part, fullname, index_string);
}
free (index_string);
@@ -503,7 +594,11 @@ static void PrintWarning (const char *error_type,
(info->report_max < 0 || nans_found <= info->report_max)) \
{ \
PrintWarning (isnan ((double) _data[_i]) ? "NaN" : "Inf", \
- info->verbose, _i, fp_type, coords, fullname, &gdata); \
+ info->verbose, _i, fp_type, coords, fullname, &gdata); \
+ } \
+ if (info->NaNmask && gtype == CCTK_GF) \
+ { \
+ info->NaNmask[_i] |= 1 << info->bitmask; \
} \
} \
} \
@@ -529,6 +624,10 @@ static void PrintWarning (const char *error_type,
PrintWarning ("NaN", info->verbose, _i, fp_type, coords, fullname, \
&gdata); \
} \
+ if (info->NaNmask) \
+ { \
+ info->NaNmask[_i] |= 1 << info->bitmask; \
+ } \
} \
} \
}
@@ -580,7 +679,7 @@ static void CheckForNaN (int vindex, const char *optstring, void *_info)
const void *data;
- info = (t_nanchecker_info *) _info;
+ info = _info;
vtype = CCTK_VarTypeI (vindex);
fullname = CCTK_FullName (vindex);
@@ -657,8 +756,7 @@ static void CheckForNaN (int vindex, const char *optstring, void *_info)
sprintf (coord_system_name, "cart%dd", gdata.dim);
if (CCTK_CoordSystemHandle (coord_system_name) >= 0)
{
- coords = (const CCTK_REAL **)
- malloc (gdata.dim * sizeof (const CCTK_REAL *));
+ coords = malloc (gdata.dim * sizeof (const CCTK_REAL *));
}
}
for (i = 0; i < gdata.dim; i++)
@@ -668,7 +766,7 @@ static void CheckForNaN (int vindex, const char *optstring, void *_info)
{
coords[i] = (const CCTK_REAL *) CCTK_VarDataPtrI (info->GH, 0,
CCTK_CoordIndex (i + 1, NULL, coord_system_name));
- if (! coords[i])
+ if (! coords[i])
{
free (coords);
coords = NULL;
@@ -712,31 +810,27 @@ static void CheckForNaN (int vindex, const char *optstring, void *_info)
}
/* Do more than just print a warning ? */
- if (nans_found > 0 && info->action_if_found)
+ if (nans_found > 0 && info->action_if_found && gdata.dim > 0)
{
- if (gdata.dim > 0)
- {
- CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "There were %d NaN/Inf value(s) found in variable '%s'",
- nans_found, fullname);
- }
-
- if (CCTK_Equals (info->action_if_found, "terminate"))
+ if (info->NaNmask && gtype == CCTK_GF)
{
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "\"action_if_found\" parameter is set to \"terminate\" - "
- "scheduling graceful termination of Cactus");
- CCTK_TerminateNext (NULL);
+ "There were %d NaN/Inf value(s) found in variable '%s' "
+ "(NaNmask bitfield %d)",
+ nans_found, fullname, info->bitmask);
}
- else if (CCTK_Equals (info->action_if_found, "abort"))
+ else
{
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "\"action_if_found\" parameter is set to \"abort\" - "
- "aborting Cactus now");
- CCTK_Abort (NULL, 0);
+ "There were %d NaN/Inf value(s) found in variable '%s'",
+ nans_found, fullname);
}
}
info->count += nans_found;
+ if (gtype == CCTK_GF)
+ {
+ info->bitmask++;
+ }
if (coords)
{