star-line

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

commit 81cd4fc0668cc86d6f4a2d89fa3d3787981a7e4d
parent 2ac21f91e0b8983625b0a4218d22697e24d839f4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 26 May 2022 18:47:29 +0200

Add mesh type to the arguments of sln_tree_create

Diffstat:
Msrc/sln.h | 28++++++++++++++++++++--------
Msrc/sln_line.c | 24++++++++++--------------
Msrc/sln_line.h | 7-------
Msrc/sln_tree.c | 10++++++++--
Msrc/sln_tree_build.c | 15++++++---------
Msrc/sln_tree_c.h | 3++-
Msrc/test_sln_tree.c | 5+++++
7 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/src/sln.h b/src/sln.h @@ -45,7 +45,7 @@ #define SLN_MAX_MOLECULES_COUNT 100 #define SLN_MAX_ISOTOPES_COUNT 10 -/* Forwar declaration of external data structures */ +/* Forward declaration of external data structures */ struct logger; struct mem_allocator; struct shtr; @@ -53,6 +53,12 @@ struct shtr_line; struct shtr_isotope_metadata; struct shtr_line_list; +enum sln_mesh_type { + SLN_MESH_UPPER, /* Mesh that majorize the underlying lines */ + SLN_MESH_USUAL, /* Mesh of the lines */ + SLN_MESH_TYPES_COUNT__ +}; + enum sln_line_profile { SLN_LINE_PROFILE_VOIGT, SLN_LINE_PROFILES_COUNT__ @@ -77,7 +83,7 @@ static const struct sln_isotope SLN_ISOTOPE_NULL = SLN_ISOTOPE_NULL__; struct sln_molecule { /* List of isotopes to be taken into account */ struct sln_isotope isotopes[SLN_MAX_ISOTOPES_COUNT]; - /* 0 <=> select all the isotopes of the molecules with refernce abundance */ + /* 0 <=> select all the isotopes of the molecules with reference abundance */ size_t nisotopes; double concentration; @@ -113,7 +119,7 @@ struct sln_mixture_desc { double wavenumber_range[2]; /* Spectral range */ double pressure; /* In atm */ double temperature; /* In K */ - size_t nlines; /* Number of partitionned lines */ + size_t nlines; /* Number of partitioned lines */ }; #define SLN_MIXTURE_DESC_NULL__ {{0,0},0,0,0} static const struct sln_mixture_desc SLN_MIXTURE_DESC_NULL = @@ -123,25 +129,31 @@ struct sln_tree_create_args { /* Max number of lines per leaf */ size_t max_nlines_per_leaf; - /* Hint on the number of vertices around the the line center */ + /* Hint on the number of vertices around the line center */ size_t nvertices_hint; /* Relative error used to simplify the spectrum mesh. The larger it is, the * coarser the mesh */ - float mesh_decimation_err; + float mesh_decimation_err; /* > 0 */ + enum sln_mesh_type mesh_type; /* Type of mesh to generate */ enum sln_line_profile line_profile; }; -#define SLN_TREE_CREATE_ARGS_DEFAULT__ {1, 16, 0.01f, SLN_LINE_PROFILE_VOIGT} +#define SLN_TREE_CREATE_ARGS_DEFAULT__ { \ + 1, 16, 0.01f, SLN_MESH_UPPER, SLN_LINE_PROFILE_VOIGT \ +} static const struct sln_tree_create_args SLN_TREE_CREATE_ARGS_DEFAULT = SLN_TREE_CREATE_ARGS_DEFAULT__; struct sln_tree_desc { size_t max_nlines_per_leaf; /* max #lines per leaf */ - double mesh_decimation_err; + float mesh_decimation_err; + enum sln_mesh_type mesh_type; enum sln_line_profile line_profile; }; -#define SLN_TREE_DESC_NULL__ {0,0,0} +#define SLN_TREE_DESC_NULL__ { \ + 0, 0, SLN_MESH_TYPES_COUNT__, SLN_LINE_PROFILES_COUNT__ \ +} static const struct sln_tree_desc SLN_TREE_DESC_NULL = SLN_TREE_DESC_NULL__; struct sln_vertex { /* 8 Bytes */ diff --git a/src/sln_line.c b/src/sln_line.c @@ -382,7 +382,6 @@ save_line_mesh const double spectral_range[2], const struct darray_double* wavenumbers, const struct darray_double* values, - const enum mesh_type mesh_type, size_t vertices_range[2]) /* Range into which the line vertices are saved */ { const struct line* line = NULL; @@ -397,7 +396,6 @@ save_line_mesh ASSERT(tree && mol_params && wavenumbers && values && vertices_range); ASSERT(darray_double_size_get(wavenumbers) == darray_double_size_get(values)); - ASSERT((unsigned)mesh_type < MESH_TYPES_COUNT__); ASSERT(spectral_range && spectral_range[0] <= spectral_range[1]); line = darray_line_cdata_get(&tree->mixture->lines) + iline; @@ -430,14 +428,14 @@ save_line_mesh const double nu = spectral_range[0]; double ha = 0; - switch(mesh_type) { - case MESH_UPPER_BOUND: + switch(tree->mesh_type) { + case SLN_MESH_UPPER: ha = nu > line->wavenumber ? next_vertex_value(nu, wavenumbers, values) : next_vertex_value(MIRROR(nu), wavenumbers, values); break; - case MESH_USUAL: + case SLN_MESH_USUAL: ha = line_value(tree->mixture, iline, tree->line_profile, nu); break; @@ -495,14 +493,14 @@ save_line_mesh const double nu = spectral_range[1]; double ha = 0; - switch(mesh_type) { - case MESH_UPPER_BOUND: + switch(tree->mesh_type) { + case SLN_MESH_UPPER: ha = nu > line->wavenumber ? next_vertex_value(nu, wavenumbers, values) : next_vertex_value(MIRROR(nu), wavenumbers, values); break; - case MESH_USUAL: + case SLN_MESH_USUAL: ha = line_value(tree->mixture, iline, tree->line_profile, nu); break; @@ -613,7 +611,6 @@ line_mesh (struct sln_tree* tree, const size_t iline, const size_t nvertices_hint, - const enum mesh_type mesh_type, size_t vertices_range[2]) { struct darray_double values; /* List of evaluated values */ @@ -625,7 +622,6 @@ line_mesh res_T res = RES_OK; ASSERT(tree && nvertices_hint); ASSERT(iline < darray_line_size_get(&tree->mixture->lines)); - ASSERT((unsigned)mesh_type < MESH_TYPES_COUNT__); line = darray_line_cdata_get(&tree->mixture->lines) + iline; SHTR(line_view_get_line(tree->mixture->line_view, iline, &shtr_line)); @@ -652,16 +648,16 @@ line_mesh * wavenumbers */ eval_mesh(tree->mixture, iline, &wavenumbers, tree->line_profile, &values); - switch(mesh_type) { - case MESH_UPPER_BOUND: + switch(tree->mesh_type) { + case SLN_MESH_UPPER: snap_mesh_to_upper_bound(&wavenumbers, &values); break; - case MESH_USUAL: /* Do nothing */ break; + case SLN_MESH_USUAL: /* Do nothing */ break; default: FATAL("Unreachable code.\n"); break; } res = save_line_mesh(tree, iline, mol_params, tree->mixture->wavenumber_range, - &wavenumbers, &values, mesh_type, vertices_range); + &wavenumbers, &values, vertices_range); if(res != RES_OK) goto error; exit: diff --git a/src/sln_line.h b/src/sln_line.h @@ -32,12 +32,6 @@ struct line { double gamma_l; /* Lorentz half width */ }; -enum mesh_type { - MESH_UPPER_BOUND, - MESH_USUAL, - MESH_TYPES_COUNT__ -}; - /* Forward declaration */ struct sln_mixture; struct sln_tree; @@ -69,7 +63,6 @@ line_mesh (struct sln_tree* tree, const size_t iline, const size_t nvertices_hint, - const enum mesh_type mesh_type, /* Range of generated line vertices. Upper bound is inclusive */ size_t vertices_range[2]); diff --git a/src/sln_tree.c b/src/sln_tree.c @@ -62,9 +62,13 @@ check_sln_tree_create_args return RES_BAD_ARG; } + if((unsigned)args->mesh_type >= SLN_MESH_TYPES_COUNT__) { + log_err(sln, "%s: invalid mesh type %d.\n", caller, args->mesh_type); + return RES_BAD_ARG; + } + if((unsigned)args->line_profile >= SLN_LINE_PROFILES_COUNT__) { - log_err(sln, "%s: invalid line profile %d.\n", - caller, args->line_profile); + log_err(sln, "%s: invalid line profile %d.\n", caller, args->line_profile); return RES_BAD_ARG; } @@ -108,6 +112,7 @@ store_input_args ASSERT(args && tree); tree->max_nlines_per_leaf = args->max_nlines_per_leaf; tree->mesh_decimation_err = args->mesh_decimation_err; + tree->mesh_type = args->mesh_type; tree->line_profile = args->line_profile; return RES_OK; } @@ -268,6 +273,7 @@ sln_tree_get_desc(const struct sln_tree* tree, struct sln_tree_desc* desc) if(!tree || !desc) return RES_BAD_ARG; desc->max_nlines_per_leaf = tree->max_nlines_per_leaf; desc->mesh_decimation_err = tree->mesh_decimation_err; + desc->mesh_type = tree->mesh_type; desc->line_profile = tree->line_profile; return RES_OK; } diff --git a/src/sln_tree_build.c b/src/sln_tree_build.c @@ -55,8 +55,7 @@ build_leaf_polyline ASSERT(leaf->range[0] == leaf->range[1]); /* Line meshing */ - res = line_mesh(tree, leaf->range[0], args->nvertices_hint, MESH_USUAL, - vertices_range); + res = line_mesh(tree, leaf->range[0], args->nvertices_hint, vertices_range); if(res != RES_OK) goto error; /* Decimate the line mesh */ @@ -86,20 +85,18 @@ static INLINE double eval_ka (const struct sln_tree* tree, const struct sln_node* node, - const enum mesh_type type, const double wavenumber) { struct sln_mesh mesh = SLN_MESH_NULL; double ka = 0; ASSERT(tree && node && wavenumber >= 0); - ASSERT((unsigned)type < MESH_TYPES_COUNT__); - switch(type) { - case MESH_UPPER_BOUND: + switch(tree->mesh_type) { + case SLN_MESH_UPPER: SLN(node_get_mesh(tree, node, &mesh)); ka = sln_mesh_eval(&mesh, wavenumber); break; - case MESH_USUAL: + case SLN_MESH_USUAL: ka = sln_node_eval(tree, node, wavenumber); break; default: FATAL("Unreachable code.\n"); break; @@ -148,12 +145,12 @@ merge_node_polylines if(nu0 < nu1) { /* The vertex comes from the node0 */ nu = vertices[ivtx0].wavenumber; - ka = (float)(vertices[ivtx0].ka + eval_ka(tree, node1, MESH_USUAL, nu)); + ka = (float)(vertices[ivtx0].ka + eval_ka(tree, node1, nu)); ++ivtx0; } else if(nu0 > nu1) { /* The vertex comes from the node1 */ nu = vertices[ivtx1].wavenumber; - ka = (float)(vertices[ivtx1].ka + eval_ka(tree, node0, MESH_USUAL, nu)); + ka = (float)(vertices[ivtx1].ka + eval_ka(tree, node0, nu)); ++ivtx1; } else { /* The vertex is shared by node0 and node1 */ diff --git a/src/sln_tree_c.h b/src/sln_tree_c.h @@ -60,7 +60,8 @@ struct sln_tree { struct darray_vertex vertices; /* List of vertices */ size_t max_nlines_per_leaf; - double mesh_decimation_err; + float mesh_decimation_err; + enum sln_mesh_type mesh_type; enum sln_line_profile line_profile; struct sln_mixture* mixture; diff --git a/src/test_sln_tree.c b/src/test_sln_tree.c @@ -176,6 +176,7 @@ test_tree(struct sln_mixture* mixture, const struct shtr_line_list* line_list) CHK(desc.max_nlines_per_leaf == tree_args.max_nlines_per_leaf); CHK(desc.mesh_decimation_err == tree_args.mesh_decimation_err); + CHK(desc.mesh_type == tree_args.mesh_type); CHK(desc.line_profile == tree_args.line_profile); CHK(node = sln_tree_get_root(tree)); @@ -216,6 +217,10 @@ test_tree(struct sln_mixture* mixture, const struct shtr_line_list* line_list) CHK(sln_tree_create(mixture, &tree_args, &tree) == RES_BAD_ARG); tree_args.mesh_decimation_err = 1e-1f; + tree_args.mesh_type = SLN_MESH_TYPES_COUNT__; + CHK(sln_tree_create(mixture, &tree_args, &tree) == RES_BAD_ARG); + + tree_args.mesh_type = SLN_MESH_USUAL; tree_args.line_profile = SLN_LINE_PROFILES_COUNT__; CHK(sln_tree_create(mixture, &tree_args, &tree) == RES_BAD_ARG);