star-phor-input

File format for describing photoreactor configurations
git clone https://www.edstar.cnrs.fr/git/star-phor-input.git
Log | Files | Refs | README | LICENSE

test_sphin_load_prop_rad.c (12800B)


      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 
     25 #include "sphin.h"
     26 
     27 #include <rsys/math.h>
     28 #include <rsys/mem_allocator.h>
     29 #include <rsys/rsys.h>
     30 
     31 #include <stdio.h>
     32 #include <string.h>
     33 
     34 struct sphin;
     35 
     36 static void
     37 write_prop_rad_test_files
     38   (void)
     39 {
     40   FILE* file;
     41   static const char* test0 =
     42     "#wv abs_cross_sec\n"
     43     "100 1\n"
     44     "200 2\n"
     45     "300 3\n"
     46     "400 4\n";
     47   static const char* test1 = /* Invalid first line */
     48     "wv  abs_cross_sec\n"
     49     "100 1\n"
     50     "200 2\n"
     51     "300 3\n"
     52     "400 4\n";
     53   static const char* test2 = /* Unsorted wavelengths */
     54     "100 1\n"
     55     "300 3\n"
     56     "200 2\n"
     57     "400 4\n";
     58   static const char* test3 = /* Missing data */
     59     "100 1\n"
     60     "200 2\n"
     61     "300 \n"
     62     "400 4\n";
     63   static const char* test4 = /* Bad formating */
     64     "100 1\n"
     65     "200 2\n"
     66     "300 2,5\n"
     67     "400 4\n";
     68   file = fopen("abs_cross_sec_0.txt", "w");
     69   CHK(file != NULL);
     70   fwrite(test0, sizeof(char), strlen(test0), file);
     71   fclose(file);
     72 
     73   file = fopen("abs_cross_sec_1.txt", "w");
     74   CHK(file != NULL);
     75   fwrite(test1, sizeof(char), strlen(test1), file);
     76   fclose(file);
     77 
     78   file = fopen("abs_cross_sec_2.txt", "w");
     79   CHK(file != NULL);
     80   fwrite(test2, sizeof(char), strlen(test2), file);
     81   fclose(file);
     82 
     83   file = fopen("abs_cross_sec_3.txt", "w");
     84   CHK(file != NULL);
     85   fwrite(test3, sizeof(char), strlen(test3), file);
     86   fclose(file);
     87 
     88   file = fopen("abs_cross_sec_4.txt", "w");
     89   CHK(file != NULL);
     90   fwrite(test4, sizeof(char), strlen(test4), file);
     91   fclose(file);
     92 }
     93 
     94 static void
     95 test_prop_rad_api
     96   (struct sphin* sphin)
     97 {
     98   struct sphin_config* config = NULL;
     99   const char* path = "file.txt";
    100   char* name = NULL;
    101   struct sphin_volume* volume = NULL;
    102   struct sphin_prop_rad* prop_rad = NULL;
    103   struct sphin_scatterer* scatterer = NULL;
    104   struct sphin_spectral_property* abs_cross_sec = NULL;
    105   struct sphin_spectral_property_descriptor abs_cs_desc =
    106     SPHIN_SPECTRAL_PROPERTY_DESCRIPTOR_NULL;
    107   size_t nprop_rad;
    108   double concentration, value;
    109   FILE* fp = NULL;
    110   CHK(fp = fopen(path, "w+"));
    111   fprintf(fp, "#Mot Clé   Nom\n");
    112   fprintf(fp, "volume: \"reaction volume\"\n");
    113   fprintf(fp, "\tprop_rad:\"my prop_rad\"\n");
    114   fprintf(fp, "\t\tscatterer:\n");
    115   fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n");
    116   fprintf(fp, "\t\tcross_sections:\n");
    117   fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_0.txt nm m^2/part\n");
    118   fclose(fp);
    119 
    120   CHK(sphin_load(sphin, path, &config) == RES_OK);
    121   CHK(sphin_config_get_volume(config, 0, &volume) == RES_OK);
    122   CHK(sphin_volume_get_prop_rad_count(NULL, NULL) == RES_BAD_ARG);
    123   CHK(sphin_volume_get_prop_rad_count(volume, NULL) == RES_BAD_ARG);
    124   CHK(sphin_volume_get_prop_rad_count(NULL, &nprop_rad) == RES_BAD_ARG);
    125   CHK(sphin_volume_get_prop_rad_count(volume, &nprop_rad) == RES_OK);
    126   CHK(nprop_rad == 1);
    127   CHK(sphin_volume_get_prop_rad(NULL, 0, NULL) == RES_BAD_ARG);
    128   CHK(sphin_volume_get_prop_rad(volume, 0, NULL) == RES_BAD_ARG);
    129   CHK(sphin_volume_get_prop_rad(NULL, 0, &prop_rad) == RES_BAD_ARG);
    130   CHK(sphin_volume_get_prop_rad(volume, (size_t)-1, &prop_rad) == RES_BAD_ARG);
    131   CHK(sphin_volume_get_prop_rad(volume, 10, &prop_rad) == RES_BAD_ARG);
    132   CHK(sphin_volume_get_prop_rad(volume, 0, &prop_rad) == RES_OK);
    133   CHK(sphin_prop_rad_get_name(NULL, NULL) == RES_BAD_ARG);
    134   CHK(sphin_prop_rad_get_name(prop_rad, NULL) == RES_BAD_ARG);
    135   CHK(sphin_prop_rad_get_name(NULL, &name) == RES_BAD_ARG);
    136   CHK(sphin_prop_rad_get_name(prop_rad, &name) == RES_OK);
    137   CHK(strcmp(name, "my prop_rad") == 0);
    138   CHK(sphin_prop_rad_ref_get(prop_rad) == RES_OK);
    139   CHK(sphin_prop_rad_ref_get(NULL) == RES_BAD_ARG);
    140   CHK(sphin_prop_rad_ref_put(NULL) == RES_BAD_ARG);
    141   CHK(sphin_prop_rad_ref_put(prop_rad) == RES_OK);
    142   CHK(sphin_prop_rad_get_scatterer(NULL, NULL) == RES_BAD_ARG);
    143   CHK(sphin_prop_rad_get_scatterer(prop_rad, NULL) == RES_BAD_ARG);
    144   CHK(sphin_prop_rad_get_scatterer(NULL, &scatterer) == RES_BAD_ARG);
    145   CHK(sphin_prop_rad_get_scatterer(prop_rad, &scatterer) == RES_OK);
    146   CHK(sphin_scatterer_ref_get(NULL) == RES_BAD_ARG);
    147   CHK(sphin_scatterer_ref_get(scatterer) == RES_OK);
    148   CHK(sphin_scatterer_ref_put(NULL) == RES_BAD_ARG);
    149   CHK(sphin_scatterer_ref_put(scatterer) == RES_OK);
    150   CHK(sphin_scatterer_get_concentration(NULL, NULL) == RES_BAD_ARG);
    151   CHK(sphin_scatterer_get_concentration(scatterer, NULL) == RES_BAD_ARG);
    152   CHK(sphin_scatterer_get_concentration(NULL, &concentration) == RES_BAD_ARG);
    153   CHK(sphin_scatterer_get_concentration(scatterer, &concentration) == RES_OK);
    154   CHK(eq_eps(concentration, 1.935, 1e-15));
    155   CHK(sphin_scatterer_get_abs_cross_sec(NULL, NULL) == RES_BAD_ARG);
    156   CHK(sphin_scatterer_get_abs_cross_sec(scatterer, NULL) == RES_BAD_ARG);
    157   CHK(sphin_scatterer_get_abs_cross_sec(NULL, &abs_cross_sec) == RES_BAD_ARG);
    158   CHK(sphin_scatterer_get_abs_cross_sec(scatterer, &abs_cross_sec) == RES_OK);
    159   CHK(sphin_spectral_property_ref_get(NULL) == RES_BAD_ARG);
    160   CHK(sphin_spectral_property_ref_get(abs_cross_sec) == RES_OK);
    161   CHK(sphin_spectral_property_ref_put(NULL) == RES_BAD_ARG);
    162   CHK(sphin_spectral_property_ref_put(abs_cross_sec) == RES_OK);
    163   CHK(sphin_spectral_property_get_desc(NULL, NULL) == RES_BAD_ARG);
    164   CHK(sphin_spectral_property_get_desc(abs_cross_sec, NULL) == RES_BAD_ARG);
    165   CHK(sphin_spectral_property_get_desc(NULL, &abs_cs_desc) == RES_BAD_ARG);
    166   CHK(sphin_spectral_property_get_desc(abs_cross_sec, &abs_cs_desc) == RES_OK);
    167   CHK(sphin_spectral_property_interpolate_at_wavelength
    168       (abs_cross_sec, 100, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK);
    169   CHK(eq_eps(value, 1., 1e-15));
    170   CHK(sphin_spectral_property_interpolate_at_wavelength
    171       (abs_cross_sec, 175, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK);
    172   CHK(eq_eps(value, 1.75, 1e-15));
    173   CHK(sphin_spectral_property_interpolate_at_wavelength
    174       (abs_cross_sec, 400, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK);
    175   CHK(eq_eps(value, 4., 1e-15));
    176   CHK(eq_eps(abs_cs_desc.wavelengths[0], 100, 1e-15));
    177   CHK(eq_eps(abs_cs_desc.wavelengths[2], 300, 1e-15));
    178   CHK(eq_eps(abs_cs_desc.values[0], 1, 1e-15));
    179   CHK(eq_eps(abs_cs_desc.values[2], 3, 1e-15));
    180   CHK(abs_cs_desc.data_count == 4);
    181   CHK(sphin_config_ref_put(config) == RES_OK);
    182 }
    183 
    184 static void
    185 test_prop_rad_api_units
    186   (struct sphin* sphin)
    187 {
    188   struct sphin_config* config = NULL;
    189   const char* path = "file.txt";
    190   struct sphin_volume* volume = NULL;
    191   struct sphin_prop_rad* prop_rad = NULL;
    192   struct sphin_scatterer* scatterer = NULL;
    193   struct sphin_spectral_property* abs_cross_sec = NULL;
    194   struct sphin_spectral_property_descriptor abs_cs_desc =
    195     SPHIN_SPECTRAL_PROPERTY_DESCRIPTOR_NULL;
    196   double value;
    197   FILE* fp = NULL;
    198   CHK(fp = fopen(path, "w+"));
    199   fprintf(fp, "#Mot Clé   Nom\n");
    200   fprintf(fp, "volume: \"reaction volume\"\n");
    201   fprintf(fp, "\tprop_rad: \"name\"\n");
    202   fprintf(fp, "\t\tscatterer:\n");
    203   fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n");
    204   fprintf(fp, "\t\tcross_sections:\n");
    205   fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_0.txt cm m^2/part\n");
    206   fclose(fp);
    207 
    208   CHK(sphin_load(sphin, path, &config) == RES_OK);
    209   CHK(sphin_config_get_volume(config, 0, &volume) == RES_OK);
    210   CHK(sphin_volume_get_prop_rad(volume, 0, &prop_rad) == RES_OK);
    211   CHK(sphin_prop_rad_get_scatterer(prop_rad, &scatterer) == RES_OK);
    212   CHK(sphin_scatterer_get_abs_cross_sec(scatterer, &abs_cross_sec) == RES_OK);
    213   CHK(sphin_spectral_property_get_desc(abs_cross_sec, &abs_cs_desc) == RES_OK);
    214   CHK(sphin_spectral_property_interpolate_at_wavelength
    215       (abs_cross_sec, 100e7, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK);
    216   CHK(eq_eps(value, 1., 1e-15));
    217   CHK(sphin_spectral_property_interpolate_at_wavelength
    218       (abs_cross_sec, 175e7, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK);
    219   CHK(eq_eps(value, 1.75, 1e-15));
    220   CHK(sphin_spectral_property_interpolate_at_wavelength
    221       (abs_cross_sec, 400e7, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK);
    222   CHK(eq_eps(value, 4., 1e-15));
    223   CHK(eq_eps(abs_cs_desc.wavelengths[0], 100e7, 1e-15));
    224   CHK(eq_eps(abs_cs_desc.wavelengths[2], 300e7, 1e-15));
    225   CHK(sphin_config_ref_put(config) == RES_OK);
    226 }
    227 static void
    228 test_prop_rad_api_bad_comment
    229   (struct sphin* sphin)
    230 {
    231   struct sphin_config* config = NULL;
    232   const char* path = "file.txt";
    233   FILE* fp = NULL;
    234 
    235   CHK(fp = fopen(path, "w+"));
    236   fprintf(fp, "#Mot Clé   Nom\n");
    237   fprintf(fp, "volume: \"reaction volume\"\n");
    238   fprintf(fp, "\tprop_rad: \"name\"\n");
    239   fprintf(fp, "\t\tscatterer:\n");
    240   fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n");
    241   fprintf(fp, "\t\tcross_sections:\n");
    242   fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_1.txt nm m^2/part\n");
    243   fclose(fp);
    244 
    245   CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG);
    246 }
    247 
    248 static void
    249 test_prop_rad_api_unsorted_wavelengths
    250   (struct sphin* sphin)
    251 {
    252   struct sphin_config* config = NULL;
    253   const char* path = "file.txt";
    254   FILE* fp = NULL;
    255 
    256   CHK(fp = fopen(path, "w+"));
    257   fprintf(fp, "#Mot Clé   Nom\n");
    258   fprintf(fp, "volume: \"reaction volume\"\n");
    259   fprintf(fp, "\tprop_rad:  \"name\"\n");
    260   fprintf(fp, "\t\tscatterer:\n");
    261   fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n");
    262   fprintf(fp, "\t\tcross_sections:\n");
    263   fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_2.txt nm m^2/part\n");
    264   fclose(fp);
    265 
    266   CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG);
    267 }
    268 
    269 static void
    270 test_prop_rad_api_missing_data
    271   (struct sphin* sphin)
    272 {
    273   struct sphin_config* config = NULL;
    274   const char* path = "file.txt";
    275   FILE* fp = NULL;
    276 
    277   CHK(fp = fopen(path, "w+"));
    278   fprintf(fp, "#Mot Clé   Nom\n");
    279   fprintf(fp, "volume: \"reaction volume\"\n");
    280   fprintf(fp, "\tprop_rad: \"name\"\n");
    281   fprintf(fp, "\t\tscatterer:\n");
    282   fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n");
    283   fprintf(fp, "\t\tcross_sections:\n");
    284   fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_3.txt nm m^2/part\n");
    285   fclose(fp);
    286 
    287   CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG);
    288 }
    289 
    290 static void
    291 test_prop_rad_api_bad_formatting
    292   (struct sphin* sphin)
    293 {
    294   struct sphin_config* config = NULL;
    295   const char* path = "file.txt";
    296   FILE* fp = NULL;
    297 
    298   CHK(fp = fopen(path, "w+"));
    299   fprintf(fp, "#Mot Clé   Nom\n");
    300   fprintf(fp, "volume: \"reaction volume\"\n");
    301   fprintf(fp, "\tprop_rad: \"name\"\n");
    302   fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n");
    303   fprintf(fp, "\t\tcross_sections:\n");
    304   fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_4.txt nm m^2/part\n");
    305   fclose(fp);
    306 
    307   CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG);
    308 }
    309 
    310 static void
    311 test_prop_rad_api_non_existing_file
    312   (struct sphin* sphin)
    313 {
    314   struct sphin_config* config = NULL;
    315   const char* path = "file.txt";
    316   FILE* fp = NULL;
    317 
    318   CHK(fp = fopen(path, "w+"));
    319   fprintf(fp, "#Mot Clé   Nom\n");
    320   fprintf(fp, "volume: \"reaction volume\"\n");
    321   fprintf(fp, "\tprop_rad: \"name\"\n");
    322   fprintf(fp, "\t\tscatterer:\n");
    323   fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n");
    324   fprintf(fp, "\t\tcross_sections:\n");
    325   fprintf(fp, "\t\t\tabs_cross_sec: non_existing_file.txt nm m^2/part\n");
    326   fclose(fp);
    327 
    328   CHK(sphin_load(sphin, path, &config) == RES_IO_ERR);
    329 }
    330 
    331 int
    332 main(int argc, char** argv)
    333 {
    334   struct sphin* sphin = NULL;
    335   struct sphin_create_args args = SPHIN_CREATE_ARGS_DEFAULT;
    336 
    337   (void)argc;
    338   (void)argv;
    339 
    340   args.verbose = 1;
    341   sphin_create(&args, &sphin);
    342 
    343   write_prop_rad_test_files();
    344   test_prop_rad_api(sphin);
    345   test_prop_rad_api_units(sphin);
    346   test_prop_rad_api_bad_comment(sphin);
    347   test_prop_rad_api_unsorted_wavelengths(sphin);
    348   test_prop_rad_api_missing_data(sphin);
    349   test_prop_rad_api_bad_formatting(sphin);
    350   test_prop_rad_api_non_existing_file(sphin);
    351   CHK(sphin_ref_put(sphin) == RES_OK);
    352 
    353   CHK(mem_allocated_size() == 0);
    354   return 0;
    355 }