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:
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);