star-gf

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

commit d04b25ded57001414af7eb4a3f863000b8460add
parent df29d4ea741ce6653129dfc6b32d9e955cd2e268
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 25 Sep 2015 11:13:50 +0200

Integrate the Gebhart Factors for each spectral band

Add the spectral_band identifier to the getter of the estimator status.

Diffstat:
Msrc/sgf.h | 8++++++--
Msrc/sgf_estimator.c | 60+++++++++++++++++++++++++++++++++++++-----------------------
Msrc/test_sgf_cube.c | 26+++++++++++++++++---------
3 files changed, 60 insertions(+), 34 deletions(-)

diff --git a/src/sgf.h b/src/sgf.h @@ -110,14 +110,17 @@ SGF_API res_T sgf_device_ref_put (struct sgf_device* dev); -/* TODO comment it */ +/* Numerical estimation of the Gebhart Factor between `primitive_id' and the + * other scene primitives. An active S3D_TRACE/S3D_GET_PRIMITIVE session must + * be active on `desc->scene'. This function is thread safe and can be invoked + * by several threads. */ SGF_API res_T sgf_integrate (struct sgf_device* dev, struct ssp_rng* rng, const size_t primitive_id, struct sgf_scene_desc* desc, - const size_t steps_count, + const size_t steps_count, /* #realisations */ struct sgf_estimator** out_estimator); SGF_API res_T @@ -132,6 +135,7 @@ SGF_API res_T sgf_estimator_get_status (struct sgf_estimator* estimator, const size_t primitive_id, + const size_t spectral_band_id, struct sgf_status* status); END_DECLS diff --git a/src/sgf_estimator.c b/src/sgf_estimator.c @@ -49,7 +49,9 @@ struct accum { /* 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 */ - size_t nsteps; /* Number of realisations */ + size_t nsteps; /* # realisations */ + size_t nprims; /* # primitives */ + size_t nbands; /* # spectral bands */ struct sgf_device* dev; ref_T ref; @@ -66,22 +68,17 @@ check_scene_desc(struct sgf_scene_desc* desc) } static FINLINE void -accum_weight - (struct sgf_estimator* estimator, - const size_t iface, - const double weight) +accum_weight(struct accum* accums, const size_t iface, const double weight) { - struct accum* acc; - ASSERT(estimator); - acc = darray_accum_data_get(&estimator->buf) + iface; - acc->radiative_flux += weight; - acc->sqr_radiative_flux += weight * weight; + ASSERT(accums); + accums[iface].radiative_flux += weight; + accums[iface].sqr_radiative_flux += weight * weight; } /* Return RES_BAD_OP on numerical issue. i.e. the radiative path is skipped */ static res_T gebhart_radiative_path - (struct sgf_estimator* estimator, + (struct accum* accums, struct ssp_rng* rng, const size_t primitive_id, struct sgf_scene_desc* desc) @@ -159,7 +156,7 @@ gebhart_radiative_path if(transmissivity > trans_min) { const double weight = transmissivity * emissivity; - accum_weight(estimator, prim.scene_prim_id, weight); + accum_weight(accums, prim.scene_prim_id, weight); transmissivity = transmissivity * (1.0 - emissivity); #ifndef NDEBUG sum_radiative_flux += weight; @@ -168,7 +165,7 @@ gebhart_radiative_path /* Russian roulette */ if(ssp_rng_canonical(rng) < emissivity) { const double weight = transmissivity; - accum_weight(estimator, prim.scene_prim_id, weight); + accum_weight(accums, prim.scene_prim_id, weight); #ifndef NDEBUG sum_radiative_flux += weight; #endif @@ -176,8 +173,7 @@ gebhart_radiative_path } } - if(reflectivity <= 0.0) - break; + if(reflectivity <= 0.0) break; proba_reflec_spec = specularity / reflectivity; f3_normalize(normal, hit.normal); @@ -259,7 +255,8 @@ sgf_integrate struct sgf_estimator** out_estimator) { struct sgf_estimator* estimator = NULL; - size_t istep = 0; + size_t istep; + size_t ispectral_band; size_t nprims; int mask; res_T res = RES_OK; @@ -307,12 +304,18 @@ sgf_integrate memset(darray_accum_data_get(&estimator->buf), 0, darray_accum_size_get(&estimator->buf)*sizeof(struct accum)); - /* Invoke the Gebhart factor integration. TODO interate per spectral bands */ - FOR_EACH(istep, 0, steps_count) { - res = gebhart_radiative_path(estimator, rng, primitive_id, desc); - if(res != RES_OK) goto error; + /* 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; + FOR_EACH(istep, 0, steps_count) { + res = gebhart_radiative_path(accums, rng, primitive_id, desc); + if(res != RES_OK) goto error; + } } estimator->nsteps = steps_count; + estimator->nprims = nprims; + estimator->nbands = desc->spectral_bands_count; exit: if(out_estimator) *out_estimator = estimator; @@ -342,23 +345,34 @@ res_T sgf_estimator_get_status (struct sgf_estimator* estimator, const size_t iprimitive, + const size_t ispectral_band, struct sgf_status* status) { struct accum* acc; size_t nsteps; + size_t iacc; if(!estimator || !status) return RES_BAD_ARG; - if(iprimitive >= darray_accum_size_get(&estimator->buf)) { + 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, - "Invalid primitive index `%lu'\n", iprimitive); + "Out of bound spectral band index `%lu'\n", ispectral_band); } return RES_BAD_ARG; } - acc = darray_accum_data_get(&estimator->buf) + iprimitive; + iacc = ispectral_band * estimator->nprims + iprimitive; + ASSERT(iacc < darray_accum_size_get(&estimator->buf)); + acc = darray_accum_data_get(&estimator->buf) + iacc; nsteps = estimator->nsteps; status->E = acc->radiative_flux / (double)nsteps; /* Expected value */ diff --git a/src/test_sgf_cube.c b/src/test_sgf_cube.c @@ -216,14 +216,22 @@ main(int argc, char** argv) CHECK(sgf_integrate(NULL, rngs[0], 0, &scn_desc, NSTEPS, &estimator), RES_BAD_ARG); CHECK(sgf_integrate(sgf, rngs[0], 0, &scn_desc, NSTEPS, &estimator), RES_OK); - CHECK(sgf_estimator_get_status(NULL, SIZE_MAX, NULL), RES_BAD_ARG); - CHECK(sgf_estimator_get_status(estimator, SIZE_MAX, NULL), RES_BAD_ARG); - CHECK(sgf_estimator_get_status(NULL, 0, NULL), RES_BAD_ARG); - CHECK(sgf_estimator_get_status(estimator, 0, NULL), RES_BAD_ARG); - CHECK(sgf_estimator_get_status(NULL, SIZE_MAX, status), RES_BAD_ARG); - CHECK(sgf_estimator_get_status(estimator, SIZE_MAX, status), RES_BAD_ARG); - CHECK(sgf_estimator_get_status(NULL, 0, status), RES_BAD_ARG); - CHECK(sgf_estimator_get_status(estimator, 0, status), RES_OK); + CHECK(sgf_estimator_get_status(NULL, SIZE_MAX, SIZE_MAX, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, SIZE_MAX, SIZE_MAX, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(NULL, 0, SIZE_MAX, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, 0, SIZE_MAX, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(NULL, SIZE_MAX, SIZE_MAX, status), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, SIZE_MAX, SIZE_MAX, status), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(NULL, 0, SIZE_MAX, status), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, 0, SIZE_MAX, status), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(NULL, SIZE_MAX, 0, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, SIZE_MAX, 0, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(NULL, 0, 0, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, 0, 0, NULL), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(NULL, SIZE_MAX, 0, status), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, SIZE_MAX, 0, status), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(NULL, 0, 0, status), RES_BAD_ARG); + CHECK(sgf_estimator_get_status(estimator, 0, 0, status), RES_OK); CHECK(status->nsteps, NSTEPS); @@ -244,7 +252,7 @@ main(int argc, char** argv) CHECK(sgf_integrate(sgf, rngs[ithread], iprim, &scn_desc, NSTEPS, &est), RES_OK); FOR_EACH(iprim2, 0, nprims) { - CHECK(sgf_estimator_get_status(est, iprim2, row + iprim2), RES_OK); + CHECK(sgf_estimator_get_status(est, iprim2, 0, row + iprim2), RES_OK); CHECK(row[iprim2].nsteps, NSTEPS); } CHECK(sgf_estimator_ref_put(est), RES_OK);