solstice-solver

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

commit 6b340d7505ad24867c52b1ca3af63b7503f34781
parent 74a0cbcd96f8254f3ef41baa95fa5c3798c391e2
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 10 Mar 2017 17:18:12 +0100

Remove per-receiver/per-primitive cos_loss, finish global cos_loss.

Diffstat:
Msrc/ssol.h | 1-
Msrc/ssol_estimator.c | 1-
Msrc/ssol_estimator_c.h | 13++-----------
Msrc/ssol_mc_receiver.c | 2--
Msrc/ssol_solver.c | 30+++++++++++++-----------------
Msrc/test_ssol_solver1.c | 20+++++++++++---------
6 files changed, 26 insertions(+), 41 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -310,7 +310,6 @@ struct ssol_mc_receiver { struct ssol_mc_result integrated_absorbed_irradiance; /* In W */ struct ssol_mc_result absorptivity_loss; /* In W */ struct ssol_mc_result reflectivity_loss; /* In W */ - struct ssol_mc_result cos_loss; /* In W TODO remove this */ /* Internal data */ size_t N__; diff --git a/src/ssol_estimator.c b/src/ssol_estimator.c @@ -169,7 +169,6 @@ ssol_estimator_get_mc_sampled_x_receiver SETUP_MC_RESULT(integrated_absorbed_irradiance); SETUP_MC_RESULT(absorptivity_loss); SETUP_MC_RESULT(reflectivity_loss); - SETUP_MC_RESULT(cos_loss); #undef SETUP_MC_RESULT rcv->mc__ = mc_rcv1; rcv->N__ = mc_samp->nb_samples; diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h @@ -43,14 +43,12 @@ static const struct mc_data MC_DATA_NULL = MC_DATA_NULL__; struct mc_data integrated_irradiance; /* In W */ \ struct mc_data integrated_absorbed_irradiance; /* In W */ \ struct mc_data absorptivity_loss; /* In W */ \ - struct mc_data reflectivity_loss; /* In W */ \ - struct mc_data cos_loss; /* In W */ + struct mc_data reflectivity_loss; /* In W */ #define MC_RECEIVER_DATA_NULL__ \ MC_DATA_NULL__, \ MC_DATA_NULL__, \ MC_DATA_NULL__, \ - MC_DATA_NULL__, \ MC_DATA_NULL__ struct mc_primitive_1side { @@ -89,7 +87,6 @@ mc_receiver_1side_init mc->integrated_absorbed_irradiance = MC_DATA_NULL; mc->absorptivity_loss = MC_DATA_NULL; mc->reflectivity_loss = MC_DATA_NULL; - mc->cos_loss = MC_DATA_NULL; htable_prim2mc_init(allocator, &mc->prim2mc); darray_mc_prim_init(allocator, &mc->mc_prims); } @@ -112,7 +109,6 @@ mc_receiver_1side_copy dst->integrated_absorbed_irradiance = src->integrated_absorbed_irradiance; dst->absorptivity_loss = src->absorptivity_loss; dst->reflectivity_loss = src->reflectivity_loss; - dst->cos_loss = src->cos_loss; res = htable_prim2mc_copy(&dst->prim2mc, &src->prim2mc); if(res != RES_OK) return res; res = darray_mc_prim_copy(&dst->mc_prims, &src->mc_prims); @@ -130,7 +126,6 @@ mc_receiver_1side_copy_and_release dst->integrated_absorbed_irradiance = src->integrated_absorbed_irradiance; dst->absorptivity_loss = src->absorptivity_loss; dst->reflectivity_loss = src->reflectivity_loss; - dst->cos_loss = src->cos_loss; res = htable_prim2mc_copy(&dst->prim2mc, &src->prim2mc); if(res != RES_OK) return res; res = darray_mc_prim_copy(&dst->mc_prims, &src->mc_prims); @@ -237,7 +232,6 @@ mc_receiver_copy_and_release ******************************************************************************/ struct mc_sampled { /* Global data for this entity */ - struct mc_data cos_loss; struct mc_data shadowed; double area; double sun_cos; @@ -253,7 +247,6 @@ mc_sampled_init struct mc_sampled* samp) { ASSERT(samp); - samp->cos_loss = MC_DATA_NULL; samp->shadowed = MC_DATA_NULL; samp->area = 0; samp->sun_cos = 0; @@ -272,7 +265,6 @@ static INLINE res_T mc_sampled_copy(struct mc_sampled* dst, const struct mc_sampled* src) { ASSERT(dst && src); - dst->cos_loss = src->cos_loss; dst->shadowed = src->shadowed; dst->area = src->area; dst->sun_cos = src->sun_cos; @@ -284,7 +276,6 @@ static INLINE res_T mc_sampled_copy_and_release(struct mc_sampled* dst, struct mc_sampled* src) { ASSERT(dst && src); - dst->cos_loss = src->cos_loss; dst->shadowed = src->shadowed; dst->area = src->area; dst->sun_cos = src->sun_cos; @@ -345,7 +336,7 @@ struct ssol_estimator { /* Implicit MC computations */ struct mc_data shadowed; struct mc_data missing; - struct mc_data cos_loss; /* TODO compute it */ + struct mc_data cos_loss; struct htable_receiver mc_receivers; /* Per receiver MC */ struct htable_sampled mc_sampled; /* Per sampled instance MC */ diff --git a/src/ssol_mc_receiver.c b/src/ssol_mc_receiver.c @@ -53,7 +53,6 @@ ssol_estimator_get_mc_receiver SETUP_MC_RESULT(integrated_absorbed_irradiance); SETUP_MC_RESULT(absorptivity_loss); SETUP_MC_RESULT(reflectivity_loss); - SETUP_MC_RESULT(cos_loss); #undef SETUP_MC_RESULT rcv->mc__ = mc_rcv1; rcv->N__ = estimator->realisation_count; @@ -98,7 +97,6 @@ ssol_mc_receiver_get_mc_primitive SETUP_MC_RESULT(integrated_absorbed_irradiance); SETUP_MC_RESULT(absorptivity_loss); SETUP_MC_RESULT(reflectivity_loss); - SETUP_MC_RESULT(cos_loss); #undef SETUP_MC_RESULT prim->index = i; return RES_OK; diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -157,10 +157,10 @@ struct point { double wl; /* Sampled wavelength */ /* MC weights, before and after hit */ double incoming_weight, weight; + double cos_loss; /* loss at the starting point */ double absorbed_irradiance; /* current hit only */ double absorptivity_loss_before, absorptivity_loss; double reflectivity_loss_before, reflectivity_loss; - double cos_loss_before, cos_loss; enum ssol_side_flag side; }; @@ -174,7 +174,7 @@ struct point { {0, 0, 0}, /* Direction */ \ {0, 0}, /* UV */ \ 0, /* Wavelength */ \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MC weights */ \ + 0, 0, 0, 0, 0, 0, 0, 0, /* MC weights */ \ SSOL_FRONT /* Side */ \ } static const struct point POINT_NULL = POINT_NULL__; @@ -225,7 +225,6 @@ point_init /* Initialise the Monte Carlo weight */ cos_sun = fabs(d3_dot(pt->N, pt->dir)); 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 */ @@ -238,8 +237,6 @@ point_init /* Store sampled entity related weights */ res = get_mc_sampled(sampled, pt->inst, &pt->mc_samp); if(res != RES_OK) goto error; - pt->mc_samp->cos_loss.weight += pt->cos_loss; - pt->mc_samp->cos_loss.sqr_weight += pt->cos_loss * pt->cos_loss; pt->mc_samp->nb_samples++; /* For punched surface, retrieve the sampled position and normal onto the @@ -248,6 +245,9 @@ point_init punched_shape_project_point (pt->sshape->shape, pt->inst->transform, pt->pos, pt->pos, pt->N); } + /* use local cos to compute cos_loss */ + cos_sun = fabs(d3_dot(pt->N, pt->dir)); + pt->cos_loss = scn->sun->dni * sampled_area_proxy * (1 - cos_sun); /* Define the primitive side on which the point lies */ if(d3_dot(pt->N, pt->dir) < 0) { @@ -370,7 +370,6 @@ point_shade pt->incoming_weight = pt->weight; pt->absorptivity_loss_before = pt->absorptivity_loss; pt->reflectivity_loss_before = pt->reflectivity_loss; - pt->cos_loss_before = pt->cos_loss; pt->absorbed_irradiance = (1 - r) * pt->weight; pt->reflectivity_loss += pt->absorbed_irradiance; pt->weight = pt->incoming_weight - pt->absorbed_irradiance; @@ -385,7 +384,6 @@ point_hit_virtual(struct point* pt) pt->incoming_weight = pt->weight; pt->absorptivity_loss_before = pt->absorptivity_loss; pt->reflectivity_loss_before = pt->reflectivity_loss; - pt->cos_loss_before = pt->cos_loss; } static FINLINE int @@ -483,7 +481,6 @@ accum_mc_receivers_1side ACCUM_WEIGHT(integrated_absorbed_irradiance); ACCUM_WEIGHT(absorptivity_loss); ACCUM_WEIGHT(reflectivity_loss); - ACCUM_WEIGHT(cos_loss); #undef ACCUM_WEIGHT /* Merge the per primitive MC of the integrated irradiance */ @@ -500,7 +497,6 @@ accum_mc_receivers_1side ACCUM_WEIGHT(integrated_absorbed_irradiance); ACCUM_WEIGHT(absorptivity_loss); ACCUM_WEIGHT(reflectivity_loss); - ACCUM_WEIGHT(cos_loss); #undef ACCUM_WEIGHT } exit: @@ -523,7 +519,6 @@ accum_mc_sampled(struct mc_sampled* dst, struct mc_sampled* src) dst->Name.weight += src->Name.weight; \ dst->Name.sqr_weight += src->Name.sqr_weight; \ } (void)0 - ACCUM_WEIGHT(cos_loss); ACCUM_WEIGHT(shadowed); #undef ACCUM_WEIGHT @@ -588,7 +583,6 @@ update_mc ACCUM_WEIGHT(integrated_absorbed_irradiance, pt->absorbed_irradiance); ACCUM_WEIGHT(absorptivity_loss, pt->absorptivity_loss_before); ACCUM_WEIGHT(reflectivity_loss, pt->reflectivity_loss_before); - ACCUM_WEIGHT(cos_loss, pt->cos_loss_before); #undef ACCUM_WEIGHT /* Per-sampled/receiver MC accumulation */ @@ -603,7 +597,6 @@ update_mc ACCUM_WEIGHT(integrated_absorbed_irradiance, pt->absorbed_irradiance); ACCUM_WEIGHT(absorptivity_loss, pt->absorptivity_loss_before); ACCUM_WEIGHT(reflectivity_loss, pt->reflectivity_loss_before); - ACCUM_WEIGHT(cos_loss, pt->cos_loss_before); #undef ACCUM_WEIGHT /* Per primitive receiver MC accumulation */ @@ -620,7 +613,6 @@ update_mc ACCUM_WEIGHT(integrated_absorbed_irradiance, pt->absorbed_irradiance); ACCUM_WEIGHT(absorptivity_loss, pt->absorptivity_loss_before); ACCUM_WEIGHT(reflectivity_loss, pt->reflectivity_loss_before); - ACCUM_WEIGHT(cos_loss, pt->cos_loss_before); #undef ACCUM_WEIGHT } @@ -655,11 +647,15 @@ trace_radiative_path view_samp, view_rt, ran_sun_dir, ran_sun_wl, thread_ctx->rng, &is_lit); if(res != RES_OK) goto error; + #define ACCUM_WEIGHT(Res, W) { \ + Res.weight += (W); \ + Res.sqr_weight += (W)*(W); \ + } (void)0 + ACCUM_WEIGHT(thread_ctx->cos_loss, pt.cos_loss); if(!is_lit) { /* The starting point is not lit */ - pt.mc_samp->shadowed.weight += pt.weight; - pt.mc_samp->shadowed.sqr_weight += pt.weight * pt.weight; - thread_ctx->shadowed.weight += pt.weight; - thread_ctx->shadowed.sqr_weight += pt.weight * pt.weight; + ACCUM_WEIGHT(pt.mc_samp->shadowed, pt.weight); + ACCUM_WEIGHT(thread_ctx->shadowed, pt.weight); + #undef ACCUM_WEIGHT } else { int hit_a_receiver = 0; diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -309,8 +309,10 @@ main(int argc, char** argv) CHECK(ssol_estimator_get_mc_global(estimator, &mc_global), RES_OK); printf("Shadows = %g +/- %g; ", mc_global.shadowed.E, mc_global.shadowed.SE); printf("Missing = %g +/- %g; ", mc_global.missing.E, mc_global.missing.SE); + printf("Cos = %g +/- %g; ", mc_global.cos_loss.E, mc_global.cos_loss.SE); CHECK(eq_eps(mc_global.shadowed.E, 0, 1e-4), 1); CHECK(eq_eps(mc_global.missing.E, 0, 1e-4), 1); + CHECK(eq_eps(mc_global.cos_loss.E, (1 - COS)*(4 * DNI), 1e-4), 1); CHECK(GET_MC_RCV(estimator, target, SSOL_FRONT, &mc_rcv), RES_OK); printf("Ir(target) = %g +/- %g\n", mc_rcv.integrated_irradiance.E, mc_rcv.integrated_irradiance.SE); @@ -343,13 +345,16 @@ main(int argc, char** argv) CHECK(ssol_estimator_get_mc_global(estimator, &mc_global), RES_OK); printf("Shadows = %g +/- %g; ", mc_global.shadowed.E, mc_global.shadowed.SE); printf("Missing = %g +/- %g; ", mc_global.missing.E, mc_global.missing.SE); + printf("Cos = %g +/- %g; ", mc_global.cos_loss.E, mc_global.cos_loss.SE); CHECK(eq_eps(mc_global.shadowed.E, 0, 1e-4), 1); CHECK(eq_eps(mc_global.missing.E, 0, 1e-4), 1); + CHECK(eq_eps(mc_global.cos_loss.E, (1 - COS)*(4 * DNI), 1e-4), 1); CHECK(GET_MC_RCV(estimator, target, SSOL_FRONT, &mc_rcv), RES_OK); printf("Ir(target) = %g +/- %g\n", mc_rcv.integrated_irradiance.E, mc_rcv.integrated_irradiance.SE); CHECK(eq_eps(mc_rcv.integrated_irradiance.E, m, 1e-8), 1); CHECK(eq_eps(mc_rcv.integrated_irradiance.SE, std, 1e-4), 1); + CHECK(eq_eps(mc_global.cos_loss.E, (1 - COS)*(4 * DNI), 1e-4), 1); CHECK(ssol_estimator_ref_put(estimator), RES_OK); /* Check atmosphere model and imperfect mirror: there are losses */ @@ -389,9 +394,11 @@ main(int argc, char** argv) CHECK(eq_eps(a_std, 0, 1e-4), 1); CHECK(ssol_estimator_get_mc_global(estimator, &mc_global), RES_OK); printf("Shadows = %g +/- %g; ", mc_global.shadowed.E, mc_global.shadowed.SE); - printf("Missing = %g +/- %g\n", mc_global.missing.E, mc_global.missing.SE); + printf("Missing = %g +/- %g; ", mc_global.missing.E, mc_global.missing.SE); + printf("Cos = %g +/- %g\n", mc_global.cos_loss.E, mc_global.cos_loss.SE); CHECK(eq_eps(mc_global.shadowed.E, 0, 1e-4), 1); CHECK(eq_eps(mc_global.missing.E, 0, 1e-4), 1); + CHECK(eq_eps(mc_global.cos_loss.E, (1 - COS)*(4 * DNI), 1e-4), 1); CHECK(GET_MC_RCV(estimator, target, SSOL_FRONT, &mc_rcv), RES_OK); printf ("\tIr(target) = %g +/- %g (%.2g %%)\n", @@ -408,11 +415,6 @@ main(int argc, char** argv) mc_rcv.reflectivity_loss.E, mc_rcv.reflectivity_loss.SE, 100 * mc_rcv.reflectivity_loss.E / m); - printf - ("\tCos Loss(target) = %g +/- %g (%.2g %%)\n", - mc_rcv.cos_loss.E, - mc_rcv.cos_loss.SE, - 100 * mc_rcv.cos_loss.E / m); CHECK(eq_eps(mc_rcv.integrated_irradiance.E, a_m, 1e-8), 1); CHECK(eq_eps(mc_rcv.integrated_irradiance.SE, a_std, 1e-4), 1); CHECK(eq_eps @@ -423,9 +425,7 @@ main(int argc, char** argv) ( mc_rcv.integrated_irradiance.E + mc_rcv.absorptivity_loss.E + mc_rcv.reflectivity_loss.E - + mc_rcv.cos_loss.E, 4 * DNI, 1e-8), 1); - CHECK(eq_eps(mc_rcv.cos_loss.E / (4 * DNI), 1 - COS, 1e-8), 1); - + + mc_global.cos_loss.E, 4 * DNI, 1e-8), 1); CHECK(ssol_mc_receiver_get_mc_primitives_count(NULL, NULL), RES_BAD_ARG); CHECK(ssol_mc_receiver_get_mc_primitives_count(&mc_rcv, NULL), RES_BAD_ARG); CHECK(ssol_mc_receiver_get_mc_primitives_count(NULL, &count), RES_BAD_ARG); @@ -480,8 +480,10 @@ main(int argc, char** argv) CHECK(ssol_estimator_get_mc_global(estimator, &mc_global), RES_OK); printf("Shadows = %g +/- %g; ", mc_global.shadowed.E, mc_global.shadowed.SE); printf("Missing = %g +/- %g; ", mc_global.missing.E, mc_global.missing.SE); + printf("Cos = %g +/- %g; ", mc_global.cos_loss.E, mc_global.cos_loss.SE); CHECK(eq_eps(mc_global.shadowed.E, 0, 1e-4), 1); CHECK(eq_eps(mc_global.missing.E, 0, 1e-4), 1); + CHECK(eq_eps(mc_global.cos_loss.E, (1 - COS)*(4 * DNI), 1e-4), 1); CHECK(GET_MC_RCV(estimator, target, SSOL_FRONT, &mc_rcv), RES_OK); printf("Ir(target) = %g +/- %g\n", mc_rcv.integrated_irradiance.E, mc_rcv.integrated_irradiance.SE);