solstice-solver

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

test_ssol_solver12.c (7454B)


      1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2016, 2018 CNRS
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "ssol.h"
     18 #include "test_ssol_utils.h"
     19 #define REFLECTIVITY 0
     20 #include "test_ssol_materials.h"
     21 
     22 #include <rsys/math.h>
     23 
     24 #define X_SZ 10
     25 #define Y_SZ 10
     26 #define PLANE_NAME SQUARE
     27 #define HALF_X (X_SZ / 2)
     28 #define HALF_Y (Y_SZ / 2)
     29 STATIC_ASSERT((HALF_X * 2 == X_SZ), ONLY_ENVEN_VALUES_FOR_SQUARE_X);
     30 STATIC_ASSERT((HALF_Y * 2 == Y_SZ), ONLY_ENVEN_VALUES_FOR_SQUARE_Y);
     31 #include "test_ssol_rect_geometry.h"
     32 
     33 #define POLYGON_NAME POLY
     34 #define HALF_X (X_SZ / 2)
     35 #define HALF_Y (Y_SZ / 2)
     36 STATIC_ASSERT((HALF_X * 2 == X_SZ), ONLY_ENVEN_VALUES_FOR_X_SZ);
     37 STATIC_ASSERT((HALF_Y * 2 == Y_SZ), ONLY_ENVEN_VALUES_FOR_Y_SZ);
     38 #include "test_ssol_rect2D_geometry.h"
     39 
     40 #include <rsys/double33.h>
     41 
     42 #include <star/s3d.h>
     43 #include <star/ssp.h>
     44 
     45 static void
     46 get_wlen(const size_t i, double* wlen, double* data, void* ctx)
     47 {
     48   double wavelengths[3] = { 1, 2, 3 };
     49   double intensities[3] = { 1, 0.8, 1 };
     50   CHK(i < 3);
     51   (void) ctx;
     52   *wlen = wavelengths[i];
     53   *data = intensities[i];
     54 }
     55 
     56 int
     57 main(int argc, char** argv)
     58 {
     59   struct mem_allocator allocator;
     60   struct ssol_device* dev;
     61   struct ssp_rng* rng;
     62   struct ssol_scene* scene;
     63   struct ssol_shape* square;
     64   struct ssol_shape* parabol;
     65   struct ssol_vertex_data attribs[1] = { SSOL_VERTEX_DATA_NULL__ };
     66   struct ssol_material* m_mtl;
     67   struct ssol_matte_shader shader = SSOL_MATTE_SHADER_NULL;
     68   struct ssol_object* m_object;
     69   struct ssol_object* q_object;
     70   struct ssol_carving carving = SSOL_CARVING_NULL;
     71   struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
     72   struct ssol_punched_surface punched = SSOL_PUNCHED_SURFACE_NULL;
     73   struct ssol_instance* geom1;
     74   struct ssol_instance* geom2;
     75   struct ssol_sun* sun;
     76   struct ssol_spectrum* spectrum;
     77   struct ssol_estimator* estimator;
     78   struct ssol_mc_global mc_global1;
     79   struct ssol_mc_global mc_global2;
     80   struct ssol_mc_receiver mc_rcv1;
     81   struct ssol_mc_receiver mc_rcv2;
     82   double dir[3];
     83   double transform[12]; /* 3x4 column major matrix */
     84   size_t count;
     85 
     86   (void) argc, (void) argv;
     87   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     88 
     89   d33_set_identity(transform);
     90 
     91   CHK(ssol_device_create
     92     (NULL, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev) == RES_OK);
     93 
     94 #define DNI 1000
     95   CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK);
     96   CHK(ssol_spectrum_create(dev, &spectrum) == RES_OK);
     97   CHK(ssol_spectrum_setup(spectrum, get_wlen, 3, NULL) == RES_OK);
     98   CHK(ssol_sun_create_gaussian(dev, &sun) == RES_OK);
     99   CHK(ssol_sun_gaussian_set_std_dev(sun, 0.01) == RES_OK);
    100   CHK(ssol_sun_set_direction(sun, d3(dir, 0, 0, -1)) == RES_OK);
    101   CHK(ssol_sun_set_spectrum(sun, spectrum) == RES_OK);
    102   CHK(ssol_sun_set_dni(sun, DNI) == RES_OK);
    103   CHK(ssol_scene_create(dev, &scene) == RES_OK);
    104   CHK(ssol_scene_attach_sun(scene, sun) == RES_OK);
    105 
    106   /* Create scene content */
    107 
    108   CHK(ssol_shape_create_mesh(dev, &square) == RES_OK);
    109   attribs[0].usage = SSOL_POSITION;
    110   attribs[0].get = get_position;
    111   CHK(ssol_mesh_setup(square, SQUARE_NTRIS__, get_ids,
    112     SQUARE_NVERTS__, attribs, 1, (void*) &SQUARE_DESC__) == RES_OK);
    113 
    114   CHK(ssol_material_create_matte(dev, &m_mtl) == RES_OK);
    115   shader.normal = get_shader_normal;
    116   shader.reflectivity = get_shader_reflectivity_2;
    117   CHK(ssol_matte_setup(m_mtl, &shader) == RES_OK);
    118 
    119   CHK(ssol_object_create(dev, &m_object) == RES_OK);
    120   CHK(ssol_object_add_shaded_shape(m_object, square, m_mtl, m_mtl) == RES_OK);
    121   CHK(ssol_object_instantiate(m_object, &geom1) == RES_OK);
    122   CHK(ssol_instance_set_receiver(geom1, SSOL_FRONT, 0) == RES_OK);
    123   d3_splat(transform + 9, 0);
    124   transform[9] = -10;
    125   CHK(ssol_instance_set_transform(geom1, transform) == RES_OK);
    126   CHK(ssol_scene_attach_instance(scene, geom1) == RES_OK);
    127 
    128 #define N1__ 10000
    129 #define GET_MC_RCV ssol_estimator_get_mc_receiver
    130   CHK(ssol_solve(scene, rng, N1__, 0, NULL, &estimator) == RES_OK);
    131   CHK(ssol_estimator_get_realisation_count(estimator, &count) == RES_OK);
    132   CHK(count == N1__);
    133   CHK(ssol_estimator_get_failed_count(estimator, &count) == RES_OK);
    134   CHK(count == 0);
    135 #define DNI_S (DNI * X_SZ * Y_SZ)
    136   CHK(ssol_estimator_get_mc_global(estimator, &mc_global1) == RES_OK);
    137   CHK(GET_MC_RCV(estimator, geom1, SSOL_FRONT, &mc_rcv1) == RES_OK);
    138 
    139   print_global(&mc_global1);
    140   print_rcv(&mc_rcv1);
    141   CHK(mc_global1.cos_factor.E == 1);
    142   CHK(mc_global1.cos_factor.SE == 0);
    143   CHK(mc_global1.absorbed_by_receivers.E == DNI_S);
    144   CHK(mc_global1.absorbed_by_receivers.SE == 0);
    145 
    146   CHK(ssol_shape_create_punched_surface(dev, &parabol) == RES_OK);
    147   carving.get = get_polygon_vertices;
    148   carving.operation = SSOL_AND;
    149   carving.nb_vertices = POLY_NVERTS__;
    150   carving.context = &POLY_EDGES__;
    151   quadric.type = SSOL_QUADRIC_PARABOL;
    152   quadric.data.parabol.focal = 10;
    153   punched.nb_carvings = 1;
    154   punched.quadric = &quadric;
    155   punched.carvings = &carving;
    156   CHK(ssol_punched_surface_setup(parabol, &punched) == RES_OK);
    157 
    158   CHK(ssol_object_create(dev, &q_object) == RES_OK);
    159   CHK(ssol_object_add_shaded_shape(q_object, parabol, m_mtl, m_mtl) == RES_OK);
    160   CHK(ssol_object_instantiate(q_object, &geom2) == RES_OK);
    161   CHK(ssol_instance_set_receiver(geom2, SSOL_FRONT, 0) == RES_OK);
    162   d3_splat(transform + 9, 0);
    163   transform[9] = +10;
    164   CHK(ssol_instance_set_transform(geom2, transform) == RES_OK);
    165   CHK(ssol_scene_attach_instance(scene, geom2) == RES_OK);
    166 
    167   CHK(ssol_scene_detach_instance(scene, geom1) == RES_OK);
    168   CHK(ssol_estimator_ref_put(estimator) == RES_OK);
    169 
    170 #define N2__ 100000
    171   CHK(ssol_solve(scene, rng, N2__, 0, NULL, &estimator) == RES_OK);
    172   CHK(ssol_estimator_get_realisation_count(estimator, &count) == RES_OK);
    173   CHK(count == N2__);
    174   CHK(ssol_estimator_get_failed_count(estimator, &count) == RES_OK);
    175   CHK(count == 0);
    176   CHK(ssol_estimator_get_mc_global(estimator, &mc_global2) == RES_OK);
    177   CHK(GET_MC_RCV(estimator, geom2, SSOL_FRONT, &mc_rcv2) == RES_OK);
    178 
    179   print_global(&mc_global2);
    180   print_rcv(&mc_rcv2);
    181   CHK(eq_eps(mc_global2.absorbed_by_receivers.E, DNI_S, 3 * mc_global2.absorbed_by_receivers.SE) == 1);
    182 
    183   /* Free data */
    184   CHK(ssol_instance_ref_put(geom1) == RES_OK);
    185   CHK(ssol_instance_ref_put(geom2) == RES_OK);
    186   CHK(ssol_object_ref_put(m_object) == RES_OK);
    187   CHK(ssol_object_ref_put(q_object) == RES_OK);
    188   CHK(ssol_shape_ref_put(square) == RES_OK);
    189   CHK(ssol_shape_ref_put(parabol) == RES_OK);
    190   CHK(ssol_material_ref_put(m_mtl) == RES_OK);
    191   CHK(ssol_estimator_ref_put(estimator) == RES_OK);
    192   CHK(ssol_device_ref_put(dev) == RES_OK);
    193   CHK(ssol_scene_ref_put(scene) == RES_OK);
    194   CHK(ssp_rng_ref_put(rng) == RES_OK);
    195   CHK(ssol_spectrum_ref_put(spectrum) == RES_OK);
    196   CHK(ssol_sun_ref_put(sun) == RES_OK);
    197 
    198   check_memory_allocator(&allocator);
    199   mem_shutdown_proxy_allocator(&allocator);
    200   CHK(mem_allocated_size() == 0);
    201 
    202   return 0;
    203 }