star-line

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

test_sln_tree_sample.c (5261B)


      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 file is part of Star-Line.
      7  *
      8  * This program is free software: you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation, either version 3 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     20 
     21 #include "test_sln_lines.h"
     22 
     23 #include "sln.h"
     24 
     25 #include <rsys/mem_allocator.h>
     26 #include <rsys/rsys.h>
     27 
     28 #include <star/ssp.h>
     29 
     30 /*******************************************************************************
     31  * Helper functions
     32  ******************************************************************************/
     33 static struct shtr_isotope_metadata*
     34 setup_isotopes
     35   (struct shtr* shtr,
     36    struct sln_molecule molecules[SHTR_MAX_MOLECULE_COUNT])
     37 {
     38   struct shtr_isotope_metadata* metadata = NULL;
     39   FILE* fp = NULL;
     40 
     41   CHK(fp = tmpfile());
     42   fprintf(fp, "Molecule # Iso Abundance Q(296K) gj Molar Mass(g)\n");
     43   write_shtr_molecule(fp, &g_H2O);
     44   write_shtr_molecule(fp, &g_CO2);
     45   write_shtr_molecule(fp, &g_O3);
     46   rewind(fp);
     47 
     48   CHK(molecules);
     49   molecules[SHTR_H2O].concentration = 0.15;
     50   molecules[SHTR_H2O].cutoff = 25; /* [cm^-1] */
     51   molecules[SHTR_CO2].concentration = 0.10;
     52   molecules[SHTR_CO2].cutoff = 50; /* [cm^-1] */
     53   molecules[SHTR_O3].concentration = 0.05;
     54   molecules[SHTR_O3].cutoff = 25; /* [cm^-1] */
     55 
     56   CHK(shtr_isotope_metadata_load_stream(shtr, fp, NULL, &metadata) == RES_OK);
     57 
     58   CHK(fclose(fp) == 0);
     59 
     60   return metadata;
     61 }
     62 
     63 static struct shtr_line_list*
     64 setup_lines(struct shtr* shtr)
     65 {
     66   struct shtr_line_list_load_args args = SHTR_LINE_LIST_LOAD_ARGS_NULL;
     67   struct shtr_line_list* lines = NULL;
     68   FILE* fp = NULL;
     69 
     70   CHK(fp = tmpfile());
     71   write_shtr_lines(fp, g_lines, g_nlines);
     72   rewind(fp);
     73 
     74   args.filename = "stream";
     75   args.file = fp;
     76   CHK(shtr_line_list_load(shtr, &args, &lines) == RES_OK);
     77 
     78   CHK(fclose(fp) == 0);
     79 
     80   return lines;
     81 }
     82 
     83 static void
     84 test_sample(struct sln_tree* tree)
     85 {
     86   struct ssp_rng* rng = NULL;
     87   const struct sln_node* node = NULL;
     88   const struct sln_node* leaf = NULL;
     89   double nu = 0; /* [cm^-2] */
     90   double proba = 0;
     91 
     92   CHK(ssp_rng_create(NULL, SSP_RNG_MT19937_64, &rng) == RES_OK);
     93 
     94   CHK(node = sln_tree_get_root(tree));
     95 
     96   /* Set an arbitrary wave number within the range of the lines */
     97   nu = (g_lines[g_nlines-1].wavenumber + g_lines[0].wavenumber) / 3.0;
     98 
     99   CHK(sln_node_sample_leaf(NULL, node, nu, rng, NULL) == NULL);
    100   CHK(sln_node_sample_leaf(tree, NULL, nu, rng, NULL) == NULL);
    101   CHK(sln_node_sample_leaf(tree, node, nu, NULL, NULL) == NULL);
    102   CHK(sln_node_sample_leaf(tree, node, nu, rng, NULL) != NULL);
    103 
    104   CHK(leaf = sln_node_sample_leaf(tree, node, nu, rng, &proba));
    105   CHK(proba > 0 && proba < 1);
    106 
    107   CHK(sln_node_sample_leaf(tree, leaf, nu, rng, &proba));
    108   CHK(proba == 1);
    109 
    110   /* Attempt to sample a line outside the spectral range. There are no lines
    111    * with a non-zero value at the wavelength in question. In this case, the
    112    * library assumes that no line can be sampled.
    113    *
    114    * To ensure that the nu value corresponds to a wave number whose value at the
    115    * node is 0, take the last line and add 51 cm^-1 to it, which is 1 cm^-1 more
    116    * than the maximum cutoff defined for the molecules in the mixture */
    117   nu = g_lines[g_nlines-1].wavenumber + 51 /* [cm^-1] */;
    118   CHK(sln_node_sample_leaf(tree, node, nu, rng, &proba) == NULL);
    119   CHK(sln_node_sample_leaf(tree, node, INF, rng, &proba) == NULL);
    120 
    121   CHK(ssp_rng_ref_put(rng) == RES_OK);
    122 }
    123 
    124 /*******************************************************************************
    125  * The test
    126  ******************************************************************************/
    127 int
    128 main(void)
    129 {
    130   struct sln_device_create_args dev_args = SLN_DEVICE_CREATE_ARGS_DEFAULT;
    131   struct sln_tree_create_args tree_args = SLN_TREE_CREATE_ARGS_DEFAULT;
    132   struct sln_device* sln = NULL;
    133   struct sln_tree* tree = NULL;
    134 
    135   struct shtr_create_args shtr_args = SHTR_CREATE_ARGS_DEFAULT;
    136   struct shtr* shtr = NULL;
    137 
    138   shtr_args.verbose = 1;
    139   CHK(shtr_create(&shtr_args, &shtr) == RES_OK);
    140 
    141   dev_args.verbose = 1;
    142   CHK(sln_device_create(&dev_args, &sln) == RES_OK);
    143 
    144   tree_args.metadata = setup_isotopes(shtr, tree_args.molecules);
    145   tree_args.lines = setup_lines(shtr);
    146   tree_args.pressure = 10; /* [atm] */
    147   tree_args.temperature = 600; /* [K] */
    148   CHK(sln_tree_create(sln, &tree_args, &tree) == RES_OK);
    149 
    150   test_sample(tree);
    151 
    152   CHK(shtr_ref_put(shtr) == RES_OK);
    153   CHK(shtr_line_list_ref_put(tree_args.lines) == RES_OK);
    154   CHK(shtr_isotope_metadata_ref_put(tree_args.metadata) == RES_OK);
    155 
    156   CHK(sln_tree_ref_put(tree) == RES_OK);
    157   CHK(sln_device_ref_put(sln) == RES_OK);
    158 
    159   CHK(mem_allocated_size() == 0);
    160   return 0;
    161 }