commit ba0cef06873f1ffa058b68f3ab9828e5389897df
parent 389933d613bfee1b7e4e0db805c6e403d6d607cb
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 17 Oct 2016 12:13:29 +0200
Handle flux absorption & upd infinite flux
The infinite radiative flux of an emissive face is computed globally.
Diffstat:
8 files changed, 271 insertions(+), 166 deletions(-)
diff --git a/src/sgf.h b/src/sgf.h
@@ -45,7 +45,8 @@ struct ssp_rng;
enum sgf_material_property {
SGF_MATERIAL_EMISSIVITY,
SGF_MATERIAL_REFLECTIVITY,
- SGF_MATERIAL_SPECULARITY
+ SGF_MATERIAL_SPECULARITY,
+ SGF_MEDIUM_ABSORPTION
};
enum sgf_dimensionality {
@@ -64,6 +65,9 @@ struct sgf_scene_desc {
void* material; /* Client side material */
size_t spectral_bands_count; /* Total number of spectral bands */
+ /* Define whether or not a medium is defined onto the scene */
+ int has_medium;
+
/* Star-3D encapsulation of the geometry */
enum sgf_dimensionality dimensionality;
union {
@@ -73,7 +77,7 @@ struct sgf_scene_desc {
};
static const struct sgf_scene_desc SGF_SCENE_DESC_NULL = {
- NULL, NULL, 0, SGF_3D, { NULL }
+ NULL, NULL, 0, 0, SGF_3D, { NULL }
};
/* Estimated Gebart Factor between 2 faces */
@@ -142,7 +146,13 @@ sgf_estimator_get_status
SGF_API res_T
sgf_estimator_get_status_infinity
(struct sgf_estimator* estimator,
- const size_t primitive_id,
+ const size_t spectral_band,
+ struct sgf_status* status);
+
+/* Return the estimated radiative flux absorbed by the medium */
+SGF_API res_T
+sgf_estimator_get_status_medium
+ (struct sgf_estimator* estimator,
const size_t spectral_band,
struct sgf_status* status);
diff --git a/src/sgf_device.c b/src/sgf_device.c
@@ -95,3 +95,22 @@ sgf_device_ref_put(struct sgf_device* dev)
return RES_OK;
}
+/*******************************************************************************
+ * Local function
+ ******************************************************************************/
+void
+log_error(struct sgf_device* dev, const char* msg, ...)
+{
+ va_list vargs;
+ res_T res; (void)res;
+ ASSERT(dev && msg);
+
+ if(!dev->verbose) return;
+
+ va_start(vargs, msg);
+ res = logger_vprint(dev->logger, LOG_ERROR, msg, vargs);
+ ASSERT(res == RES_OK);
+ va_end(vargs);
+}
+
+
diff --git a/src/sgf_device_c.h b/src/sgf_device_c.h
@@ -29,5 +29,18 @@ struct sgf_device {
ref_T ref;
};
+/* Conditionally log a message on the LOG_ERROR stream of the device logger,
+ * with respect to the device verbose flag */
+extern LOCAL_SYM void
+log_error
+ (struct sgf_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+
#endif /* SGF_DEVICE_C_H */
diff --git a/src/sgf_estimator.c b/src/sgf_estimator.c
@@ -27,11 +27,6 @@
#include <rsys/mem_allocator.h>
#include <rsys/ref_count.h>
-enum status_type {
- GEBHART_FACTOR,
- INFINITY_RADIATIVE_FLUX
-};
-
/* Generate the accum dynamic array data type */
#define DARRAY_NAME accum
#define DARRAY_DATA struct accum
@@ -47,8 +42,12 @@ enum status_type {
/* Estimator of the Gebhart Factor of a given face to all the other ones */
struct sgf_estimator {
- struct darray_accum buf; /* Integrated radiative flux of each primitive */
- struct darray_accum buf_infinity; /* Radiative flux going to the infinity */
+ /* Per spectral band & per primitive radiative flux */
+ struct darray_accum buf;
+ /* Per spectral band radiative flux going to the infinity */
+ struct darray_accum buf_infinity;
+ /* Per spectral band radiative flux absorbed by the medium */
+ struct darray_accum buf_medium;
size_t nsteps; /* # realisations */
size_t nprims; /* # primitives */
@@ -82,9 +81,8 @@ setup_status
ASSERT(acc && status && nsteps);
status->E = acc->radiative_flux / (double)nsteps; /* Expected value */
- status->V = /* Variance */
- acc->sqr_radiative_flux / (double)nsteps
- - (acc->radiative_flux * acc->radiative_flux) / (double)(nsteps * nsteps);
+ status->V = acc->sqr_radiative_flux / (double)nsteps - status->E*status->E;
+ status->V = MMAX(status->V, 0);
status->SE = sqrt(status->V / (double)nsteps); /* Standard error */
status->nsteps = nsteps; /* # realisations */
}
@@ -98,10 +96,8 @@ estimator_create(struct sgf_device* dev, struct sgf_estimator** out_estimator)
estimator = MEM_CALLOC(dev->allocator, 1, sizeof(struct sgf_estimator));
if(!estimator) {
- if(dev->verbose) {
- logger_print(dev->logger, LOG_ERROR,
+ log_error(dev,
"Not enough memory space: couldn't allocate the Gebhart Factor estimator.\n");
- }
res = RES_MEM_ERR;
goto error;
}
@@ -110,6 +106,7 @@ estimator_create(struct sgf_device* dev, struct sgf_estimator** out_estimator)
estimator->dev = dev;
darray_accum_init(dev->allocator, &estimator->buf);
darray_accum_init(dev->allocator, &estimator->buf_infinity);
+ darray_accum_init(dev->allocator, &estimator->buf_medium);
exit:
*out_estimator = estimator;
@@ -123,51 +120,6 @@ error:
goto exit;
}
-static res_T
-estimator_get_status
- (struct sgf_estimator* estimator,
- const enum status_type type,
- const size_t iprimitive,
- const size_t ispectral_band,
- struct sgf_status* status)
-{
- struct accum* acc;
- size_t iacc;
-
- if(!estimator || !status)
- return RES_BAD_ARG;
-
- if(iprimitive >= estimator->nprims) {
- if(estimator->dev->verbose) {
- logger_print(estimator->dev->logger, LOG_ERROR,
- "Out of bound primitive index `%lu'\n", iprimitive);
- }
- return RES_BAD_ARG;
- }
- if(ispectral_band >= estimator->nbands) {
- if(estimator->dev->verbose) {
- logger_print(estimator->dev->logger, LOG_ERROR,
- "Out of bound spectral band index `%lu'\n", ispectral_band);
- }
- return RES_BAD_ARG;
- }
-
- iacc = ispectral_band * estimator->nprims + iprimitive;
- switch(type) {
- case GEBHART_FACTOR:
- ASSERT(iacc < darray_accum_size_get(&estimator->buf));
- acc = darray_accum_data_get(&estimator->buf) + iacc;
- break;
- case INFINITY_RADIATIVE_FLUX:
- ASSERT(iacc < darray_accum_size_get(&estimator->buf_infinity));
- acc = darray_accum_data_get(&estimator->buf_infinity) + iacc;
- break;
- default: FATAL("Unreachable code\n"); break;
- }
- setup_status(acc, estimator->nsteps, status);
- return RES_OK;
-}
-
static void
estimator_release(ref_T* ref)
{
@@ -177,6 +129,7 @@ estimator_release(ref_T* ref)
estimator = CONTAINER_OF(ref, struct sgf_estimator, ref);
darray_accum_release(&estimator->buf);
darray_accum_release(&estimator->buf_infinity);
+ darray_accum_release(&estimator->buf_medium);
dev = estimator->dev;
MEM_RM(dev->allocator, estimator);
SGF(device_ref_put(dev));
@@ -189,7 +142,7 @@ res_T
sgf_integrate
(struct sgf_device* dev,
struct ssp_rng* rng,
- const size_t primitive_id,
+ const size_t iprim,
struct sgf_scene_desc* desc,
const size_t steps_count,
struct sgf_estimator** out_estimator)
@@ -198,7 +151,7 @@ sgf_integrate
#define SXD_ENUM(Enum) (desc->dimensionality == SGF_2D ? S2D_##Enum : S3D_##Enum)
struct sgf_estimator* estimator = NULL;
size_t istep;
- size_t ispectral_band;
+ size_t iband;
size_t nprims;
float epsilon;
float lower[3], upper[3];
@@ -231,22 +184,18 @@ sgf_integrate
/* Check scene active sessions */
SXD_FUNC(scene_get_session_mask(scene, &mask));
if(!(mask & SXD_ENUM(TRACE)) || !(mask & SXD_ENUM(GET_PRIMITIVE))) {
- if(dev->verbose) {
- logger_print(dev->logger, LOG_ERROR,
- "No active trace/get_primitive session on the Star-%dD scene\n",
- desc->dimensionality == SGF_2D ? 2 : 3);
- }
+ log_error(dev,
+ "%s: no active trace/get_primitive session on the Star-%dD scene.\n",
+ FUNC_NAME, desc->dimensionality == SGF_2D ? 2 : 3);
res = RES_BAD_ARG;
goto error;
}
/* Check submitted primitive_id */
SXD_FUNC(scene_primitives_count(scene, &nprims));
- if(primitive_id >= nprims) {
- if(dev->verbose) {
- logger_print(dev->logger, LOG_ERROR,
- "Invalid primitive index `%lu'\n", (unsigned long)primitive_id);
- }
+ if(iprim >= nprims) {
+ log_error(dev, "%s: invalid primitive index `%lu'\n",
+ FUNC_NAME, (unsigned long)iprim);
res = RES_BAD_ARG;
goto error;
}
@@ -259,63 +208,80 @@ sgf_integrate
epsilon = MMIN(epsilon, upper[2] - lower[2]);
}
if(epsilon <= 0.f) {
- if(dev->verbose) {
- logger_print(dev->logger, LOG_ERROR,"Degenerated scene geometry. ");
- switch(desc->dimensionality) {
- case SGF_2D:
- logger_print(dev->logger, LOG_ERROR,
- "lower: %g, %g; upper: %g, %g\n",
- SPLIT2(lower), SPLIT2(upper));
- break;
- case SGF_3D:
- logger_print(dev->logger, LOG_ERROR,
- "lower: %g, %g, %g; upper: %g, %g, %g\n",
- SPLIT3(lower), SPLIT3(upper));
- break;
- default: FATAL("Unreachable code\n"); break;
- }
+ log_error(dev, "%s: degenerated scene geometry. ", FUNC_NAME);
+ if(desc->dimensionality == SGF_2D) {
+ log_error(dev, "lower: %g, %g; upper: %g, %g\n",
+ SPLIT2(lower), SPLIT2(upper));
+ } else {
+ log_error(dev, "lower: %g, %g, %g; upper: %g, %g, %g\n",
+ SPLIT3(lower), SPLIT3(upper));
}
res = RES_BAD_ARG;
goto error;
}
epsilon = MMAX(epsilon*1.e-6f, FLT_MIN);
- /* Allocate and init the Gebhart Factor result buffer */
+ /* Allocate and init the accumulators of radiative flux */
res = darray_accum_resize(&estimator->buf, nprims*desc->spectral_bands_count);
if(res != RES_OK) {
- if(dev->verbose) {
- logger_print(dev->logger, LOG_ERROR,
- "Couldn't allocate the Gebhart Factor result buffer.\n");
- }
+ log_error(dev, "%s: couldn't allocate the Gebhart Factor result buffer.\n",
+ FUNC_NAME);
goto error;
}
memset(darray_accum_data_get(&estimator->buf), 0,
darray_accum_size_get(&estimator->buf)*sizeof(struct accum));
- /* Allocate and init the infinite radiative flux buffer */
- res = darray_accum_resize
- (&estimator->buf_infinity, nprims*desc->spectral_bands_count);
- if(res != RES_OK) {
- if(dev->verbose) {
- logger_print(dev->logger, LOG_ERROR,
- "Couldn't allocate the buffer of infinite radiative flux.\n");
+ if(desc->has_medium) {
+ /* Allocate and init the accumulators of absorbed radiative flux */
+ res = darray_accum_resize
+ (&estimator->buf_medium, desc->spectral_bands_count);
+ if(res != RES_OK) {
+ log_error(dev,
+"%s: couldn't allocate the accumulators of the per spectral radiative flux "
+"absorbed by the medium.\n", FUNC_NAME);
+ goto error;
}
- goto error;
+ memset(darray_accum_data_get(&estimator->buf_medium), 0,
+ darray_accum_size_get(&estimator->buf_medium)*sizeof(struct accum));
+ } else {
+ /* Allocate and init the accumulators of infinite radiative flux */
+ res = darray_accum_resize
+ (&estimator->buf_infinity, desc->spectral_bands_count);
+ if(res != RES_OK) {
+ log_error(dev,
+"%s: couldn't allocate the accumulators of the per spectral band radiative flux"
+" that goes to the infinite.\n", FUNC_NAME);
+ goto error;
+ }
+ memset(darray_accum_data_get(&estimator->buf_infinity), 0,
+ darray_accum_size_get(&estimator->buf_infinity)*sizeof(struct accum));
}
- memset(darray_accum_data_get(&estimator->buf_infinity), 0,
- darray_accum_size_get(&estimator->buf_infinity)*sizeof(struct accum));
-
/* Invoke the Gebhart factor integration. */
- FOR_EACH(ispectral_band, 0, desc->spectral_bands_count) {
- struct accum* accums =
- darray_accum_data_get(&estimator->buf) + ispectral_band * nprims;
- struct accum* accums_infinity =
- darray_accum_data_get(&estimator->buf_infinity) + ispectral_band * nprims;
+ FOR_EACH(iband, 0, desc->spectral_bands_count) {
+ struct accum* accums = NULL;
+ struct accum* accum_infinity = NULL;
+ struct accum* accum_medium = NULL;
+ double ka = -1; /* Absorption coefficient of the medium */
+
+ accums = darray_accum_data_get(&estimator->buf) + iband * nprims;
+ if(!desc->has_medium) {
+ accum_infinity = darray_accum_data_get(&estimator->buf_infinity) + iband;
+ } else {
+ accum_medium = darray_accum_data_get(&estimator->buf_medium) + iband;
+ ka = desc->get_material_property
+ (desc->material, SGF_MEDIUM_ABSORPTION, iprim, iband);
+ if(ka < 0) {
+ log_error(dev, "%s: invalid absorption coefficient `%g'.\n",
+ FUNC_NAME, ka);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
FOR_EACH(istep, 0, steps_count) {
- res = gebhart_radiative_path
- (dev, accums, accums_infinity, rng, epsilon, primitive_id, desc);
+ res = gebhart_radiative_path(dev, accums, accum_infinity, accum_medium,
+ rng, ka, iband, epsilon, iprim, desc);
if(res != RES_OK) goto error;
}
}
@@ -353,22 +319,83 @@ sgf_estimator_ref_put(struct sgf_estimator* estimator)
res_T
sgf_estimator_get_status
(struct sgf_estimator* estimator,
- const size_t iprimitive,
- const size_t ispectral_band,
+ const size_t iprim,
+ const size_t iband,
struct sgf_status* status)
{
- return estimator_get_status
- (estimator, GEBHART_FACTOR, iprimitive, ispectral_band, status);
+ const struct accum* acc;
+ size_t iacc;
+
+ if(!estimator || !status)
+ return RES_BAD_ARG;
+
+ if(iprim >= estimator->nprims) {
+ log_error(estimator->dev, "%s: out of bound primitive index `%lu'.\n",
+ FUNC_NAME, (unsigned long)iprim);
+ return RES_BAD_ARG;
+ }
+
+ if(iband >= estimator->nbands) {
+ log_error(estimator->dev, "%s: out of bound spectral band index `%lu'.\n",
+ FUNC_NAME, (unsigned long)iband);
+ return RES_BAD_ARG;
+ }
+
+ iacc = iband * estimator->nprims + iprim;
+ acc = darray_accum_cdata_get(&estimator->buf) + iacc;
+ setup_status(acc, estimator->nsteps, status);
+ return RES_OK;
}
res_T
sgf_estimator_get_status_infinity
(struct sgf_estimator* estimator,
- const size_t iprimitive,
- const size_t ispectral_band,
+ const size_t iband,
+ struct sgf_status* status)
+{
+ const struct accum* acc;
+
+ if(!estimator || !status)
+ return RES_BAD_ARG;
+
+ if(iband >= estimator->nbands) {
+ log_error(estimator->dev, "%s: out of bound spectral band index `%lu'.\n",
+ FUNC_NAME, (unsigned long)iband);
+ return RES_BAD_ARG;
+ }
+ if(darray_accum_size_get(&estimator->buf_infinity) != 0) {
+ acc = darray_accum_cdata_get(&estimator->buf_infinity) + iband;
+ setup_status(acc, estimator->nsteps, status);
+ } else {
+ status->E = status->V = status->SE = 0;
+ status->nsteps = estimator->nsteps;
+ }
+ return RES_OK;
+}
+
+res_T
+sgf_estimator_get_status_medium
+ (struct sgf_estimator* estimator,
+ const size_t iband,
struct sgf_status* status)
{
- return estimator_get_status
- (estimator, INFINITY_RADIATIVE_FLUX, iprimitive, ispectral_band, status);
+ const struct accum* acc;
+
+ if(!estimator || !status)
+ return RES_BAD_ARG;
+
+ if(iband >= estimator->nbands) {
+ log_error(estimator->dev, "%s: out of bound spectral band index `%lu'\n.",
+ FUNC_NAME, (unsigned long)iband);
+ return RES_BAD_ARG;
+ }
+ if(darray_accum_size_get(&estimator->buf_medium) != 0) {
+ acc = darray_accum_cdata_get(&estimator->buf_medium) + iband;
+ setup_status(acc, estimator->nsteps, status);
+ } else {
+ status->E = status->V = status->SE = 0;
+ status->nsteps = estimator->nsteps;
+ }
+ return RES_OK;
}
diff --git a/src/sgf_realisation.h b/src/sgf_realisation.h
@@ -27,6 +27,7 @@
#include <star/s3d.h>
#include <star/ssp.h>
#include <rsys/float2.h>
+#include <rsys/float3.h>
/* How many self intersections are tested on the same ray before an error
* occurs */
@@ -43,18 +44,21 @@ typedef res_T
(*gebhart_radiative_path_T)
(struct sgf_device* dev,
struct accum* accums,
- struct accum* accums_infinity,
+ struct accum* accum_infinity,
+ struct accum* accum_medium,
struct ssp_rng* rng,
+ const double absorption_coef,
+ const size_t ispectral_band,
const float epsilon,
const size_t primitive_id,
struct sgf_scene_desc* desc);
static FINLINE void
-accum_weight(struct accum* accums, const size_t iface, const double weight)
+accum_weight(struct accum* accum, const double weight)
{
- ASSERT(accums);
- accums[iface].radiative_flux += weight;
- accums[iface].sqr_radiative_flux += weight * weight;
+ ASSERT(accum);
+ accum->radiative_flux += weight;
+ accum->sqr_radiative_flux += weight * weight;
}
/*******************************************************************************
@@ -197,8 +201,11 @@ static res_T
GEBHART_RADIATIVE_PATH
(struct sgf_device* dev,
struct accum* accums,
- struct accum* accums_infinity,
+ struct accum* accum_infinity,
+ struct accum* accum_medium,
struct ssp_rng* rng,
+ const double absorption_coef, /* m^-1 */
+ const size_t ispectral_band,
const float epsilon,
const size_t primitive_id,
struct sgf_scene_desc* desc)
@@ -210,16 +217,20 @@ GEBHART_RADIATIVE_PATH
const double trans_min = 1.e-8; /* Minimum transmissivity threshold */
double proba_reflec_spec;
double transmissivity, emissivity, reflectivity, specularity;
+ double medium_transmissivity;
#ifndef NDEBUG
+ double radiative_flux = 0.0;
double infinite_radiative_flux = 0.0;
- double sum_radiative_flux = 0.f;
+ double medium_radiative_flux = 0.0;
#endif
float vec0[3]; /* Temporary vector */
float normal[3]; /* Geometric normal */
float pos[3]; /* Radiative path position */
float dir[4]; /* Radiative path direction. dir[3] <=> sampled dir pdf */
float range[2]; /* Traced ray range */
- ASSERT(accums && accums_infinity && epsilon > 0.f && rng && desc);
+ ASSERT(accums && epsilon > 0.f && rng && desc);
+ ASSERT(absorption_coef < 0 || accum_medium);
+ ASSERT(absorption_coef >= 0 || accum_infinity);
scene = sgf_scene_desc_get_sXd_scene(desc);
@@ -252,16 +263,44 @@ GEBHART_RADIATIVE_PATH
&& ++nself_hits < NSELF_HITS_MAX); /* Too many self hits */
if(nself_hits >= NSELF_HITS_MAX) {
- if(dev->verbose) {
- logger_print(dev->logger, LOG_ERROR,
- "Too many self hit on a given ray. Ray origin: %g, %g, %g\n",
- SPLIT3(pos));
- }
+ log_error(dev,
+ "Too many self hit on a given ray. Ray origin: %g, %g, %g\n",
+ SPLIT3(pos));
return RES_BAD_OP;
}
+ /* Handle medium absorption */
+ 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));
+ return RES_BAD_OP;
+ } else {
+ double weight, ka;
+
+ /* Check the consistency of the medium description, i.e. the absorption
+ * coefficient must be the same when it is fetched from any primitive
+ * surrounding the current enclosure */
+ ka = desc->get_material_property
+ (desc->material, SGF_MEDIUM_ABSORPTION, primitive_id, ispectral_band);
+ if(ka != absorption_coef) {
+ log_error(dev, "Inconsistent medium description.\n");
+ return RES_BAD_ARG;
+ }
+
+ medium_transmissivity = exp(-absorption_coef*hit.distance);
+ weight = transmissivity * (1-medium_transmissivity);
+ accum_weight(accum_medium, weight);
+ transmissivity *= medium_transmissivity;
+#ifndef NDEBUG
+ medium_radiative_flux += weight;
+#endif
+ }
+ }
+
if(SXD_HIT_NONE(&hit)) { /* The ray is outside the volume */
- accum_weight(accums_infinity, prim.scene_prim_id, transmissivity);
+ accum_weight(accum_infinity, transmissivity);
#ifndef NDEBUG
infinite_radiative_flux = transmissivity;
#endif
@@ -275,26 +314,26 @@ GEBHART_RADIATIVE_PATH
/* Fetch material property */
emissivity = desc->get_material_property(desc->material,
- SGF_MATERIAL_EMISSIVITY, prim.scene_prim_id, 0);
+ SGF_MATERIAL_EMISSIVITY, prim.scene_prim_id, ispectral_band);
specularity = desc->get_material_property(desc->material,
- SGF_MATERIAL_SPECULARITY, prim.scene_prim_id, 0);
+ SGF_MATERIAL_SPECULARITY, prim.scene_prim_id, ispectral_band);
reflectivity = desc->get_material_property(desc->material,
- SGF_MATERIAL_REFLECTIVITY, prim.scene_prim_id, 0);
+ SGF_MATERIAL_REFLECTIVITY, prim.scene_prim_id, ispectral_band);
if(transmissivity > trans_min) {
const double weight = transmissivity * emissivity;
- accum_weight(accums, prim.scene_prim_id, weight);
+ accum_weight(accums + prim.scene_prim_id, weight);
transmissivity = transmissivity * (1.0 - emissivity);
#ifndef NDEBUG
- sum_radiative_flux += weight;
+ radiative_flux += weight;
#endif
} else {
/* Russian roulette */
if(ssp_rng_canonical(rng) < emissivity) {
const double weight = transmissivity;
- accum_weight(accums, prim.scene_prim_id, weight);
+ accum_weight(accums + prim.scene_prim_id, weight);
#ifndef NDEBUG
- sum_radiative_flux += weight;
+ radiative_flux += weight;
#endif
break;
}
@@ -317,7 +356,9 @@ GEBHART_RADIATIVE_PATH
}
#if !defined(NDEBUG)
/* Check the energy conservation property */
- ASSERT(eq_eps(sum_radiative_flux + infinite_radiative_flux, 1.0, 1.e6));
+ ASSERT(eq_eps
+ (radiative_flux + infinite_radiative_flux + medium_radiative_flux,
+ 1.0, 1.e6));
#endif
return RES_OK;
}
diff --git a/src/test_sgf_cube.c b/src/test_sgf_cube.c
@@ -221,22 +221,14 @@ main(int argc, char** argv)
CHECK(sgf_estimator_get_status(estimator, 0, 0, status), RES_OK);
CHECK(status->nsteps, NSTEPS);
- CHECK(sgf_estimator_get_status_infinity(NULL, SIZE_MAX, SIZE_MAX, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, SIZE_MAX, SIZE_MAX, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(NULL, 0, SIZE_MAX, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, 0, SIZE_MAX, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(NULL, SIZE_MAX, SIZE_MAX, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, SIZE_MAX, SIZE_MAX, status), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(NULL, 0, SIZE_MAX, status), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, 0, SIZE_MAX, status), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(NULL, SIZE_MAX, 0, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, SIZE_MAX, 0, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(NULL, 0, 0, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, 0, 0, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(NULL, SIZE_MAX, 0, NULL), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, SIZE_MAX, 0, status), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(NULL, 0, 0, status), RES_BAD_ARG);
- CHECK(sgf_estimator_get_status_infinity(estimator, 0, 0, status), RES_OK);
+ CHECK(sgf_estimator_get_status_infinity(NULL, SIZE_MAX, NULL), RES_BAD_ARG);
+ CHECK(sgf_estimator_get_status_infinity(estimator, SIZE_MAX, NULL), RES_BAD_ARG);
+ CHECK(sgf_estimator_get_status_infinity(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(sgf_estimator_get_status_infinity(estimator, 0, NULL), RES_BAD_ARG);
+ CHECK(sgf_estimator_get_status_infinity(NULL, SIZE_MAX, status), RES_BAD_ARG);
+ CHECK(sgf_estimator_get_status_infinity(estimator, SIZE_MAX, status), RES_BAD_ARG);
+ CHECK(sgf_estimator_get_status_infinity(NULL, 0, status), RES_BAD_ARG);
+ CHECK(sgf_estimator_get_status_infinity(estimator, 0, status), RES_OK);
CHECK(eq_eps(status->E, 0, status->SE), 1);
CHECK(status->nsteps, NSTEPS);
@@ -251,21 +243,21 @@ main(int argc, char** argv)
for(iprim = 0; iprim < (int)nprims; ++iprim) {
size_t iprim2;
struct sgf_status* row = status + (size_t)iprim * nprims;
+ struct sgf_status infinity;
const int ithread = omp_get_thread_num();
struct sgf_estimator* est;
CHECK(sgf_integrate
(sgf, rngs[ithread], (size_t)iprim, &scn_desc, NSTEPS, &est), RES_OK);
-
FOR_EACH(iprim2, 0, nprims) {
- struct sgf_status inf;
CHECK(sgf_estimator_get_status(est, iprim2, 0, row + iprim2), RES_OK);
CHECK(row[iprim2].nsteps, NSTEPS);
- CHECK(sgf_estimator_get_status_infinity(est, iprim2, 0, &inf), RES_OK);
- CHECK(eq_eps(inf.E, 0, 3 * inf.SE), 1);
}
+ CHECK(sgf_estimator_get_status_infinity(est, 0, &infinity), RES_OK);
+ CHECK(eq_eps(infinity.E, 0, infinity.SE), 1);
+
CHECK(sgf_estimator_ref_put(est), RES_OK);
}
diff --git a/src/test_sgf_square.c b/src/test_sgf_square.c
@@ -147,9 +147,10 @@ main(int argc, char** argv)
CHECK(iprim == i+1 || iprim == i-1, 1);
CHECK(eq_eps(status.E, 1 - sqrt(2)/2, 2*status.SE), 1);
}
- CHECK(sgf_estimator_get_status_infinity(estimator, i, 0, &status), RES_OK);
- CHECK(eq_eps(status.E, 0, status.SE), 1);
}
+ CHECK(sgf_estimator_get_status_infinity(estimator, 0, &status), RES_OK);
+ CHECK(eq_eps(status.E, 0, status.SE), 1);
+
CHECK(sgf_estimator_ref_put(estimator), RES_OK);
}
diff --git a/src/test_sgf_tetrahedron.c b/src/test_sgf_tetrahedron.c
@@ -110,6 +110,7 @@ main(int argc, char** argv)
for(iprim = 0; iprim < (int)nprims; ++iprim) {
struct sgf_status* row = status + (size_t)iprim*nprims;
struct sgf_estimator* estimator = NULL;
+ struct sgf_status infinity;
size_t iprim2;
const int ithread = omp_get_thread_num();
@@ -117,12 +118,13 @@ main(int argc, char** argv)
(sgf, rngs[ithread], (size_t)iprim, &desc, NSTEPS, &estimator), RES_OK);
FOR_EACH(iprim2, 0, nprims) {
- struct sgf_status inf;
CHECK(sgf_estimator_get_status(estimator, iprim2, 0, row + iprim2), RES_OK);
CHECK(row[iprim2].nsteps, NSTEPS);
- CHECK(sgf_estimator_get_status_infinity(estimator, iprim2, 0, &inf), RES_OK);
- CHECK(eq_eps(inf.E, 0, 3*inf.SE), 1);
}
+
+ CHECK(sgf_estimator_get_status_infinity(estimator, 0, &infinity), RES_OK);
+ CHECK(eq_eps(infinity.E, 0, infinity.SE), 1);
+
CHECK(sgf_estimator_ref_put(estimator), RES_OK);
}
CHECK(s3d_scene_end_session(scn), RES_OK);