commit 7502c4a90dc8c6fd338746fbc7df8b442771c85c
parent b61839e419d9bdc180c82d31b058a9d6f6c839b7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 21 Nov 2016 16:01:52 +0100
Handle precision issues
If a geometry inconsistency is detected during a realisation, reject up
to MAX_FAILURES random walks before an error occurs.
Diffstat:
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/src/sgf_estimator.c b/src/sgf_estimator.c
@@ -27,6 +27,11 @@
#include <rsys/mem_allocator.h>
#include <rsys/ref_count.h>
+/* A random walk may fail du to numerical inaccuracy. The following constant
+ * empirically defines the maximum number of "random walk" attempts before an
+ * error occurs. */
+#define MAX_FAILURES 10
+
/* Generate the accum dynamic array data type */
#define DARRAY_NAME accum
#define DARRAY_DATA struct accum
@@ -243,9 +248,22 @@ sgf_integrate
}
FOR_EACH(istep, 0, steps_count) {
- res = gebhart_radiative_path(scn->dev, accums, accum_infinity,
- accum_medium, rng, &path, ka, iband, iprim, scn);
- if(res != RES_OK) goto error;
+ size_t nfailures = 0;
+ do {
+ res = gebhart_radiative_path(scn->dev, accums, accum_infinity,
+ accum_medium, rng, &path, ka, iband, iprim, scn);
+ if(res == RES_BAD_OP) {
+ log_error(scn->dev, "%s: reject radiative random walk.\n", FUNC_NAME);
+ ++nfailures;
+ } else if(res != RES_OK) {
+ goto error;
+ }
+ } while(res != RES_OK && nfailures < MAX_FAILURES);
+
+ if(++nfailures > MAX_FAILURES) {
+ log_error(scn->dev, "%s: too many numerical issues.\n", FUNC_NAME);
+ goto error;
+ }
}
}
estimator->nsteps = steps_count;
diff --git a/src/sgf_realisation.h b/src/sgf_realisation.h
@@ -272,8 +272,11 @@ GEBHART_RADIATIVE_PATH
if(absorption_coef >= 0) {
if(SXD_HIT_NONE(&hit)) { /* The ray shoulnd't be outside the volume */
log_error(dev,
-"The radiative random walk goes to the infinity while the submitted geometry "
-"should surround a close medium. Ray origin: %g, %g, %g\n", SPLIT3(pos));
+"The radiative random walk goes to the infinity while the submitted geometry \n"
+"should surround a close medium. This may be due to numerical issues or to an\n"
+"invalid geometry definition.\n"
+"Ray origin: %g, %g, %g\n",
+ SPLIT3(pos));
return RES_BAD_OP;
} else {
double weight, ka;