stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

test_sdis_scene.c (19471B)


      1 /* Copyright (C) 2016-2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "sdis.h"
     17 #include "test_sdis_utils.h"
     18 
     19 #include <rsys/double2.h>
     20 #include <rsys/double3.h>
     21 #include <rsys/math.h>
     22 #include <star/senc2d.h>
     23 #include <star/senc3d.h>
     24 
     25 struct context {
     26   const double* positions;
     27   const size_t* indices;
     28   struct sdis_interface* interf;
     29 };
     30 
     31 static INLINE double
     32 rand_canonic()
     33 {
     34   return (double)rand()/(double)((double)RAND_MAX+1);
     35 }
     36 
     37 static INLINE void
     38 get_indices_3d(const size_t itri, size_t ids[3], void* context)
     39 {
     40   struct context* ctx = context;
     41   CHK(ctx != NULL);
     42   CHK(itri < box_ntriangles);
     43   ids[0] = ctx->indices[itri*3+0];
     44   ids[1] = ctx->indices[itri*3+1];
     45   ids[2] = ctx->indices[itri*3+2];
     46 }
     47 
     48 static INLINE void
     49 get_indices_2d(const size_t iseg, size_t ids[2], void* context)
     50 {
     51   struct context* ctx = context;
     52   CHK(ctx != NULL);
     53   CHK(iseg < square_nsegments);
     54   ids[0] = ctx->indices[iseg*2+0];
     55   ids[1] = ctx->indices[iseg*2+1];
     56 }
     57 
     58 static INLINE void
     59 get_position_3d(const size_t ivert, double pos[3], void* context)
     60 {
     61   struct context* ctx = context;
     62   CHK(ctx != NULL);
     63   CHK(ivert < box_nvertices);
     64   pos[0] = ctx->positions[ivert*3+0];
     65   pos[1] = ctx->positions[ivert*3+1];
     66   pos[2] = ctx->positions[ivert*3+2];
     67 }
     68 
     69 static INLINE void
     70 get_position_2d(const size_t ivert, double pos[2], void* context)
     71 {
     72   struct context* ctx = context;
     73   CHK(ctx != NULL);
     74   CHK(ivert < square_nvertices);
     75   pos[0] = ctx->positions[ivert*2+0];
     76   pos[1] = ctx->positions[ivert*2+1];
     77 }
     78 
     79 static INLINE void
     80 get_interface(const size_t itri, struct sdis_interface** bound, void* context)
     81 {
     82   struct context* ctx = context;
     83   CHK(ctx != NULL);
     84   CHK(itri < box_ntriangles);
     85   CHK(bound != NULL);
     86   *bound = ctx->interf;
     87 }
     88 
     89 static void
     90 test_scene_3d
     91   (struct sdis_device* dev,
     92    struct sdis_interface* interf,
     93    struct sdis_radiative_env* in_radenv)
     94 {
     95   size_t duplicated_indices[] = { 0, 1, 2, 0, 2, 1 };
     96   size_t degenerated_indices[] = { 0, 1, 1 };
     97   double duplicated_vertices[] = { 0, 0, 0, 1, 1, 1, 0, 0, 0 };
     98   double lower[3], upper[3];
     99   double uv0[2], uv1[2], uv2[2], pos[3], pos1[3];
    100   struct context ctx;
    101   struct senc2d_scene* scn2d;
    102   struct senc3d_scene* scn3d;
    103   struct s2d_scene_view* view2d;
    104   struct s3d_scene_view* view3d;
    105   struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT;
    106   struct sdis_scene_find_closest_point_args closest_pt_args =
    107     SDIS_SCENE_FIND_CLOSEST_POINT_ARGS_NULL;
    108   struct sdis_scene* scn = NULL;
    109   struct sdis_device* dev2 = NULL;
    110   struct sdis_radiative_env* radenv = NULL;
    111   size_t ntris, npos;
    112   size_t iprim;
    113   size_t i;
    114   double dst = 0;
    115   size_t dup_vrtx_indices[] = { 0, 1, 2 };
    116   enum sdis_scene_dimension dim;
    117 
    118   ctx.positions = box_vertices;
    119   ctx.indices = box_indices;
    120   ctx.interf = interf;
    121   ntris = box_ntriangles;
    122   npos = box_nvertices;
    123 
    124   scn_args.get_indices = get_indices_3d;
    125   scn_args.get_interface = get_interface;
    126   scn_args.get_position = get_position_3d;
    127   scn_args.nprimitives = ntris;
    128   scn_args.nvertices = npos;
    129   scn_args.context = &ctx;
    130   BA(sdis_scene_create(NULL, &SDIS_SCENE_CREATE_ARGS_DEFAULT, NULL));
    131   BA(sdis_scene_create(NULL, &SDIS_SCENE_CREATE_ARGS_DEFAULT, NULL));
    132 
    133   scn_args.nprimitives = 0;
    134   BA(sdis_scene_create(dev, &scn_args, &scn));
    135   scn_args.nprimitives = ntris;
    136   scn_args.get_indices = NULL;
    137   BA(sdis_scene_create(dev, &scn_args, &scn));
    138   scn_args.get_indices = get_indices_3d;
    139   scn_args.get_interface = NULL;
    140   BA(sdis_scene_create(dev, &scn_args, &scn));
    141   scn_args.get_interface = get_interface;
    142   scn_args.get_position = NULL;
    143   BA(sdis_scene_create(dev, &scn_args, &scn));
    144   scn_args.get_position = get_position_3d;
    145   scn_args.nvertices = 0;
    146   BA(sdis_scene_create(dev, &scn_args, &scn));
    147   scn_args.nvertices = npos;
    148   scn_args.fp_to_meter = 0;
    149   BA(sdis_scene_create(dev, &scn_args, &scn));
    150   scn_args.fp_to_meter = 1;
    151   /* Duplicated vertex */
    152   ctx.positions = duplicated_vertices;
    153   ctx.indices = dup_vrtx_indices;
    154   BA(sdis_scene_create(dev, &scn_args, &scn));
    155   /* Duplicated triangle */
    156   ctx.positions = box_vertices;
    157   ctx.indices = duplicated_indices;
    158   BA(sdis_scene_create(dev, &scn_args, &scn));
    159   /* Degenerated triangle */
    160   ctx.indices = degenerated_indices;
    161   BA(sdis_scene_create(dev, &scn_args, &scn));
    162   ctx.positions = box_vertices;
    163   ctx.indices = box_indices;
    164   BA(sdis_scene_create(dev, &SDIS_SCENE_CREATE_ARGS_DEFAULT, &scn));
    165   BA(sdis_scene_create(NULL, &scn_args, &scn));
    166   BA(sdis_scene_create(dev, NULL, &scn));
    167   BA(sdis_scene_create(dev, &scn_args, NULL));
    168   OK(sdis_scene_create(dev, &scn_args, &scn));
    169 
    170   BA(sdis_scene_get_dimension(NULL, &dim));
    171   BA(sdis_scene_get_dimension(scn, NULL));
    172   OK(sdis_scene_get_dimension(scn, &dim));
    173   CHK(dim == SDIS_SCENE_3D);
    174 
    175   BA(sdis_scene_get_device(NULL, &dev2));
    176   BA(sdis_scene_get_device(scn, NULL));
    177   OK(sdis_scene_get_device(scn, &dev2));
    178   CHK(dev == dev2);
    179 
    180   BA(sdis_scene_get_aabb(NULL, lower, upper));
    181   BA(sdis_scene_get_aabb(scn, NULL, upper));
    182   BA(sdis_scene_get_aabb(scn, lower, NULL));
    183   OK(sdis_scene_get_aabb(scn, lower, upper));
    184   CHK(eq_eps(lower[0], 0, 1.e-6));
    185   CHK(eq_eps(lower[1], 0, 1.e-6));
    186   CHK(eq_eps(lower[2], 0, 1.e-6));
    187   CHK(eq_eps(upper[0], 1, 1.e-6));
    188   CHK(eq_eps(upper[1], 1, 1.e-6));
    189   CHK(eq_eps(upper[2], 1, 1.e-6));
    190 
    191   uv0[0] = 0.3;
    192   uv0[1] = 0.3;
    193 
    194   BA(sdis_scene_get_boundary_position(NULL, 6, uv0, pos));
    195   BA(sdis_scene_get_boundary_position(scn, 12, uv0, pos));
    196   BA(sdis_scene_get_boundary_position(scn, 6, NULL, pos));
    197   BA(sdis_scene_get_boundary_position(scn, 6, uv0, NULL));
    198   OK(sdis_scene_get_boundary_position(scn, 6, uv0, pos) );
    199 
    200   BA(sdis_scene_boundary_project_position(NULL, 6, pos, uv1));
    201   BA(sdis_scene_boundary_project_position(scn, 12, pos, uv1));
    202   BA(sdis_scene_boundary_project_position(scn, 6, NULL, uv1));
    203   BA(sdis_scene_boundary_project_position(scn, 6, pos, NULL));
    204   OK(sdis_scene_boundary_project_position(scn, 6, pos, uv1));
    205 
    206   closest_pt_args.position[0] = pos[0];
    207   closest_pt_args.position[1] = pos[1];
    208   closest_pt_args.position[2] = pos[2];
    209   closest_pt_args.radius = INF;
    210   BA(sdis_scene_find_closest_point(NULL, &closest_pt_args, &iprim, uv2));
    211   BA(sdis_scene_find_closest_point(scn, NULL, &iprim, uv2));
    212   BA(sdis_scene_find_closest_point(scn, &closest_pt_args, NULL, uv2));
    213   BA(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, NULL));
    214   OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, uv2));
    215 
    216   CHK(iprim == 6);
    217   CHK(d2_eq_eps(uv0, uv1, 1.e-6));
    218   CHK(d2_eq_eps(uv1, uv2, 1.e-6));
    219 
    220   pos[0] = 0.5;
    221   pos[1] = 0.1;
    222   pos[2] = 0.25;
    223   closest_pt_args.position[0] = pos[0];
    224   closest_pt_args.position[1] = pos[1];
    225   closest_pt_args.position[2] = pos[2];
    226   OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, uv2));
    227   CHK(iprim == 10);
    228 
    229   OK(sdis_scene_boundary_project_position(scn, 10, pos, uv0));
    230   CHK(d2_eq_eps(uv0, uv2, 1.e-6));
    231 
    232   OK(sdis_scene_get_boundary_position(scn, iprim, uv2, pos1));
    233   dst = d3_len(d3_sub(pos1, pos, pos1));
    234   CHK(eq_eps(dst, 0.1, 1.e-6));
    235 
    236   closest_pt_args.position[0] = pos[0];
    237   closest_pt_args.position[1] = pos[1];
    238   closest_pt_args.position[2] = pos[2];
    239   closest_pt_args.radius = 0.09;
    240   OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, uv2));
    241   CHK(iprim == SDIS_PRIMITIVE_NONE);
    242 
    243   FOR_EACH(i, 0, 64) {
    244     uv0[0] = rand_canonic();
    245     uv0[1] = rand_canonic() * (1 - uv0[0]);
    246 
    247     OK(sdis_scene_get_boundary_position(scn, 4, uv0, pos));
    248     OK(sdis_scene_boundary_project_position(scn, 4, pos, uv1));
    249 
    250     closest_pt_args.position[0] = pos[0];
    251     closest_pt_args.position[1] = pos[1];
    252     closest_pt_args.position[2] = pos[2];
    253     closest_pt_args.radius = INF;
    254     OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, uv2));
    255     CHK(d2_eq_eps(uv0, uv1, 1.e-6));
    256     CHK(d2_eq_eps(uv1, uv2, 1.e-6));
    257     CHK(iprim == 4);
    258   }
    259 
    260   pos[0] = 10;
    261   pos[1] = 0.1;
    262   pos[2] = 0.5;
    263   OK(sdis_scene_boundary_project_position(scn, 6, pos, uv1));
    264   OK(sdis_scene_get_boundary_position(scn, 6, uv1, pos1));
    265   CHK(!d3_eq_eps(pos1, pos, 1.e-6));
    266 
    267   BA(sdis_scene_get_senc3d_scene(NULL, NULL));
    268   BA(sdis_scene_get_senc3d_scene(scn, NULL));
    269   BA(sdis_scene_get_senc3d_scene(NULL, &scn3d));
    270   OK(sdis_scene_get_senc3d_scene(scn, &scn3d));
    271   BA(sdis_scene_get_senc2d_scene(scn, &scn2d)); /* No 2D available */
    272 
    273   BA(sdis_scene_get_s3d_scene_view(NULL, NULL));
    274   BA(sdis_scene_get_s3d_scene_view(NULL, &view3d));
    275   BA(sdis_scene_get_s3d_scene_view(scn, NULL));
    276   OK(sdis_scene_get_s3d_scene_view(scn, &view3d));
    277   BA(sdis_scene_get_s2d_scene_view(scn, &view2d)); /* No 2D available */
    278 
    279   BA(sdis_scene_get_radiative_env(NULL, &radenv));
    280   BA(sdis_scene_get_radiative_env(scn, NULL));
    281   OK(sdis_scene_get_radiative_env(scn, &radenv));
    282   CHK(radenv == NULL);
    283 
    284   BA(sdis_scene_ref_get(NULL));
    285   OK(sdis_scene_ref_get(scn));
    286   BA(sdis_scene_ref_put(NULL));
    287   OK(sdis_scene_ref_put(scn));
    288   OK(sdis_scene_ref_put(scn));
    289 
    290   scn_args.radenv = in_radenv;
    291   OK(sdis_scene_create(dev, &scn_args, &scn));
    292   OK(sdis_scene_get_radiative_env(scn, &radenv));
    293   CHK(radenv == in_radenv);
    294   CHK(radenv != NULL);
    295 
    296   OK(sdis_scene_ref_put(scn));
    297 }
    298 
    299 static void
    300 test_scene_2d
    301   (struct sdis_device* dev,
    302    struct sdis_interface* interf,
    303    struct sdis_radiative_env* in_radenv)
    304 {
    305   size_t duplicated_indices[] = { 0, 1, 1, 0 };
    306   size_t degenerated_indices[] = { 0, 0 };
    307   double duplicated_vertices[] = { 0, 0, 0, 0 };
    308   struct sdis_scene* scn = NULL;
    309   struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT;
    310   struct sdis_scene_find_closest_point_args closest_pt_args =
    311     SDIS_SCENE_FIND_CLOSEST_POINT_ARGS_NULL;
    312   struct sdis_radiative_env* radenv = NULL;
    313   double lower[2], upper[2];
    314   double t_range[2];
    315   double u0, u1, u2, pos[2], pos1[2];
    316   double dst, fp;
    317   struct context ctx;
    318   struct senc2d_scene* scn2d;
    319   struct senc3d_scene* scn3d;
    320   struct s2d_scene_view* view2d;
    321   struct s3d_scene_view* view3d;
    322   size_t nsegs, npos;
    323   size_t i;
    324   size_t iprim;
    325   size_t dup_vrtx_indices[] = { 0, 1 };
    326   enum sdis_scene_dimension dim;
    327 
    328   ctx.positions = square_vertices;
    329   ctx.indices = square_indices;
    330   ctx.interf = interf;
    331   nsegs = square_nsegments;
    332   npos = square_nvertices;
    333 
    334   scn_args.get_indices = get_indices_2d;
    335   scn_args.get_interface = get_interface;
    336   scn_args.get_position = get_position_2d;
    337   scn_args.nprimitives = nsegs;
    338   scn_args.nvertices = npos;
    339   scn_args.context = &ctx;
    340 
    341   BA(sdis_scene_2d_create(NULL, &SDIS_SCENE_CREATE_ARGS_DEFAULT, NULL));
    342   scn_args.nprimitives = 0;
    343   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    344   scn_args.nprimitives = nsegs;
    345   scn_args.get_indices = NULL;
    346   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    347   scn_args.get_indices = get_indices_2d;
    348   scn_args.get_interface = NULL;
    349   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    350   scn_args.get_interface = get_interface;
    351   scn_args.get_position = NULL;
    352   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    353   scn_args.get_position = get_position_2d;
    354   scn_args.nvertices = 0;
    355   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    356   scn_args.nvertices = npos;
    357   scn_args.fp_to_meter = 0;
    358   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    359   scn_args.fp_to_meter = 1;
    360   /* Duplicated vertex */
    361   ctx.positions = duplicated_vertices;
    362   ctx.indices = dup_vrtx_indices;
    363   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    364   /* Duplicated segment */
    365   ctx.positions = square_vertices;
    366   ctx.indices = duplicated_indices;
    367   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    368   /* Degenerated segment */
    369   ctx.indices = degenerated_indices;
    370   BA(sdis_scene_2d_create(dev, &scn_args, &scn));
    371   ctx.positions = square_vertices;
    372   ctx.indices = square_indices;
    373   BA(sdis_scene_2d_create(dev, &SDIS_SCENE_CREATE_ARGS_DEFAULT, &scn));
    374   BA(sdis_scene_2d_create(NULL, &scn_args, &scn));
    375   BA(sdis_scene_2d_create(dev, NULL, &scn));
    376   BA(sdis_scene_2d_create(dev, &scn_args, NULL));
    377   OK(sdis_scene_2d_create(dev, &scn_args, &scn));
    378 
    379   BA(sdis_scene_get_dimension(NULL, &dim));
    380   BA(sdis_scene_get_dimension(scn, NULL));
    381   OK(sdis_scene_get_dimension(scn, &dim));
    382   CHK(dim == SDIS_SCENE_2D);
    383 
    384   BA(sdis_scene_get_aabb(NULL, lower, upper));
    385   BA(sdis_scene_get_aabb(scn, NULL, upper));
    386   BA(sdis_scene_get_aabb(scn, lower, NULL));
    387   OK(sdis_scene_get_aabb(scn, lower, upper));
    388   CHK(eq_eps(lower[0], 0, 1.e-6));
    389   CHK(eq_eps(lower[1], 0, 1.e-6));
    390   CHK(eq_eps(upper[0], 1, 1.e-6));
    391   CHK(eq_eps(upper[1], 1, 1.e-6));
    392 
    393   u0 = 0.5;
    394 
    395   BA(sdis_scene_get_fp_to_meter(NULL, NULL));
    396   BA(sdis_scene_get_fp_to_meter(scn, NULL));
    397   BA(sdis_scene_get_fp_to_meter(NULL, &fp));
    398   OK(sdis_scene_get_fp_to_meter(scn, &fp));
    399   CHK(fp == 1);
    400 
    401   fp = 0;
    402   BA(sdis_scene_set_fp_to_meter(NULL, fp));
    403   BA(sdis_scene_set_fp_to_meter(scn, fp));
    404   fp = 2;
    405   OK(sdis_scene_set_fp_to_meter(scn, fp));
    406   OK(sdis_scene_get_fp_to_meter(scn, &fp));
    407   CHK(fp == 2);
    408 
    409   BA(sdis_scene_get_temperature_range(NULL, NULL));
    410   BA(sdis_scene_get_temperature_range(scn, NULL));
    411   BA(sdis_scene_get_temperature_range(NULL, t_range));
    412   OK(sdis_scene_get_temperature_range(scn, t_range));
    413   if(SDIS_TEMPERATURE_IS_KNOWN(t_range[0])) {
    414     CHK(t_range[0] == SDIS_SCENE_CREATE_ARGS_DEFAULT.t_range[0]);
    415   } else {
    416     CHK(SDIS_TEMPERATURE_IS_UNKNOWN(SDIS_SCENE_CREATE_ARGS_DEFAULT.t_range[0]));
    417   }
    418   if(SDIS_TEMPERATURE_IS_KNOWN(t_range[1])) {
    419     CHK(t_range[1] == SDIS_SCENE_CREATE_ARGS_DEFAULT.t_range[1]);
    420   } else {
    421     CHK(SDIS_TEMPERATURE_IS_UNKNOWN(SDIS_SCENE_CREATE_ARGS_DEFAULT.t_range[0]));
    422   }
    423 
    424   t_range[0] = 1;
    425   t_range[1] = 100;
    426 
    427   BA(sdis_scene_set_temperature_range(NULL, t_range));
    428   BA(sdis_scene_set_temperature_range(scn, NULL));
    429   OK(sdis_scene_set_temperature_range(scn, t_range));
    430   t_range[0] = SDIS_TEMPERATURE_NONE;
    431   t_range[1] = SDIS_TEMPERATURE_NONE;
    432   OK(sdis_scene_get_temperature_range(scn, t_range));
    433   CHK(t_range[0] == 1);
    434   CHK(t_range[1] == 100);
    435 
    436   BA(sdis_scene_get_boundary_position(NULL, 1, &u0, pos));
    437   BA(sdis_scene_get_boundary_position(scn, 4, &u0, pos));
    438   BA(sdis_scene_get_boundary_position(scn, 1, NULL, pos));
    439   BA(sdis_scene_get_boundary_position(scn, 1, &u0, NULL));
    440   OK(sdis_scene_get_boundary_position(scn, 1, &u0, pos));
    441 
    442   BA(sdis_scene_boundary_project_position(NULL, 1, pos, &u1));
    443   BA(sdis_scene_boundary_project_position(scn, 4, pos, &u1));
    444   BA(sdis_scene_boundary_project_position(scn, 1, NULL, &u1));
    445   BA(sdis_scene_boundary_project_position(scn, 1, pos, NULL));
    446   OK(sdis_scene_boundary_project_position(scn, 1, pos, &u1));
    447 
    448   closest_pt_args.position[0] = pos[0];
    449   closest_pt_args.position[1] = pos[1];
    450   closest_pt_args.radius = INF;
    451   BA(sdis_scene_find_closest_point(NULL, &closest_pt_args, &iprim, &u2));
    452   BA(sdis_scene_find_closest_point(scn, NULL, &iprim, &u2));
    453   BA(sdis_scene_find_closest_point(scn, &closest_pt_args, NULL, &u2));
    454   BA(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, NULL));
    455   OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, &u2));
    456 
    457   CHK(eq_eps(u0, u1, 1.e-6));
    458   CHK(eq_eps(u1, u2, 1.e-6));
    459   CHK(iprim == 1);
    460 
    461   pos[0] = 0.5;
    462   pos[1] = 0.1;
    463   closest_pt_args.position[0] = pos[0];
    464   closest_pt_args.position[1] = pos[1];
    465   closest_pt_args.radius = INF;
    466   OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, &u2));
    467   CHK(iprim == 0);
    468 
    469   OK(sdis_scene_boundary_project_position(scn, 0, pos, &u0));
    470   CHK(eq_eps(u0, u2, 1.e-6));
    471 
    472   OK(sdis_scene_get_boundary_position(scn, iprim, &u2, pos1));
    473   dst = d2_len(d2_sub(pos1, pos, pos1));
    474   CHK(eq_eps(dst, 0.1, 1.e-6));
    475 
    476   closest_pt_args.position[0] = pos[0];
    477   closest_pt_args.position[1] = pos[1];
    478   closest_pt_args.radius = 0.09;
    479   OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, &u2));
    480   CHK(iprim == SDIS_PRIMITIVE_NONE);
    481 
    482   FOR_EACH(i, 0, 64) {
    483     u0 = rand_canonic();
    484 
    485     OK(sdis_scene_get_boundary_position(scn, 2, &u0, pos));
    486     OK(sdis_scene_boundary_project_position(scn, 2, pos, &u1));
    487 
    488     closest_pt_args.position[0] = pos[0];
    489     closest_pt_args.position[1] = pos[1];
    490     closest_pt_args.radius = INF;
    491     OK(sdis_scene_find_closest_point(scn, &closest_pt_args, &iprim, &u2));
    492     CHK(eq_eps(u0, u1, 1.e-6));
    493     CHK(eq_eps(u1, u2, 1.e-6));
    494     CHK(iprim == 2);
    495   }
    496 
    497   d2(pos, 5, 0.5);
    498   OK(sdis_scene_boundary_project_position(scn, 3, pos, &u0));
    499   CHK(eq_eps(u0, 0.5, 1.e-6));
    500 
    501   d2(pos, 1, 2);
    502   OK(sdis_scene_boundary_project_position(scn, 3, pos, &u0));
    503   CHK(eq_eps(u0, 0, 1.e-6));
    504 
    505   d2(pos, 1, -1);
    506   OK(sdis_scene_boundary_project_position(scn, 3, pos, &u0));
    507   CHK(eq_eps(u0, 1, 1.e-6));
    508 
    509   BA(sdis_scene_get_senc2d_scene(NULL, NULL));
    510   BA(sdis_scene_get_senc2d_scene(scn, NULL));
    511   BA(sdis_scene_get_senc2d_scene(NULL, &scn2d));
    512   OK(sdis_scene_get_senc2d_scene(scn, &scn2d));
    513   BA(sdis_scene_get_senc3d_scene(scn, &scn3d)); /* No 3D available */
    514 
    515   BA(sdis_scene_get_s2d_scene_view(NULL, NULL));
    516   BA(sdis_scene_get_s2d_scene_view(NULL, &view2d));
    517   BA(sdis_scene_get_s2d_scene_view(scn, NULL));
    518   OK(sdis_scene_get_s2d_scene_view(scn, &view2d));
    519   BA(sdis_scene_get_s3d_scene_view(scn, &view3d)); /* No 3D available */
    520 
    521   BA(sdis_scene_get_radiative_env(NULL, NULL));
    522   BA(sdis_scene_get_radiative_env(scn, NULL));
    523   BA(sdis_scene_get_radiative_env(NULL, &radenv));
    524   OK(sdis_scene_get_radiative_env(scn, &radenv));
    525   CHK(radenv == NULL);
    526 
    527   BA(sdis_scene_ref_get(NULL));
    528   OK(sdis_scene_ref_get(scn));
    529   BA(sdis_scene_ref_put(NULL));
    530   OK(sdis_scene_ref_put(scn));
    531   OK(sdis_scene_ref_put(scn));
    532 
    533   scn_args.radenv = in_radenv;
    534   OK(sdis_scene_2d_create(dev, &scn_args, &scn));
    535   OK(sdis_scene_get_radiative_env(scn, &radenv));
    536   CHK(radenv == in_radenv);
    537   CHK(radenv != NULL);
    538 
    539   OK(sdis_scene_ref_put(scn));
    540 }
    541 
    542 int
    543 main(int argc, char** argv)
    544 {
    545   struct sdis_device* dev = NULL;
    546   struct sdis_medium* solid = NULL;
    547   struct sdis_medium* fluid = NULL;
    548   struct sdis_interface* interf = NULL;
    549   struct sdis_radiative_env* radenv = NULL;
    550   struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER;
    551   struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER;
    552   struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL;
    553   struct sdis_radiative_env_shader ray_shader = DUMMY_RAY_SHADER;
    554   (void)argc, (void)argv;
    555 
    556   interface_shader.convection_coef = DUMMY_INTERFACE_SHADER.convection_coef;
    557 
    558   OK(sdis_device_create(&SDIS_DEVICE_CREATE_ARGS_DEFAULT, &dev));
    559 
    560   OK(sdis_fluid_create(dev, &fluid_shader, NULL, &fluid));
    561   OK(sdis_solid_create(dev, &solid_shader, NULL, &solid));
    562   OK(sdis_interface_create
    563     (dev, solid, fluid, &interface_shader, NULL, &interf));
    564   OK(sdis_radiative_env_create(dev, &ray_shader, NULL, &radenv));
    565 
    566   OK(sdis_medium_ref_put(solid));
    567   OK(sdis_medium_ref_put(fluid));
    568 
    569   test_scene_3d(dev, interf, radenv);
    570   test_scene_2d(dev, interf, radenv);
    571 
    572   OK(sdis_device_ref_put(dev));
    573   OK(sdis_interface_ref_put(interf));
    574   OK(sdis_radiative_env_ref_put(radenv));
    575 
    576   CHK(mem_allocated_size() == 0);
    577   return 0;
    578 }
    579