solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit 95a8dcc055cccc2d48cf0b8ecfe0de4044de929a
parent 1ffaa3be1b5a9d734c4dba95ae07f675eff4e9a3
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 22 Feb 2017 16:39:34 +0100

Add and test the ssol_estimator_get_sampled_area function

Move the sampled_area and primary_area from the scene to the estimator
Rename the sampled_area in sampled_area_proxy and the primary area in
sampled_area.

Diffstat:
Msrc/ssol.h | 6++++++
Msrc/ssol_estimator.c | 9+++++++++
Msrc/ssol_estimator_c.h | 3+++
Msrc/ssol_scene.c | 26++++++++++++++------------
Msrc/ssol_scene_c.h | 6+++---
Msrc/ssol_solver.c | 22++++++++++++++--------
Msrc/test_ssol_by_receiver_integration.c | 2+-
Msrc/test_ssol_solver1.c | 6++++++
8 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -872,6 +872,12 @@ ssol_estimator_get_failed_count (const struct ssol_estimator* estimator, size_t* count); +/* Retrieve the overall area of the sampled instances */ +SSOL_API res_T +ssol_estimator_get_sampled_area + (const struct ssol_estimator* estimator, + double* area); + /******************************************************************************* * Per receiver MC estimations ******************************************************************************/ diff --git a/src/ssol_estimator.c b/src/ssol_estimator.c @@ -193,6 +193,15 @@ ssol_estimator_get_failed_count return RES_OK; } +res_T +ssol_estimator_get_sampled_area + (const struct ssol_estimator* estimator, double* area) +{ + if(!estimator || !area) return RES_BAD_ARG; + *area = estimator->sampled_area; + return RES_OK; +} + /******************************************************************************* * Local function ******************************************************************************/ diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h @@ -345,6 +345,9 @@ struct ssol_estimator { struct htable_receiver mc_receivers; /* Per receiver MC */ struct htable_sampled mc_sampled; /* Per sampled instance MC */ + /* Overall area of the sampled instances. Actually this is not the area that + * is effectively sampled since an instance may be sampled through a proxy + * geometry */ double sampled_area; struct ssol_device* dev; diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -293,7 +293,7 @@ ssol_scene_for_each_instance res = RES_BAD_ARG; goto error; } - + htable_instance_begin(&scn->instances_rt, &it); htable_instance_end(&scn->instances_rt, &end); while(!htable_instance_iterator_eq(&it, &end)) { @@ -317,15 +317,20 @@ res_T scene_create_s3d_views (struct ssol_scene* scn, struct s3d_scene_view** out_view_rt, - struct s3d_scene_view** out_view_samp) + struct s3d_scene_view** out_view_samp, + double* out_sampled_area, + double* out_sampled_area_proxy) { struct htable_instance_iterator it, end; struct s3d_scene_view* view_rt = NULL; struct s3d_scene_view* view_samp = NULL; + double sampled_area = 0; + double sampled_area_proxy = 0; int has_sampled = 0; int has_receiver = 0; res_T res = RES_OK; ASSERT(scn && out_view_rt && out_view_samp); + ASSERT(out_sampled_area && out_sampled_area_proxy); S3D(scene_clear(scn->scn_samp)); htable_instance_clear(&scn->instances_samp); @@ -333,10 +338,7 @@ scene_create_s3d_views htable_instance_begin(&scn->instances_rt, &it); htable_instance_end(&scn->instances_rt, &end); - scn->sampled_area = 0; - scn->primary_area = 0; - - while (!htable_instance_iterator_eq(&it, &end)) { + while(!htable_instance_iterator_eq(&it, &end)) { struct ssol_instance* inst = *htable_instance_iterator_data_get(&it); unsigned id; htable_instance_iterator_next(&it); @@ -347,8 +349,8 @@ scene_create_s3d_views if(!inst->sample) continue; - scn->sampled_area += inst->shape_samp_area; - scn->primary_area += inst->shape_rt_area; + sampled_area += inst->shape_rt_area; + sampled_area_proxy += inst->shape_samp_area; /* Note that geometries with virtual material can be sampled without risk * since the solver avoid to shade them and simply pursue the primary ray */ @@ -358,7 +360,6 @@ scene_create_s3d_views res = s3d_scene_attach_shape(scn->scn_samp, inst->shape_samp); if(res != RES_OK) goto error; - /* Register the instantiated s3d sampling shape */ S3D(shape_get_id(inst->shape_samp, &id)); ASSERT(!htable_instance_find(&scn->instances_samp, &id)); @@ -387,6 +388,8 @@ scene_create_s3d_views exit: *out_view_rt = view_rt; *out_view_samp = view_samp; + *out_sampled_area = sampled_area; + *out_sampled_area_proxy = sampled_area_proxy; return res; error: S3D(scene_clear(scn->scn_samp)); @@ -455,8 +458,7 @@ hit_filter_function if(dst >= FLT_MAX) { /* No projection is found => the ray does not intersect the quadric */ return 1; - } - else if (inst != rdata->inst_from) { + } else if (inst != rdata->inst_from) { hit_side = d3_dot(dir, N) < 0 ? SSOL_FRONT : SSOL_BACK; } else { if(hit->distance <= rdata->range_min) { @@ -476,7 +478,7 @@ hit_filter_function default: FATAL("Unreachable code.\n"); break; } ASSERT(hit_side == SSOL_BACK || hit_side == SSOL_FRONT); - if (rdata->reversed_ray) { + if(rdata->reversed_ray) { hit_side = (hit_side == SSOL_FRONT) ? SSOL_BACK : SSOL_FRONT; } mtl = hit_side == SSOL_FRONT ? sshape->mtl_front : sshape->mtl_back; diff --git a/src/ssol_scene_c.h b/src/ssol_scene_c.h @@ -46,8 +46,6 @@ struct ssol_scene { struct ssol_sun* sun; /* Sun of the scene */ struct ssol_atmosphere* atmosphere; /* Atmosphere of the scene */ - double sampled_area, primary_area; /* scene areas */ - struct ssol_device* dev; ref_T ref; }; @@ -58,7 +56,9 @@ extern LOCAL_SYM res_T scene_create_s3d_views (struct ssol_scene* scn, struct s3d_scene_view** view_rt, - struct s3d_scene_view** view_samp); + struct s3d_scene_view** view_samp, + double* sampled_area, /* Area of the instance set as "samplable" */ + double* sampled_area_proxy); /* Area of the sampled geometries */ #endif /* SSOL_SCENE_C_H */ diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -181,6 +181,7 @@ static const struct point POINT_NULL = POINT_NULL__; static res_T point_init (struct point* pt, + const double sampled_area_proxy, struct ssol_scene* scn, struct htable_sampled* sampled, struct s3d_scene_view* view_samp, @@ -222,8 +223,8 @@ point_init /* Initialise the Monte Carlo weight */ cos_sun = fabs(d3_dot(pt->N, pt->dir)); - pt->weight = scn->sun->dni * scn->sampled_area * cos_sun; - pt->cos_loss = scn->sun->dni * scn->sampled_area * (1 - cos_sun); + pt->weight = scn->sun->dni * sampled_area_proxy * cos_sun; + pt->cos_loss = scn->sun->dni * sampled_area_proxy * (1 - cos_sun); pt->absorptivity_loss = pt->reflectivity_loss = 0; /* Retrieve the sampled instance and shaded shape */ @@ -611,6 +612,7 @@ error: static res_T trace_radiative_path (const size_t path_id, /* Unique id of the radiative path */ + const double sampled_area_proxy, /* Overall area of the sampled geometries */ struct thread_context* thread_ctx, struct ssol_scene* scn, struct s3d_scene_view* view_samp, @@ -629,8 +631,8 @@ trace_radiative_path ASSERT(thread_ctx && scn && view_samp && view_rt && ran_sun_dir && ran_sun_wl); /* Find a new starting point of the radiative random walk */ - res = point_init(&pt, scn, &thread_ctx->mc_samps, view_samp, view_rt, - ran_sun_dir, ran_sun_wl, thread_ctx->rng, &is_lit); + res = point_init(&pt, sampled_area_proxy, scn, &thread_ctx->mc_samps, + view_samp, view_rt, ran_sun_dir, ran_sun_wl, thread_ctx->rng, &is_lit); if(res != RES_OK) goto error; if(!is_lit) { /* The starting point is not lit */ @@ -737,6 +739,8 @@ ssol_solve struct darray_thread_ctx thread_ctxs; struct ssol_estimator* estimator = NULL; struct ssp_rng_proxy* rng_proxy = NULL; + double sampled_area; + double sampled_area_proxy; int nthreads = 0; int64_t nrealisations = 0; int i = 0; @@ -762,7 +766,8 @@ ssol_solve if(res != RES_OK) goto error; /* Create data structures shared by all threads */ - res = scene_create_s3d_views(scn, &view_rt, &view_samp); + res = scene_create_s3d_views(scn, &view_rt, &view_samp, &sampled_area, + &sampled_area_proxy); if(res != RES_OK) goto error; res = sun_create_distributions(scn->sun, &ran_sun_dir, &ran_sun_wl); if(res != RES_OK) goto error; @@ -798,8 +803,8 @@ ssol_solve thread_ctx = darray_thread_ctx_data_get(&thread_ctxs) + ithread; /* Execute a MC experiment */ - res_local = trace_radiative_path((size_t)i, thread_ctx, scn, view_samp, - view_rt, ran_sun_dir, ran_sun_wl, output); + res_local = trace_radiative_path((size_t)i, sampled_area_proxy, thread_ctx, + scn, view_samp, view_rt, ran_sun_dir, ran_sun_wl, output); if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; @@ -868,7 +873,8 @@ ssol_solve } } - estimator->realisation_count += realisations_count; + estimator->realisation_count = realisations_count; + estimator->sampled_area = sampled_area; exit: darray_thread_ctx_release(&thread_ctxs); diff --git a/src/test_ssol_by_receiver_integration.c b/src/test_ssol_by_receiver_integration.c @@ -152,7 +152,7 @@ main(int argc, char** argv) mc_rcv.integrated_irradiance.E, mc_rcv.integrated_irradiance.SE); CHECK(eq_eps(mc_rcv.integrated_irradiance.E, S_DNI_cos, S_DNI_cos * 1e-1), 1); CHECK(GET_MC_SAMP_X_RCV(estimator1, heliostat, target, SSOL_FRONT, &mc_rcv), RES_OK); - printf("Ir(heliostat=>target) = %g +/- %g", + printf("Ir(heliostat=>target) = %g +/- %g\n", mc_rcv.integrated_irradiance.E, mc_rcv.integrated_irradiance.SE); CHECK(eq_eps(mc_rcv.integrated_irradiance.E, S_DNI_cos, S_DNI_cos * 1e-1), 1); diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -160,6 +160,12 @@ main(int argc, char** argv) CHECK(ssol_solve(scene, rng, 1, NULL, &estimator), RES_OK); + CHECK(ssol_estimator_get_sampled_area(NULL, NULL), RES_BAD_ARG); + CHECK(ssol_estimator_get_sampled_area(estimator, NULL), RES_BAD_ARG); + CHECK(ssol_estimator_get_sampled_area(NULL, &dbl), RES_BAD_ARG); + CHECK(ssol_estimator_get_sampled_area(estimator, &dbl), RES_OK); + CHECK(eq_eps(dbl, 12, 1.e-6), 1); + CHECK(ssol_estimator_get_count(NULL, NULL), RES_BAD_ARG); CHECK(ssol_estimator_get_count(estimator, NULL), RES_BAD_ARG); CHECK(ssol_estimator_get_count(NULL, &count), RES_BAD_ARG);