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:
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;
+}