solstice-solver

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

commit d0ca1b8cda44b4db1caef59b0364225d080a064b
parent 813b783dc007bb67692e3dd30856ad0a93abc490
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 24 Mar 2017 13:07:27 +0100

Add a test where the mirror is a mesh.

Diffstat:
Mcmake/CMakeLists.txt | 1+
Asrc/test_ssol_cube_geometry.h | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/test_ssol_solver9.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 292 insertions(+), 0 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -170,6 +170,7 @@ if(NOT NO_TEST) new_test(test_ssol_solver6) new_test(test_ssol_solver7) new_test(test_ssol_solver8) + new_test(test_ssol_solver9) new_test(test_ssol_sun) build_test(test_ssol_draw) diff --git a/src/test_ssol_cube_geometry.h b/src/test_ssol_cube_geometry.h @@ -0,0 +1,107 @@ +/* Copyright (C) CNRS 2016-2017 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "test_ssol_geometries.h" + +/******************************************************************************* +* Rectangle polygon +******************************************************************************/ +#if !defined(HALF_X) && !(defined(X_MIN) && defined(X_MAX)) +#error "Missing the HALF_X or X_MIN and X_MAX macros defining the cube size" +#endif +#if !defined(HALF_Y) && !(defined(Y_MIN) && defined(Y_MAX)) +#error "Missing the HALF_Y or Y_MIN and Y_MAX macros defining the cube size" +#endif +#if !defined(HALF_Z) && !(defined(Z_MIN) && defined(Z_MAX)) +#error "Missing the HALF_Z or Z_MIN and Z_MAX macros defining the cube size" +#endif +#if !defined(CUBE_NAME) +#error "Missing the CUBE_NAME macro defining the rectangle name" +#endif + +#define EDGES__ CONCAT(CUBE_NAME, _EDGES__) +#define CUBE_NVERTS__ CONCAT(CUBE_NAME, _NVERTS__) + +#if !defined(X_MIN) +#define X_MIN (float)(-(HALF_X)) +#endif + +#if !defined(X_MAX) +#define X_MAX (float)(HALF_X) +#endif + +#if !defined(Y_MIN) +#define Y_MIN (float)(-(HALF_Y)) +#endif + +#if !defined(Y_MAX) +#define Y_MAX (float)(HALF_Y) +#endif + +#if !defined(Z_MIN) +#define Z_MIN (float)(-(HALF_Z)) +#endif + +#if !defined(Z_MAX) +#define Z_MAX (float)(HALF_Z) +#endif + +static const float EDGES__ [] = { + X_MIN, Y_MIN, Z_MIN, + X_MIN, Y_MIN, Z_MAX, + X_MIN, Y_MAX, Z_MIN, + X_MIN, Y_MAX, Z_MAX, + X_MAX, Y_MIN, Z_MIN, + X_MAX, Y_MIN, Z_MAX, + X_MAX, Y_MAX, Z_MIN, + X_MAX, Y_MAX, Z_MAX +}; + +const unsigned CUBE_NVERTS__ = sizeof(EDGES__) / sizeof(float[3]); + +const unsigned TRG_IDS__ [] = { + 0, 6, 4, + 0, 2, 6, + 0, 3, 2, + 0, 1, 3, + 2, 7, 6, + 2, 3, 7, + 4, 6, 7, + 4, 7, 5, + 0, 4, 5, + 0, 5, 1, + 1, 5, 7, + 1, 7, 3 +}; +const unsigned CUBE_NTRIS__ = sizeof(TRG_IDS__) / sizeof(unsigned[3]); + +static const struct desc CUBE_DESC__ = { EDGES__, TRG_IDS__ }; + +#undef EDGES__ +#undef TRG_IDS__ +#undef CUBE_DESC__ +#undef CUBE_NVERTS__ +#undef CUBE_NTRIS__ + +#undef HALF_X +#undef HALF_Y +#undef HALF_Z +#undef X_MIN +#undef X_MAX +#undef Y_MIN +#undef Y_MAX +#undef Z_MIN +#undef Z_MAX +#undef CUBE_NAME diff --git a/src/test_ssol_solver9.c b/src/test_ssol_solver9.c @@ -0,0 +1,184 @@ +/* Copyright (C) CNRS 2016-2017 +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "ssol.h" +#include "test_ssol_utils.h" +#include "test_ssol_materials.h" + +#include <rsys/math.h> + +#define TGT_X 6 +#define TGT_Y 10 +#define PLANE_NAME TARGET +#define HALF_X (TGT_X / 2) +#define HALF_Y (TGT_Y / 2) +STATIC_ASSERT((HALF_X * 2 == TGT_X), ONLY_ENVEN_VALUES_FOR_TGT_X); +STATIC_ASSERT((HALF_Y * 2 == TGT_Y), ONLY_ENVEN_VALUES_FOR_TGT_Y); +#include "test_ssol_rect_geometry.h" + +#define SZ MMAX(TGT_X, TGT_Y) +#define CUBE_NAME CUBE +#define HALF_X (SZ / 2) +#define HALF_Y (SZ / 2) +#define HALF_Z (SZ / 2) +STATIC_ASSERT((HALF_X * 2 == SZ), ONLY_ENVEN_VALUES_FOR_SZ); +#include "test_ssol_cube_geometry.h" + +#include <rsys/double33.h> + +#include <star/s3d.h> +#include <star/ssp.h> + +static void +get_wlen(const size_t i, double* wlen, double* data, void* ctx) +{ + double wavelengths[3] = { 1, 2, 3 }; + double intensities[3] = { 1, 0.8, 1 }; + CHECK(i < 3, 1); + (void) ctx; + *wlen = wavelengths[i]; + *data = intensities[i]; +} + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct ssol_device* dev; + struct ssp_rng* rng; + struct ssol_scene* scene; + struct ssol_shape* square; + struct ssol_vertex_data attribs[1] = { SSOL_VERTEX_DATA_NULL__ }; + struct ssol_shape* cube; + struct ssol_material* m_mtl; + struct ssol_material* v_mtl; + struct ssol_mirror_shader shader = SSOL_MIRROR_SHADER_NULL; + struct ssol_object* m_object; + struct ssol_object* t_object; + struct ssol_instance* heliostat; + struct ssol_instance* target; + struct ssol_sun* sun; + struct ssol_spectrum* spectrum; + struct ssol_estimator* estimator; + struct ssol_mc_global mc_global; + struct ssol_mc_receiver mc_rcv; + double dir[3]; + double transform[12]; /* 3x4 column major matrix */ + size_t count; + FILE* tmp; + uint32_t r_id; + + (void) argc, (void) argv; + d3_splat(transform + 9, 0); + d33_rotation_pitch(transform, PI); /* flip faces: invert normal */ + transform[11] = 6; /* set it above the cube */ + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + + CHECK(ssol_device_create + (NULL, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK); + +#define DNI 1000 + CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK); + CHECK(ssol_spectrum_create(dev, &spectrum), RES_OK); + CHECK(ssol_spectrum_setup(spectrum, get_wlen, 3, NULL), RES_OK); + CHECK(ssol_sun_create_directional(dev, &sun), RES_OK); + CHECK(ssol_sun_set_direction(sun, d3(dir, 0, 0, -1)), RES_OK); + CHECK(ssol_sun_set_spectrum(sun, spectrum), RES_OK); + CHECK(ssol_sun_set_dni(sun, DNI), RES_OK); + CHECK(ssol_scene_create(dev, &scene), RES_OK); + CHECK(ssol_scene_attach_sun(scene, sun), RES_OK); + + /* Create scene content */ + + CHECK(ssol_shape_create_mesh(dev, &square), RES_OK); + attribs[0].usage = SSOL_POSITION; + attribs[0].get = get_position; + CHECK(ssol_mesh_setup(square, TARGET_NTRIS__, get_ids, + TARGET_NVERTS__, attribs, 1, (void*) &TARGET_DESC__), RES_OK); + + CHECK(ssol_shape_create_mesh(dev, &cube), RES_OK); + CHECK(ssol_mesh_setup(cube, CUBE_NTRIS__, get_ids, + CUBE_NVERTS__, attribs, 1, (void*) &CUBE_DESC__), RES_OK); + + CHECK(ssol_material_create_mirror(dev, &m_mtl), RES_OK); + shader.normal = get_shader_normal; + shader.reflectivity = get_shader_reflectivity; + shader.roughness = get_shader_roughness; + CHECK(ssol_mirror_set_shader(m_mtl, &shader), RES_OK); + CHECK(ssol_material_create_virtual(dev, &v_mtl), RES_OK); + + CHECK(ssol_object_create(dev, &m_object), RES_OK); + CHECK(ssol_object_add_shaded_shape(m_object, cube, m_mtl, m_mtl), RES_OK); + CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK); + CHECK(ssol_scene_attach_instance(scene, heliostat), RES_OK); + + CHECK(ssol_object_create(dev, &t_object), RES_OK); + CHECK(ssol_object_add_shaded_shape(t_object, square, v_mtl, v_mtl), RES_OK); + CHECK(ssol_object_instantiate(t_object, &target), RES_OK); + CHECK(ssol_instance_set_transform(target, transform), RES_OK); + CHECK(ssol_instance_set_receiver(target, SSOL_FRONT, 0), RES_OK); + CHECK(ssol_instance_sample(target, 0), RES_OK); + CHECK(ssol_scene_attach_instance(scene, target), RES_OK); + + NCHECK(tmp = tmpfile(), 0); +#define N__ 100000 +#define GET_MC_RCV ssol_estimator_get_mc_receiver + CHECK(ssol_solve(scene, rng, N__, 0, tmp, &estimator), RES_OK); + CHECK(ssol_instance_get_id(target, &r_id), RES_OK); + CHECK(ssol_estimator_get_count(estimator, &count), RES_OK); + CHECK(count, N__); + CHECK(fclose(tmp), 0); + CHECK(ssol_estimator_get_failed_count(estimator, &count), RES_OK); + CHECK(count, 0); +#define DNI_TGT_S (DNI * TGT_X * TGT_Y) +#define DNI_S (DNI * SZ * SZ) + CHECK(ssol_estimator_get_mc_global(estimator, &mc_global), RES_OK); + printf("Cos = %g +/- %g\n", mc_global.cos_loss.E, mc_global.cos_loss.SE); + printf("Shadows = %g +/- %g\n", mc_global.shadowed.E, mc_global.shadowed.SE); + printf("Missing = %g +/- %g\n", mc_global.missing.E, mc_global.missing.SE); + /* CHECK(eq_eps(mc_global.cos_loss.E, 4 * DNI_S, DNI_S * 1e-4), 1); */ + CHECK(eq_eps(mc_global.shadowed.E, DNI_S, 3 * mc_global.shadowed.SE), 1); + CHECK(eq_eps(mc_global.missing.E, + MMAX(DNI_S, DNI_TGT_S) - MMIN(DNI_S, DNI_TGT_S), + 3 * mc_global.missing.SE), 1); + CHECK(GET_MC_RCV(estimator, target, SSOL_FRONT, &mc_rcv), RES_OK); + printf("Ir(target1) = %g +/- %g\n", + mc_rcv.integrated_irradiance.E, mc_rcv.integrated_irradiance.SE); + CHECK(eq_eps(mc_rcv.integrated_irradiance.E, MMIN(DNI_S, DNI_TGT_S), + 3 * mc_rcv.integrated_irradiance.SE), 1); + + /* Free data */ + CHECK(ssol_instance_ref_put(heliostat), RES_OK); + CHECK(ssol_instance_ref_put(target), RES_OK); + CHECK(ssol_object_ref_put(m_object), RES_OK); + CHECK(ssol_object_ref_put(t_object), RES_OK); + CHECK(ssol_shape_ref_put(square), RES_OK); + CHECK(ssol_shape_ref_put(cube), RES_OK); + CHECK(ssol_material_ref_put(m_mtl), RES_OK); + CHECK(ssol_material_ref_put(v_mtl), RES_OK); + CHECK(ssol_estimator_ref_put(estimator), RES_OK); + CHECK(ssol_device_ref_put(dev), RES_OK); + CHECK(ssol_scene_ref_put(scene), RES_OK); + CHECK(ssp_rng_ref_put(rng), RES_OK); + CHECK(ssol_spectrum_ref_put(spectrum), RES_OK); + CHECK(ssol_sun_ref_put(sun), RES_OK); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHECK(mem_allocated_size(), 0); + + return 0; +}