star-line

Structure for accelerating line importance sampling
git clone git://git.meso-star.fr/star-line.git
Log | Files | Refs | README | LICENSE

test_sln_mixture.c (9657B)


      1 /* Copyright (C) 2022, 2026 |Méso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2026 Université de Lorraine
      3  * Copyright (C) 2022 Centre National de la Recherche Scientifique
      4  * Copyright (C) 2022 Université Paul Sabatier
      5  *
      6  * This program is free software: you can redistribute it and/or modify
      7  * it under the terms of the GNU General Public License as published by
      8  * the Free Software Foundation, either version 3 of the License, or
      9  * (at your option) any later version.
     10  *
     11  * This program is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     14  * GNU General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU General Public License
     17  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     18 
     19 #include "test_sln_lines.h"
     20 #include "sln.h"
     21 
     22 #include <star/shtr.h>
     23 #include <rsys/math.h>
     24 #include <rsys/mem_allocator.h>
     25 
     26 /*******************************************************************************
     27  * Helper function
     28  ******************************************************************************/
     29 static void
     30 test_mixture
     31   (struct sln_device* sln,
     32    struct shtr_isotope_metadata* metadata,
     33    struct shtr_line_list* line_list)
     34 {
     35   struct sln_mixture_create_args mixture_args = SLN_MIXTURE_CREATE_ARGS_DEFAULT;
     36   struct sln_mixture_desc desc = SLN_MIXTURE_DESC_NULL;
     37   struct sln_mixture* mixture = NULL;
     38   size_t nlines = 0;
     39 
     40   mixture_args.metadata = metadata;
     41   mixture_args.lines = line_list;
     42   mixture_args.molecules[0].nisotopes = 0; /* Handle all isotopes */
     43   mixture_args.molecules[0].concentration = 1.0/3.0;
     44   mixture_args.molecules[0].cutoff = 25;
     45   mixture_args.molecules[0].id = 1; /* H2O */
     46   mixture_args.molecules[1].nisotopes = 0; /* Handle all isotopes */
     47   mixture_args.molecules[1].concentration = 1.0/3.0;
     48   mixture_args.molecules[1].cutoff = 50;
     49   mixture_args.molecules[1].id = 2; /* CO2 */
     50   mixture_args.molecules[2].nisotopes = 0; /* Handle all isotopes */
     51   mixture_args.molecules[2].concentration = 1.0/3.0;
     52   mixture_args.molecules[2].cutoff = 25;
     53   mixture_args.molecules[2].id = 3; /* O3 */
     54   mixture_args.nmolecules = 3;
     55   mixture_args.wavenumber_range[0] = 0;
     56   mixture_args.wavenumber_range[1] = INF;
     57   mixture_args.pressure = 1;
     58   mixture_args.temperature = 296;
     59   CHK(sln_mixture_create(NULL, &mixture_args, &mixture) == RES_BAD_ARG);
     60   CHK(sln_mixture_create(sln, NULL, &mixture) == RES_BAD_ARG);
     61   CHK(sln_mixture_create(sln, NULL, NULL) == RES_BAD_ARG);
     62   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_OK);
     63 
     64   CHK(sln_mixture_get_desc(NULL, &desc) == RES_BAD_ARG);
     65   CHK(sln_mixture_get_desc(mixture, NULL) == RES_BAD_ARG);
     66   CHK(sln_mixture_get_desc(mixture, &desc) == RES_OK);
     67 
     68   CHK(shtr_line_list_get_size(line_list, &nlines) == RES_OK);
     69 
     70   CHK(desc.wavenumber_range[0] == mixture_args.wavenumber_range[0]);
     71   CHK(desc.wavenumber_range[1] == mixture_args.wavenumber_range[1]);
     72   CHK(desc.temperature = mixture_args.temperature);
     73   CHK(desc.pressure == mixture_args.pressure);
     74   CHK(desc.nlines == nlines); /* All the lines are taken into the count */
     75 
     76   CHK(sln_mixture_ref_get(NULL) == RES_BAD_ARG);
     77   CHK(sln_mixture_ref_get(mixture) == RES_OK);
     78   CHK(sln_mixture_ref_put(NULL) == RES_BAD_ARG);
     79   CHK(sln_mixture_ref_put(mixture) == RES_OK);
     80   CHK(sln_mixture_ref_put(mixture) == RES_OK);
     81 
     82   mixture_args.metadata = NULL;
     83   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
     84 
     85   mixture_args.metadata = metadata;
     86   mixture_args.lines = NULL;
     87   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
     88 
     89   mixture_args.metadata = metadata;
     90   mixture_args.lines = NULL;
     91   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
     92 
     93   mixture_args.lines = line_list;
     94   mixture_args.molecules[0].concentration = 1;
     95   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
     96 
     97   mixture_args.molecules[0].concentration = -1;
     98   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
     99 
    100   mixture_args.molecules[0].concentration = 1.0/3.0;
    101   mixture_args.molecules[0].cutoff = 0;
    102   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
    103 
    104   mixture_args.molecules[0].cutoff = 25;
    105   mixture_args.pressure = -1;
    106   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
    107 
    108   mixture_args.pressure = 1;
    109   mixture_args.temperature = -1;
    110   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
    111   mixture_args.temperature = 296;
    112 
    113   mixture_args.molecules[0].nisotopes = 2;
    114   mixture_args.molecules[0].isotopes[0].abundance = 0.6;
    115   mixture_args.molecules[0].isotopes[0].id_local = 0;
    116   mixture_args.molecules[0].isotopes[1].abundance = 0.5;
    117   mixture_args.molecules[0].isotopes[1].id_local = 1;
    118   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
    119   mixture_args.molecules[0].isotopes[0].abundance = 0.5;
    120 
    121   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_OK);
    122   CHK(sln_mixture_ref_put(mixture) == RES_OK);
    123 
    124   mixture_args.molecules[0].id = SLN_MAX_MOLECULES_COUNT;
    125   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
    126   mixture_args.molecules[0].id = 1;
    127   mixture_args.molecules[0].isotopes[0].id_local = SLN_MAX_ISOTOPES_COUNT;
    128   CHK(sln_mixture_create(sln, &mixture_args, &mixture) == RES_BAD_ARG);
    129 }
    130 
    131 static void
    132 test_mixture_serialization
    133   (struct sln_device* sln,
    134    struct shtr* shtr,
    135    struct shtr_isotope_metadata* metadata,
    136    struct shtr_line_list* line_list)
    137 {
    138   struct sln_mixture_create_args mixture_args = SLN_MIXTURE_CREATE_ARGS_DEFAULT;
    139   struct sln_mixture_desc desc1 = SLN_MIXTURE_DESC_NULL;
    140   struct sln_mixture_desc desc2 = SLN_MIXTURE_DESC_NULL;
    141   struct sln_mixture* mixture1 = NULL;
    142   struct sln_mixture* mixture2 = NULL;
    143   FILE* fp = NULL;
    144 
    145   mixture_args.metadata = metadata;
    146   mixture_args.lines = line_list;
    147   mixture_args.molecules[0].nisotopes = 0; /* Handle all isotopes */
    148   mixture_args.molecules[0].concentration = 1.0/3.0;
    149   mixture_args.molecules[0].cutoff = 25;
    150   mixture_args.molecules[0].id = 1; /* H2O */
    151   mixture_args.molecules[1].nisotopes = 0; /* Handle all isotopes */
    152   mixture_args.molecules[1].concentration = 1.0/3.0;
    153   mixture_args.molecules[1].cutoff = 50;
    154   mixture_args.molecules[1].id = 2; /* CO2 */
    155   mixture_args.molecules[2].nisotopes = 0; /* Handle all isotopes */
    156   mixture_args.molecules[2].concentration = 1.0/3.0;
    157   mixture_args.molecules[2].cutoff = 25;
    158   mixture_args.molecules[2].id = 3; /* O3 */
    159   mixture_args.nmolecules = 3;
    160   mixture_args.wavenumber_range[0] = 0;
    161   mixture_args.wavenumber_range[1] = INF;
    162   mixture_args.pressure = 1;
    163   mixture_args.temperature = 296;
    164   CHK(sln_mixture_create(sln, &mixture_args, &mixture1) == RES_OK);
    165 
    166   CHK(fp = tmpfile());
    167   CHK(sln_mixture_write(NULL, fp) == RES_BAD_ARG);
    168   CHK(sln_mixture_write(mixture1, NULL) == RES_BAD_ARG);
    169   CHK(sln_mixture_write(mixture1, fp) == RES_OK);
    170   rewind(fp);
    171 
    172   CHK(sln_mixture_create_from_stream(NULL, shtr, fp, &mixture2) == RES_BAD_ARG);
    173   CHK(sln_mixture_create_from_stream(sln, NULL, fp, &mixture2) == RES_BAD_ARG);
    174   CHK(sln_mixture_create_from_stream(sln, shtr, NULL, &mixture2) == RES_BAD_ARG);
    175   CHK(sln_mixture_create_from_stream(sln, shtr, fp, NULL) == RES_BAD_ARG);
    176   CHK(sln_mixture_create_from_stream(sln, shtr, fp, &mixture2) == RES_OK);
    177   fclose(fp);
    178 
    179   CHK(sln_mixture_get_desc(mixture1, &desc1) == RES_OK);
    180   CHK(sln_mixture_get_desc(mixture2, &desc2) == RES_OK);
    181 
    182   CHK(desc1.wavenumber_range[0] == desc2.wavenumber_range[0]);
    183   CHK(desc1.wavenumber_range[1] == desc2.wavenumber_range[1]);
    184   CHK(desc1.pressure == desc2.pressure);
    185   CHK(desc1.temperature == desc2.temperature);
    186   CHK(desc1.nlines == desc2.nlines);
    187 
    188   CHK(sln_mixture_ref_put(mixture1) == RES_OK);
    189   CHK(sln_mixture_ref_put(mixture2) == RES_OK);
    190 }
    191 
    192 /*******************************************************************************
    193  * Test function
    194  ******************************************************************************/
    195 int
    196 main(int argc, char** argv)
    197 {
    198   struct sln_device_create_args dev_args = SLN_DEVICE_CREATE_ARGS_DEFAULT;
    199 
    200   struct sln_device* sln = NULL;
    201 
    202   struct shtr_create_args shtr_args = SHTR_CREATE_ARGS_DEFAULT;
    203   struct shtr* shtr = NULL;
    204   struct shtr_line_list* line_list = NULL;
    205   struct shtr_isotope_metadata* metadata = NULL;
    206 
    207   FILE* fp_lines = NULL;
    208   FILE* fp_mdata = NULL;
    209   (void)argc, (void)argv;
    210 
    211   /* Generate the file of the isotope metadata */
    212   CHK(fp_mdata = tmpfile());
    213   fprintf(fp_mdata, "Molecule # Iso Abundance Q(296K) gj Molar Mass(g)\n");
    214   write_shtr_molecule(fp_mdata, &g_H2O);
    215   write_shtr_molecule(fp_mdata, &g_CO2);
    216   write_shtr_molecule(fp_mdata, &g_O3);
    217   rewind(fp_mdata);
    218 
    219   /* Generate the file of lines */
    220   CHK(fp_lines = tmpfile());
    221   write_shtr_lines(fp_lines, g_lines, g_nlines);
    222   rewind(fp_lines);
    223 
    224   /* Load the isotope metadata and the lines */
    225   shtr_args.verbose = 1;
    226   CHK(shtr_create(&shtr_args, &shtr) == RES_OK);
    227   CHK(shtr_isotope_metadata_load_stream(shtr, fp_mdata, NULL, &metadata) == RES_OK);
    228   CHK(shtr_line_list_load_stream(shtr, fp_lines, NULL, &line_list) == RES_OK);
    229 
    230   CHK(fclose(fp_lines) == 0);
    231   CHK(fclose(fp_mdata) == 0);
    232 
    233   dev_args.verbose = 1;
    234   CHK(sln_device_create(&dev_args, &sln) == RES_OK);
    235 
    236   test_mixture(sln, metadata, line_list);
    237   test_mixture_serialization(sln, shtr, metadata, line_list);
    238 
    239   CHK(sln_device_ref_put(sln) == RES_OK);
    240   CHK(shtr_ref_put(shtr) == RES_OK);
    241   CHK(shtr_line_list_ref_put(line_list) == RES_OK);
    242   CHK(shtr_isotope_metadata_ref_put(metadata) == RES_OK);
    243   CHK(mem_allocated_size() == 0);
    244   return 0;
    245 }