star-line

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

commit 144a2ac7d11d8a9a31021d36450577ce75c19006
parent fb6d137ff898ab14582aa3743c76f4caad6f4e3a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 22 Sep 2026 10:28:57 +0200

Add missing source file

Diffstat:
Asrc/test_sln_tree_sample.c | 159+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 159 insertions(+), 0 deletions(-)

diff --git a/src/test_sln_tree_sample.c b/src/test_sln_tree_sample.c @@ -0,0 +1,159 @@ +/* Copyright (C) 2022, 2026 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2026 Université de Lorraine + * Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "test_sln_lines.h" + +#include "sln.h" + +#include <rsys/mem_allocator.h> +#include <rsys/rsys.h> + +#include <star/ssp.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static struct shtr_isotope_metadata* +setup_isotopes + (struct shtr* shtr, + struct sln_molecule molecules[SHTR_MAX_MOLECULE_COUNT]) +{ + struct shtr_isotope_metadata* metadata = NULL; + FILE* fp = NULL; + + CHK(fp = tmpfile()); + fprintf(fp, "Molecule # Iso Abundance Q(296K) gj Molar Mass(g)\n"); + write_shtr_molecule(fp, &g_H2O); + write_shtr_molecule(fp, &g_CO2); + write_shtr_molecule(fp, &g_O3); + rewind(fp); + + CHK(molecules); + molecules[SHTR_H2O].concentration = 0.15; + molecules[SHTR_H2O].cutoff = 25; /* [cm^-1] */ + molecules[SHTR_CO2].concentration = 0.10; + molecules[SHTR_CO2].cutoff = 50; /* [cm^-1] */ + molecules[SHTR_O3].concentration = 0.05; + molecules[SHTR_O3].cutoff = 25; /* [cm^-1] */ + + CHK(shtr_isotope_metadata_load_stream(shtr, fp, NULL, &metadata) == RES_OK); + + CHK(fclose(fp) == 0); + + return metadata; +} + +static struct shtr_line_list* +setup_lines(struct shtr* shtr) +{ + struct shtr_line_list_load_args args = SHTR_LINE_LIST_LOAD_ARGS_NULL; + struct shtr_line_list* lines = NULL; + FILE* fp = NULL; + + CHK(fp = tmpfile()); + write_shtr_lines(fp, g_lines, g_nlines); + rewind(fp); + + args.filename = "stream"; + args.file = fp; + CHK(shtr_line_list_load(shtr, &args, &lines) == RES_OK); + + CHK(fclose(fp) == 0); + + return lines; +} + +static void +test_sample(struct sln_tree* tree) +{ + struct ssp_rng* rng = NULL; + const struct sln_node* node = NULL; + const struct sln_node* leaf = NULL; + double nu = 0; /* [cm^-2] */ + double proba = 0; + + CHK(ssp_rng_create(NULL, SSP_RNG_MT19937_64, &rng) == RES_OK); + + CHK(node = sln_tree_get_root(tree)); + + /* Set an arbitrary wave number within the range of the lines */ + nu = (g_lines[g_nlines-1].wavenumber + g_lines[0].wavenumber) / 3.0; + + CHK(sln_node_sample_leaf(NULL, node, nu, rng, NULL) == NULL); + CHK(sln_node_sample_leaf(tree, NULL, nu, rng, NULL) == NULL); + CHK(sln_node_sample_leaf(tree, node, nu, NULL, NULL) == NULL); + CHK(sln_node_sample_leaf(tree, node, nu, rng, NULL) != NULL); + + CHK(leaf = sln_node_sample_leaf(tree, node, nu, rng, &proba)); + CHK(proba > 0 && proba < 1); + + CHK(sln_node_sample_leaf(tree, leaf, nu, rng, &proba)); + CHK(proba == 1); + + /* Attempt to sample a line outside the spectral range. There are no lines + * with a non-zero value at the wavelength in question. In this case, the + * library assumes that no line can be sampled. + * + * To ensure that the nu value corresponds to a wave number whose value at the + * node is 0, take the last line and add 51 cm^-1 to it, which is 1 cm^-1 more + * than the maximum cutoff defined for the molecules in the mixture */ + nu = g_lines[g_nlines-1].wavenumber + 51 /* [cm^-1] */; + CHK(sln_node_sample_leaf(tree, node, nu, rng, &proba) == NULL); + CHK(sln_node_sample_leaf(tree, node, INF, rng, &proba) == NULL); + + CHK(ssp_rng_ref_put(rng) == RES_OK); +} + +/******************************************************************************* + * The test + ******************************************************************************/ +int +main(void) +{ + struct sln_device_create_args dev_args = SLN_DEVICE_CREATE_ARGS_DEFAULT; + struct sln_tree_create_args tree_args = SLN_TREE_CREATE_ARGS_DEFAULT; + struct sln_device* sln = NULL; + struct sln_tree* tree = NULL; + + struct shtr_create_args shtr_args = SHTR_CREATE_ARGS_DEFAULT; + struct shtr* shtr = NULL; + + shtr_args.verbose = 1; + CHK(shtr_create(&shtr_args, &shtr) == RES_OK); + + dev_args.verbose = 1; + CHK(sln_device_create(&dev_args, &sln) == RES_OK); + + tree_args.metadata = setup_isotopes(shtr, tree_args.molecules); + tree_args.lines = setup_lines(shtr); + tree_args.pressure = 10; /* [atm] */ + tree_args.temperature = 600; /* [K] */ + CHK(sln_tree_create(sln, &tree_args, &tree) == RES_OK); + + test_sample(tree); + + CHK(shtr_ref_put(shtr) == RES_OK); + CHK(shtr_line_list_ref_put(tree_args.lines) == RES_OK); + CHK(shtr_isotope_metadata_ref_put(tree_args.metadata) == RES_OK); + + CHK(sln_tree_ref_put(tree) == RES_OK); + CHK(sln_device_ref_put(sln) == RES_OK); + + CHK(mem_allocated_size() == 0); + return 0; +}