star-phor

Radiative transfer solver for photoreactors.
git clone https://www.edstar.cnrs.fr/git/star-phor.git
Log | Files | Refs | README | LICENSE

test_sphor_MVREA_btdf_snell_dielectric.c (8139B)


      1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique
      2  * Copyright (C) 2024-2026 Clermont Auvergne INP
      3  * Copyright (C) 2024-2026 INSA Lyon
      4  * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux
      5  * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse
      6  * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com)
      7  * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com)
      8  * Copyright (C) 2024-2026 Université de Lorraine
      9  * Copyright (C) 2024-2026 Université Paul Sabatier
     10  * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès
     11  *
     12  * This program is free software: you can redistribute it and/or modify
     13  * it under the terms of the GNU General Public License as published by
     14  * the Free Software Foundation, either version 3 of the License, or
     15  * (at your option) any later version.
     16  *
     17  * This program is distributed in the hope that it will be useful,
     18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     20  * GNU General Public License for more details.
     21  *
     22  * You should have received a copy of the GNU General Public License
     23  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     24 #define _POSIX_C_SOURCE 200112L
     25 
     26 #include "sphor.h"
     27 
     28 #include <rsys/cstr.h>
     29 #include <rsys/logger.h>
     30 #include <rsys/str.h>
     31 #include <rsys/text_reader.h>
     32 
     33 #include <stdio.h>
     34 
     35 static void
     36 write_emitting_surface()
     37 {
     38   FILE* fp = fopen("emitting_surface.stl", "w");
     39   CHK(fp != NULL);
     40 
     41   fprintf(fp,
     42     "solid emitting_surface\n"
     43     "  facet normal 0.5 0.8660254037844386 0\n"
     44     "    outer loop\n"
     45     "      vertex -1.4433756729740643 -1.5 -1\n"
     46     "      vertex -0.5773502691896257 -2 1\n"
     47     "      vertex -0.5773502691896257 -2 -1\n"
     48     "    endloop\n"
     49     "  endfacet\n"
     50     "  facet normal 0.5 0.8660254037844386 0\n"
     51     "    outer loop\n"
     52     "      vertex -0.5773502691896257 -2 1\n"
     53     "      vertex -1.4433756729740643 -1.5 -1\n"
     54     "      vertex -1.4433756729740643 -1.5 1\n"
     55     "    endloop\n"
     56     "  endfacet\n"
     57     "endsolid emitting_surface\n");
     58 
     59   CHK(fclose(fp) == 0);
     60 }
     61 
     62 static void
     63 write_btdf_surface()
     64 {
     65   FILE* fp = fopen("btdf_surface.stl", "w");
     66   CHK(fp != NULL);
     67 
     68   fprintf(fp,
     69     "solid btdf_surface\n"
     70     "  facet normal 1 0 0\n"
     71     "    outer loop\n"
     72     "      vertex 0 -1 -1\n"
     73     "      vertex 0 1 1\n"
     74     "      vertex 0 -1 1\n"
     75     "    endloop\n"
     76     "  endfacet\n"
     77     "  facet normal 1 0 0\n"
     78     "    outer loop\n"
     79     "      vertex 0 -1 -1\n"
     80     "      vertex 0 1 -1\n"
     81     "      vertex 0 1 1\n"
     82     "    endloop\n"
     83     "  endfacet\n"
     84     "endsolid btdf_surface\n");
     85 
     86   CHK(fclose(fp) == 0);
     87 }
     88 
     89 static void
     90 write_absorbing_surface()
     91 {
     92   FILE* fp = fopen("absorbing_surface.stl", "w");
     93   CHK(fp != NULL);
     94 
     95   fprintf(fp,
     96     "solid absorbing_surface\n"
     97         "facet normal 0 0 0\n"
     98           "outer loop\n"
     99             "vertex 1.7320508075688772 0 -1\n"
    100             "vertex 1.7320508075688772 0 1\n"
    101             "vertex 0.8660254037844386 1.5 1\n"
    102           "endloop\n"
    103         "endfacet\n"
    104         "facet normal 0 0 0\n"
    105           "outer loop\n"
    106             "vertex 0.8660254037844386 1.5 1\n"
    107             "vertex 0.8660254037844386 1.5 -1\n"
    108             "vertex 1.7320508075688772 0 -1\n"
    109           "endloop\n"
    110         "endfacet\n"
    111     "endsolid absorbing_surface\n");
    112 
    113   CHK(fclose(fp) == 0);
    114 }
    115 
    116 static void
    117 write_spectrum()
    118 {
    119   FILE* fp = fopen("emission_spectrum.dat", "w");
    120   CHK(fp != NULL);
    121 
    122   fprintf(fp, "400 1\n");
    123   fprintf(fp, "401 1\n");
    124 
    125   CHK(fclose(fp) == 0);
    126 }
    127 
    128 static void
    129 write_btdf()
    130 {
    131   FILE* fp = fopen("btdf.dat", "w");
    132   CHK(fp != NULL);
    133 
    134   fprintf(fp, "400 1\n");
    135   fprintf(fp, "401 1\n");
    136 
    137   CHK(fclose(fp) == 0);
    138 }
    139 
    140 static void
    141 write_bsdf_null()
    142 {
    143   FILE* fp = fopen("bsdf_null.dat", "w");
    144   CHK(fp != NULL);
    145 
    146   fprintf(fp, "400 0\n");
    147   fprintf(fp, "401 0\n");
    148 
    149   CHK(fclose(fp) == 0);
    150 }
    151 
    152 static void
    153 write_n_back()
    154 {
    155   FILE* fp = fopen("n_back.dat", "w");
    156   CHK(fp != NULL);
    157 
    158   fprintf(fp, "400 1\n");
    159   fprintf(fp, "401 1\n");
    160 
    161   CHK(fclose(fp) == 0);
    162 }
    163 
    164 static void
    165 write_n_front()
    166 {
    167   FILE* fp = fopen("n_front.dat", "w");
    168   CHK(fp != NULL);
    169 
    170   fprintf(fp, "400 1.7320508075688772\n");
    171   fprintf(fp, "401 1.7320508075688772\n");
    172 
    173   CHK(fclose(fp) == 0);
    174 }
    175 
    176 static void
    177 write_input_file(FILE* fp)
    178 {
    179   write_emitting_surface();
    180   write_btdf_surface();
    181   write_absorbing_surface();
    182   write_spectrum();
    183   write_btdf();
    184   write_bsdf_null();
    185   write_n_front();
    186   write_n_back();
    187 
    188   fprintf(fp, "surface: \"source\"\n");
    189   fprintf(fp, "\tgeometry: FRONT emitting_surface.stl\n");
    190   fprintf(fp, "\tsource:\n");
    191   fprintf(fp, "\tflux_density: 1.7320508075688772 umol/m^2/s");
    192   fprintf(fp, " emission_spectrum.dat nm nm^-1\n");
    193   fprintf(fp, "\t\tdirection: COLLIM NORMAL\n");
    194   fprintf(fp, "\n");
    195 
    196   fprintf(fp, "surface: \"transmitter\"\n");
    197   fprintf(fp, "\tgeometry: BACK btdf_surface.stl\n");
    198   fprintf(fp, "\tbtdf: SNELL_DIELECTRIC btdf.dat\n");
    199   fprintf(fp, "\n");
    200 
    201   fprintf(fp, "surface: \"absorber\"\n");
    202   fprintf(fp, "\tgeometry: FRONT absorbing_surface.stl\n");
    203   fprintf(fp, "\tbrdf: SPECULAR bsdf_null.dat\n");
    204   fprintf(fp, "\tsensor:\n");
    205   fprintf(fp, "\t\tresponse_function: 1\n");
    206 
    207   fprintf(fp, "volume: \"n_front\"\n");
    208   fprintf(fp, "\tgeometry: FRONT btdf_surface.stl\n");
    209   fprintf(fp, "\trefractive_index:\n");
    210   fprintf(fp, "\t\tn_real: n_front.dat\n");
    211 
    212   fprintf(fp, "volume: \"n_back\"\n");
    213   fprintf(fp, "\tgeometry: BACK btdf_surface.stl\n");
    214   fprintf(fp, "\trefractive_index:\n");
    215   fprintf(fp, "\t\tn_real: n_back.dat\n");
    216 
    217   CHK(fflush(fp) == 0);
    218 }
    219 
    220 int main(int argc, char** argv)
    221 {
    222   struct sphor* sphor = NULL;
    223   struct sphor_create_args args = SPHOR_CREATE_ARGS_DEFAULT;
    224   struct txtrdr* txtrdr = NULL;
    225   struct str line;
    226   char* token = NULL;
    227   char* token_ptr = NULL;
    228   char input_filename[] = "input";
    229   char output_filename[] = "output";
    230   double avg = 0;
    231   double std_err = 0;
    232 
    233   FILE* fp = NULL;
    234 
    235   fp = fopen(input_filename, "w+");
    236   CHK(NULL != fp);
    237 
    238   write_input_file(fp);
    239   CHK(fclose(fp) == 0);
    240 
    241   args.input_filename = input_filename;
    242   args.output_filename = output_filename;
    243   args.force = 1;
    244 
    245   (void)argc;
    246   (void)argv;
    247 
    248   /* Test sphor_create with NULL logger and allocator */
    249   CHK(sphor_create(&args, &sphor) == RES_OK);
    250 
    251   /* Run sphor with the config file */
    252   CHK(sphor_run(sphor) == RES_OK);
    253 
    254   CHK(sphor_ref_put(sphor) == RES_OK);
    255 
    256   fp = fopen(output_filename, "r");
    257   CHK(NULL != fp);
    258 
    259   str_init(NULL, &line);
    260   CHK(txtrdr_stream(NULL, fp, output_filename, '#', &txtrdr) == RES_OK);
    261 
    262   /* Verify first level: total scene MVREA */
    263   CHK(txtrdr_read_line(txtrdr) == RES_OK);
    264   CHK(str_set(&line, txtrdr_get_cline(txtrdr)) == RES_OK);
    265   token = strtok_r(str_get(&line), ":", &token_ptr);
    266   CHK(strcmp(token, "MVREA") == 0);
    267   token = strtok_r(NULL, ":", &token_ptr);
    268   CHK(cstr_to_double(token, &avg) == RES_OK);
    269   CHK(cstr_to_double(token_ptr, &std_err) == RES_OK);
    270   /* Compare to analytical solution */
    271   CHK(eq_eps(avg, 0, 2 * std_err));
    272 
    273   /* Verify first level: total scene losses */
    274   CHK(txtrdr_read_line(txtrdr) == RES_OK);
    275   CHK(str_set(&line, txtrdr_get_cline(txtrdr)) == RES_OK);
    276   token = strtok_r(str_get(&line), ":", &token_ptr);
    277   CHK(strcmp(token, "LOSSES") == 0);
    278   token = strtok_r(NULL, ":", &token_ptr);
    279   CHK(cstr_to_double(token, &avg) == RES_OK);
    280   CHK(cstr_to_double(token_ptr, &std_err) == RES_OK);
    281   /* Compare to analytical solution */
    282   CHK(eq_eps(avg, 1, 2 * std_err));
    283 
    284   /* Verify second level: per surface losses */
    285   CHK(txtrdr_read_line(txtrdr) == RES_OK);
    286   CHK(str_set(&line, txtrdr_get_cline(txtrdr)) == RES_OK);
    287   token = strtok_r(str_get(&line), ":", &token_ptr);
    288   CHK(strcmp(token, "LOSSES") == 0);
    289   token = strtok_r(NULL, ":", &token_ptr);
    290   CHK(strcmp(token, "absorber") == 0);
    291   token = strtok_r(NULL, ":", &token_ptr);
    292   CHK(cstr_to_double(token, &avg) == RES_OK);
    293   CHK(cstr_to_double(token_ptr, &std_err) == RES_OK);
    294   /* Compare to analytical solution */
    295   CHK(eq_eps(avg, 1, 2 * std_err));
    296 
    297   CHK(fclose(fp) == 0);
    298 
    299   str_release(&line);
    300   txtrdr_ref_put(txtrdr);
    301 
    302  CHK(mem_allocated_size() == 0);
    303 
    304   return 0;
    305 }