star-gf

Compute Gebhart factors
git clone git://git.meso-star.fr/star-gf.git
Log | Files | Refs | README | LICENSE

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:
Msrc/sgf.h | 16+++++++++++++---
Msrc/sgf_device.c | 19+++++++++++++++++++
Msrc/sgf_device_c.h | 13+++++++++++++
Msrc/sgf_estimator.c | 259++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/sgf_realisation.h | 85++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/test_sgf_cube.c | 32++++++++++++--------------------
Msrc/test_sgf_square.c | 5+++--
Msrc/test_sgf_tetrahedron.c | 8+++++---
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);