solstice-solver

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

commit fcee059601c6901d5f4592ae3da3e20b9c18df79
parent 3face32bdf729929c34ac339cd62393cdba13ce8
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 13 Feb 2017 17:52:48 +0100

Cos loss computation (per receiver).

Diffstat:
Msrc/ssol.h | 1+
Msrc/ssol_estimator.c | 10++++++++++
Msrc/ssol_estimator_c.h | 4+++-
Msrc/ssol_solver.c | 13++++++++++---
Msrc/test_ssol_solver1.c | 30++++++++++++++++++++++--------
5 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -258,6 +258,7 @@ struct ssol_estimator_status { struct ssol_mc_result irradiance; struct ssol_mc_result absorptivity_loss; struct ssol_mc_result reflectivity_loss; + struct ssol_mc_result cos_loss; size_t N; /* Samples count */ size_t Nf; /* Failed samples count */ }; diff --git a/src/ssol_estimator.c b/src/ssol_estimator.c @@ -123,6 +123,9 @@ ssol_estimator_get_status status->reflectivity_loss.E = 0; status->reflectivity_loss.V = 0; status->reflectivity_loss.SE = 0; + status->cos_loss.E = 0; + status->cos_loss.V = 0; + status->cos_loss.SE = 0; return RES_OK; } @@ -166,6 +169,13 @@ ssol_estimator_get_receiver_status status->reflectivity_loss.SE = (status->reflectivity_loss.V > 0) ? sqrt(status->reflectivity_loss.V / (double) status->N) : 0; + status->cos_loss.E = data->cos_loss.weight / (double) status->N; + status->cos_loss.V + = data->cos_loss.sqr_weight / (double) status->N + - status->cos_loss.E * status->cos_loss.E; + status->cos_loss.SE + = (status->cos_loss.V > 0) ? + sqrt(status->cos_loss.V / (double) status->N) : 0; return RES_OK; } diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h @@ -41,9 +41,11 @@ struct mc_per_receiver_1side_data { struct mc_data irradiance; struct mc_data absorptivity_loss; struct mc_data reflectivity_loss; + struct mc_data cos_loss; }; -#define MC_RECV_1SIDE_DATA_NULL__ { MC_DATA_NULL__, MC_DATA_NULL__, MC_DATA_NULL__ } +#define MC_RECV_1SIDE_DATA_NULL__ {\ + MC_DATA_NULL__, MC_DATA_NULL__, MC_DATA_NULL__, MC_DATA_NULL__ } static const struct mc_per_receiver_1side_data MC_RECV_1SIDE_DATA_NULL = MC_RECV_1SIDE_DATA_NULL__; diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -54,8 +54,9 @@ struct point { float uv[2]; double wl; /* Sampled wavelength */ double weight; /* actual weight */ - double absorptivity_loss; /* weight with no amospheric effets */ - double reflectivity_loss; /* weight with no reflectivity effets */ + double absorptivity_loss; + double reflectivity_loss; + double cos_loss; enum ssol_side_flag side; }; @@ -92,6 +93,7 @@ point_init struct s3d_hit hit; struct ray_data ray_data = RAY_DATA_NULL; float dir[3], pos[3], range[2] = { 0, FLT_MAX }; + double cos_sun; size_t id; /* Sample a point into the scene view */ @@ -115,7 +117,9 @@ point_init ranst_sun_dir_get(ran_sun_dir, rng, pt->dir); /* Initialise the Monte Carlo weight */ - pt->weight = scn->sun->dni * sampled_area * fabs(d3_dot(pt->N, pt->dir)); + cos_sun = fabs(d3_dot(pt->N, pt->dir)); + pt->weight = scn->sun->dni * sampled_area * cos_sun; + pt->cos_loss = scn->sun->dni * sampled_area * (1 - cos_sun); pt->absorptivity_loss = pt->reflectivity_loss = 0; /* Retrieve the sampled instance and shaded shape */ @@ -485,6 +489,8 @@ ssol_solve data->absorptivity_loss.sqr_weight += pt.absorptivity_loss * pt.absorptivity_loss; data->reflectivity_loss.weight += pt.reflectivity_loss; data->reflectivity_loss.sqr_weight += pt.reflectivity_loss * pt.reflectivity_loss; + data->cos_loss.weight += pt.cos_loss; + data->cos_loss.sqr_weight += pt.cos_loss * pt.cos_loss; hit_a_receiver = 1; } @@ -572,6 +578,7 @@ ssol_solve ACCUM_WEIGHT(irradiance); ACCUM_WEIGHT(absorptivity_loss); ACCUM_WEIGHT(reflectivity_loss); + ACCUM_WEIGHT(cos_loss); #undef ACCUM_WEIGHT } } diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -261,7 +261,8 @@ main(int argc, char** argv) CHECK(fcount, 0); logger_print(&logger, LOG_OUTPUT, "\nIr = %g +/- %g", m, std); #define COS cos(PI / 4) -#define DNI_cos (1000 * COS) +#define DNI 1000 +#define DNI_cos (DNI * COS) CHECK(eq_eps(m, 4 * DNI_cos, MMAX(4 * DNI_cos * 1e-2, 2*std)), 1); #define SQR(x) ((x)*(x)) dbl = sqrt((SQR(12 * DNI_cos) / 3 - SQR(4 * DNI_cos)) / (double)count); @@ -397,7 +398,8 @@ main(int argc, char** argv) CHECK(fclose(tmp), 0); logger_print(&logger, LOG_OUTPUT, "\nIr = %g +/- %g", a_m, a_std); #define K (exp(-KA * 4 * sqrt(2))) - CHECK(eq_eps(a_m, REFLECTIVITY * 4 * K * DNI_cos, MMAX(4 * K * DNI_cos * 1e-1, a_std)), 1); + CHECK(eq_eps(a_m, REFLECTIVITY * 4 * K * DNI_cos, + MMAX(4 * K * DNI_cos * 1e-1, a_std)), 1); CHECK(eq_eps(a_std, 0, 1e-4), 1); CHECK(GET_STATUS(estimator, SSOL_STATUS_SHADOW, &status), RES_OK); logger_print(&logger, LOG_OUTPUT, "Shadows = %g +/- %g", @@ -408,15 +410,27 @@ main(int argc, char** argv) status.irradiance.E, status.irradiance.SE); CHECK(eq_eps(status.irradiance.E, 0, 1e-4), 1); CHECK(GET_RCV_STATUS(estimator, target, SSOL_FRONT, &status), RES_OK); - logger_print(&logger, LOG_OUTPUT, "Ir(target) = %g +/- %g (%.2g %%)", + logger_print(&logger, LOG_OUTPUT, + "Ir(target) = %g +/- %g (%.2g %%)", status.irradiance.E, status.irradiance.SE, 100 * status.irradiance.E / m); - logger_print(&logger, LOG_OUTPUT, "Atmospheric Loss(target) = %g +/- %g (%.2g %%)", - status.absorptivity_loss.E, status.absorptivity_loss.SE, 100 * status.absorptivity_loss.E / m); - logger_print(&logger, LOG_OUTPUT, "Reflectivity Loss(target) = %g +/- %g (%.2g %%)", - status.reflectivity_loss.E, status.reflectivity_loss.SE, 100 * status.reflectivity_loss.E / m); + logger_print(&logger, LOG_OUTPUT, + "Atmospheric Loss(target) = %g +/- %g (%.2g %%)", + status.absorptivity_loss.E, status.absorptivity_loss.SE, + 100 * status.absorptivity_loss.E / m); + logger_print(&logger, LOG_OUTPUT, + "Reflectivity Loss(target) = %g +/- %g (%.2g %%)", + status.reflectivity_loss.E, status.reflectivity_loss.SE, + 100 * status.reflectivity_loss.E / m); + logger_print(&logger, LOG_OUTPUT, + "Cos Loss(target) = %g +/- %g (%.2g %%)", + status.cos_loss.E, status.cos_loss.SE, 100 * status.cos_loss.E / m); CHECK(eq_eps(status.irradiance.E, a_m, 1e-8), 1); CHECK(eq_eps(status.irradiance.SE, a_std, 1e-4), 1); - CHECK(eq_eps(status.irradiance.E + status.absorptivity_loss.E + status.reflectivity_loss.E, m, 1e-8), 1); + CHECK(eq_eps(status.irradiance.E + status.absorptivity_loss.E + + status.reflectivity_loss.E, m, 1e-8), 1); + CHECK(eq_eps(status.irradiance.E + status.absorptivity_loss.E + + status.reflectivity_loss.E + status.cos_loss.E, 4 * DNI, 1e-8), 1); + CHECK(eq_eps(status.cos_loss.E / (4 * DNI), 1 - COS, 1e-8), 1); CHECK(ssol_estimator_ref_put(estimator), RES_OK); CHECK(ssol_scene_detach_instance(scene, heliostat2), RES_OK);