solstice-solver

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

commit cc617d02ed44b931158f95d3cd9c5966d7525ee0
parent c0feeb38100aa38976301dbbae8e9d0ba57fea93
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  8 Sep 2017 14:00:51 +0200

Use mc_data deferred accumulation for glogal MC counters.

Diffstat:
Msrc/ssol_solver.c | 36++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -173,7 +173,8 @@ struct point { const struct ssol_material* material; /* tmp quantities to compute weights */ double kabs_at_pt; - double partial_atm, partial_recv, partial_other; + /* for conservation of energy check */ + double energy_loss; /* MC weights */ /* Set once */ double initial_flux; /* the initial flux*/ @@ -204,7 +205,8 @@ struct point { {0, 0}, /* UV */ \ 0, /* Wavelength */ \ NULL, /* Material */ \ - 0, 0, 0, 0, /* tmp values */ \ + 0, /* tmp values */ \ + 0, /* Energy loss */ \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MC weights */ \ SSOL_FRONT /* Side */ \ } @@ -306,7 +308,7 @@ point_init pt->cos_factor = surface_sun_cos; } - pt->partial_atm = pt->partial_recv = pt->partial_other = 0; + pt->energy_loss = w0; pt->initial_flux = w0; pt->prev_outgoing_flux = w0; pt->prev_outgoing_if_no_atm_loss = w0; @@ -682,7 +684,11 @@ update_mc res_T res = RES_OK; ASSERT(pt && thread_ctx && point_is_receiver(pt)); - pt->partial_recv += pt->incoming_flux - pt->outgoing_flux; + #define ACCUM_WEIGHT(Name, W)\ + mc_data_add_weight(&thread_ctx->Name, irealisation, W) + ACCUM_WEIGHT(absorbed_by_receivers, pt->incoming_flux - pt->outgoing_flux); + pt->energy_loss -= (pt->incoming_flux - pt->outgoing_flux); + #undef ACCUM_WEIGHT /* Per receiver MC accumulation */ res = get_mc_receiver_1side(&thread_ctx->mc_rcvs, pt->inst, pt->side, &mc_rcv1); @@ -799,6 +805,7 @@ trace_radiative_path if(!is_lit) { /* The starting point is not lit */ ACCUM_WEIGHT(pt.mc_samp->shadowed, pt.initial_flux); ACCUM_WEIGHT(thread_ctx->shadowed, pt.initial_flux); + pt.energy_loss -= pt.initial_flux; if(tracker) path.type = SSOL_PATH_SHADOW; } else { /* Setup the ray as if it starts from the current point position in order @@ -846,7 +853,8 @@ trace_radiative_path res = update_mc(&pt, irealisation, thread_ctx); if(res != RES_OK) goto error; } else { - pt.partial_other += pt.incoming_flux * pt.kabs_at_pt; + ACCUM_WEIGHT(thread_ctx->other_absorbed, + pt.incoming_flux * pt.kabs_at_pt); } /* Stop the radiative random walk if no more flux */ @@ -897,10 +905,14 @@ trace_radiative_path * a non-virtual material is hit or no further hit can be found. */ if(last_segment || !hit_virtual) { if(in_atm) { - pt.partial_atm += pt.prev_outgoing_flux - pt.incoming_flux; + ACCUM_WEIGHT(thread_ctx->absorbed_by_atmosphere, + pt.prev_outgoing_flux - pt.incoming_flux); } else { - pt.partial_other += pt.prev_outgoing_flux - pt.incoming_flux; + ACCUM_WEIGHT(thread_ctx->other_absorbed, + pt.prev_outgoing_flux - pt.incoming_flux); } + pt.energy_loss -= (pt.prev_outgoing_flux - pt.incoming_flux); + if(last_segment) { break; } @@ -922,21 +934,17 @@ trace_radiative_path ssol_medium_copy(&in_medium, &out_medium); } - /* Check conservation of energy */ - ASSERT((double)depth * pt.initial_flux * DBL_EPSILON >= - fabs(pt.initial_flux - - (pt.outgoing_flux + pt.partial_recv + pt.partial_atm + pt.partial_other))); /* Now that the sample ends successfully, * record MC weights and register the remaining power as missing */ ACCUM_WEIGHT(pt.mc_samp->cos_factor, pt.cos_factor); ACCUM_WEIGHT(thread_ctx->cos_factor, pt.cos_factor); ACCUM_WEIGHT(thread_ctx->missing, pt.outgoing_flux); - ACCUM_WEIGHT(thread_ctx->absorbed_by_receivers, pt.partial_recv); - ACCUM_WEIGHT(thread_ctx->absorbed_by_atmosphere, pt.partial_atm); - ACCUM_WEIGHT(thread_ctx->other_absorbed, pt.partial_other); + pt.energy_loss -= pt.outgoing_flux; #undef ACCUM_WEIGHT + /* Check conservation of energy */ + ASSERT((double)depth*DBL_EPSILON*pt.initial_flux >= fabs(pt.energy_loss)); if(tracker) { path.type = hit_a_receiver ? SSOL_PATH_SUCCESS : SSOL_PATH_MISSING; }