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 }