solstice-solver

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

commit d4e76776f903fab8ab6769c777d4c6b9955c3451
parent a14788671ec6786440abdd2902d275e5569ab234
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Tue, 13 Sep 2016 09:25:15 +0200

Fix test solver #2

Diffstat:
Msrc/ssol_scene.c | 12++++--------
Msrc/ssol_solver_c.h | 18+++++++++---------
Msrc/test_ssol_solver1.c | 6+++++-
Msrc/test_ssol_solver2.c | 23++++++++++++++---------
4 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -290,11 +290,10 @@ hit_filter_function ASSERT(seg->self_instance); NCHECK(seg->self_front, 99); - /* Discard self intersection; using raytracing normal */ + /* Discard self intersection */ + seg->hit_front = f3_dot(hit->normal, dir) < 0; inst = *htable_instance_find(&rs->data.scene->instances_rt, &hit->prim.inst_id); - - int hit_front = f3_dot(hit->normal, dir) < 0; - if (seg->self_instance == inst && seg->self_front != hit_front) { + if (seg->self_instance == inst && seg->self_front != seg->hit_front) { return 1; } @@ -330,7 +329,6 @@ hit_filter_function /* transform normal to world */ d33_invtrans(tr, transform); d33_muld3(seg->hit_normal, tr, seg->hit_normal); - ASSERT(d3_dot(seg->hit_normal, d3_set_f3(tr, hit->normal)) > 0); break; } case SHAPE_MESH: { @@ -342,13 +340,11 @@ hit_filter_function default: FATAL("Unreachable code.\n"); break; } - seg->hit_front = d3_dot(seg->hit_normal, seg->dir) < 0; - ASSERT(hit_front == seg->hit_front); - if(seg->hit_front) { seg->hit_material = inst->object->mtl_front; receiver_name = &inst->receiver_front; } else { + d3_muld(seg->hit_normal, seg->hit_normal, -1); seg->hit_material = inst->object->mtl_back; receiver_name = &inst->receiver_back; } diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h @@ -58,16 +58,16 @@ enum realisation_mode { struct segment { const struct ssol_instance* hit_instance; - const struct ssol_instance* self_instance; + const struct ssol_instance* self_instance; /* instance of the starting point */ const struct ssol_material* hit_material; double weight; struct s3d_hit hit; double org[3], dir[4]; double hit_pos[3]; double hit_pos_local[3]; /* in local coordinate, only set on punched shapes */ - double hit_normal[3]; - char hit_front; - char self_front; + double hit_normal[3]; /* possibly reversed to face the incoming dir */ + char hit_front; /* is the ending point of the segment on the front face? */ + char self_front; /* was the starting point of the segment on the front face? */ char on_punched; /* is the hit on a punched shape? */ }; @@ -77,11 +77,11 @@ struct starting_point { struct s3d_primitive sampl_primitive; double sundir[3]; double pos[3]; - double pos_local[3]; /* in local coordinate, only set on quadrics */ - double normal[3]; /* oriented to face the sun*/ - double cos_sun; + double pos_local[3]; /* in local coordinate, only set on punched shapes */ + double normal[3]; /* oriented towards the sun*/ + double cos_sun; /* > 0 */ float uv[2]; - char front_exposed; + char front_exposed; /* if false, normal has been reversed */ char on_punched; /* is the point on a punched shape? */ }; @@ -104,7 +104,7 @@ struct solver_data { /* Tmp data used for propagation */ struct brdf_composite* brdfs; struct surface_fragment fragment; - + /* total area of the surface sampled as starting point candidate */ float sampled_area; }; diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -130,7 +130,6 @@ main(int argc, char** argv) CHECK(ssol_instance_set_target_mask(target, 0x4, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, target), RES_OK); - CHECK(ssol_solve(scene, rng, 20, stdout), RES_OK); tmp = tmpfile(); CHECK(!tmp, 0); #define N 10000 @@ -140,6 +139,7 @@ main(int argc, char** argv) CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-2), 1); #define SQR(x) ((x)*(x)) CHECK(eq_eps(std, sqrt((SQR(12 * DNI_cos) / 3 - SQR(4 * DNI_cos)) / N), 1e-1), 1); + logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); CHECK(fclose(tmp), 0); CHECK(ssol_instance_dont_sample(target, 1), RES_OK); @@ -147,11 +147,15 @@ main(int argc, char** argv) CHECK(ssol_instance_set_target_mask(heliostat, 0, 0), RES_OK); CHECK(ssol_instance_set_target_mask(secondary, 0, 0), RES_OK); CHECK(ssol_instance_set_target_mask(target, 0x1, 0), RES_OK); + + CHECK(ssol_solve(scene, rng, 20, stdout), RES_OK); + tmp = tmpfile(); CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1); CHECK(eq_eps(std, sqrt((SQR(4 * DNI_cos) - SQR(4 * DNI_cos)) / N), 1e-4), 1); + logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); /* free data */ diff --git a/src/test_ssol_solver2.c b/src/test_ssol_solver2.c @@ -62,6 +62,8 @@ main(int argc, char** argv) double transform2[12]; /* 3x4 column major matrix */ double polygon[] = { -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0 }; const size_t npolygon_verts = sizeof(polygon) / sizeof(double[2]); + FILE* tmp; + double m, std; (void) argc, (void) argv; @@ -95,12 +97,6 @@ main(int argc, char** argv) CHECK(ssol_scene_create(dev, &scene), RES_OK); CHECK(ssol_scene_attach_sun(scene, sun), RES_OK); - CHECK(ssol_solve(NULL, rng, 10, stdout), RES_BAD_ARG); - CHECK(ssol_solve(scene, NULL, 10, stdout), RES_BAD_ARG); - CHECK(ssol_solve(scene, rng, 0, stdout), RES_BAD_ARG); - CHECK(ssol_solve(scene, rng, 10, NULL), RES_BAD_ARG); - CHECK(ssol_solve(scene, rng, 10, stdout), RES_BAD_ARG); /* no geometry */ - /* create scene content */ CHECK(ssol_shape_create_mesh(dev, &square), RES_OK); @@ -130,25 +126,34 @@ main(int argc, char** argv) CHECK(ssol_object_create(dev, square, m_mtl, m_mtl, &m_object), RES_OK); CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK); CHECK(ssol_instance_set_receiver(heliostat, "miroir", NULL), RES_OK); - CHECK(ssol_instance_set_target_mask(heliostat, 0x1, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, heliostat), RES_OK); CHECK(ssol_object_create(dev, quad_square, m_mtl, m_mtl, &s_object), RES_OK); CHECK(ssol_object_instantiate(s_object, &secondary), RES_OK); CHECK(ssol_instance_set_receiver(secondary, "secondaire", NULL), RES_OK); CHECK(ssol_instance_set_transform(secondary, transform1), RES_OK); - CHECK(ssol_instance_set_target_mask(secondary, 0x2, 0), RES_OK); + CHECK(ssol_instance_dont_sample(secondary, 1), RES_OK); CHECK(ssol_scene_attach_instance(scene, secondary), RES_OK); CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK); CHECK(ssol_object_instantiate(t_object, &target), RES_OK); CHECK(ssol_instance_set_transform(target, transform2), RES_OK); CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK); - CHECK(ssol_instance_set_target_mask(target, 0x4, 0), RES_OK); + CHECK(ssol_instance_set_target_mask(target, 0x1, 0), RES_OK); + CHECK(ssol_instance_dont_sample(target, 1), RES_OK); CHECK(ssol_scene_attach_instance(scene, target), RES_OK); CHECK(ssol_solve(scene, rng, 20, stdout), RES_OK); + tmp = tmpfile(); +#define N 10000 + CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); + CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); +#define DNI_cos (1000 * cos(PI / 4)) + CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1); +#define SQR(x) ((x)*(x)) + CHECK(eq_eps(std, sqrt((SQR(4 * DNI_cos) - SQR(4 * DNI_cos)) / N), 1e-4), 1); + logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std); /* free data */ CHECK(ssol_instance_ref_put(heliostat), RES_OK);