star-line

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

commit 56fc20939a04b6ce553dfd9dc2da0ce1dd2b3b87
parent 8e7a5b5825d3ae39f99e1cca59be5b12632f41f2
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  4 May 2022 16:43:53 +0200

Clip the line mesh to the spectral range

Diffstat:
Msrc/sln.h | 17++++++++++++++++-
Msrc/sln_line.c | 58+++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/sln_tree_c.h | 7+------
3 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/src/sln.h b/src/sln.h @@ -76,7 +76,8 @@ 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]; - size_t nisotopes; /* 0 <=> select all the isotopes of the molecules */ + /* 0 <=> select all the isotopes of the molecules with refernce abundance */ + size_t nisotopes; double concentration; double cutoff; /* in cm^-1 */ @@ -122,6 +123,20 @@ struct sln_tree_desc { #define SLN_TREE_DESC_NULL__ {{0,0},0,0,0,0} static const struct sln_tree_desc SLN_TREE_DESC_NULL = SLN_TREE_DESC_NULL__; +struct sln_vertex { /* 8 Bytes */ + float wavenumber; /* in cm^-1 */ + float ka; +}; +#define SLN_VERTEX_NULL__ {0,0} +static const struct sln_vertex SLN_VERTEX_NULL = SLN_VERTEX_NULL__; + +struct sln_mesh { + const struct sln_vertex* vertices; + size_t nvertices; +}; +#define SLN_MESH_NULL__ {NULL,0} +static const struct sln_mesh SLN_MESH_NULL = SLN_MESH_NULL__; + /* Forward declarations of opaque data structures */ struct sln_device; struct sln_tree; diff --git a/src/sln_line.c b/src/sln_line.c @@ -197,6 +197,8 @@ regular_mesh_fragmented ASSERT(tree && line && mol_params && wavenumbers); ASSERT(fragment_length > 0); ASSERT(IS_POW2(nvertices)); + ASSERT(line->wavenumber + mol_params->cutoff > tree->wavenumber_range[0]); + ASSERT(line->wavenumber - mol_params->cutoff < tree->wavenumber_range[1]); /* Compute the spectral range of the line from its center to its cutoff */ line_nu_min = line->wavenumber; @@ -236,7 +238,10 @@ eval_mesh const struct darray_double* wavenumbers, struct darray_double* values) { + const struct shtr_line* shtr_line = NULL; size_t ivertex, nvertices; + double range[2]; + double cutoff; res_T res = RES_OK; ASSERT(tree && wavenumbers && values); @@ -246,8 +251,24 @@ eval_mesh res = darray_double_resize(values, nvertices); if(res != RES_OK) goto error; + SHTR(lines_view_get_line(tree->lines_view, iline, &shtr_line)); + + /* Calculate the spectral range in which the vertices should be evaluated. + * Recall that a line being symmetrical in its center, we will only evaluate + * its upper half. Anyway, note that a line clipped by the spectral range is + * no longer symmetric. In the following, we thus adjust the spectral range + * to emit all the vertices needed to mesh the upper half _and_ the lower + * half of a possibly clipped line */ + cutoff = MMAX + (shtr_line->wavenumber - tree->wavenumber_range[0], + tree->wavenumber_range[1] - shtr_line->wavenumber); + range[0] = MMIN(shtr_line->wavenumber, tree->wavenumber_range[0]); + range[1] = shtr_line->wavenumber + cutoff; + FOR_EACH(ivertex, 0, nvertices) { const double nu = darray_double_cdata_get(wavenumbers)[ivertex]; + if(nu < range[0]) continue; + if(nu > range[1]) break; darray_double_data_get(values)[ivertex] = line_value(tree, iline, nu); } @@ -372,23 +393,50 @@ line_mesh goto error; } - /* Copy the first half of the line vertices */ i = tree_nvertices; + + /* Emit the 1st vertex for the lower bound of the spectral range if the line + * cut it */ + if(line->wavenumber - mol_params->cutoff <= tree->wavenumber_range[0]) { + struct sln_vertex* vtx = darray_vertex_data_get(&tree->vertices) + i; + vtx->wavenumber = (float)tree->wavenumber_range[0]; + vtx->ka = (float)line_value(tree, iline, vtx->wavenumber); + ++i; + } + + /* Copy the first half of the line vertices */ FOR_EACH_REVERSE(ivertex, line_nvertices-1, 0) { - struct vertex* vtx = darray_vertex_data_get(&tree->vertices) + i; - vtx->wavenumber = (float)darray_double_cdata_get(&wavenumbers)[ivertex]; + struct sln_vertex* vtx = darray_vertex_data_get(&tree->vertices) + i; + double nu = (float)darray_double_cdata_get(&wavenumbers)[ivertex]; + nu = line->wavenumber - nu + line->wavenumber; + if(nu <= tree->wavenumber_range[0]) continue;/* Out of range */ + vtx->wavenumber = (float)nu; vtx->ka = (float)darray_double_cdata_get(&values)[ivertex]; ++i; } /* Copy the vertex of the line center and the second half of the line * vertices */ FOR_EACH(ivertex, 0, line_nvertices) { - struct vertex* vtx = darray_vertex_data_get(&tree->vertices) + i; - vtx->wavenumber = (float)darray_double_cdata_get(&wavenumbers)[ivertex]; + struct sln_vertex* vtx = darray_vertex_data_get(&tree->vertices) + i; + const double nu = darray_double_cdata_get(&wavenumbers)[ivertex]; + if(nu >= tree->wavenumber_range[1]) break;/* Out of range */ + vtx->wavenumber = (float)nu; vtx->ka = (float)darray_double_cdata_get(&values)[ivertex]; ++i; } + /* Emit the last vertex for the upper bound of the spectral range */ + if(line->wavenumber + mol_params->cutoff >= tree->wavenumber_range[1]) { + struct sln_vertex* vtx = darray_vertex_data_get(&tree->vertices) + i; + vtx->wavenumber = (float)tree->wavenumber_range[1]; + vtx->ka = (float)line_value(tree, iline, vtx->wavenumber); + ++i; + } + + /* Several vertices could be deleted due to spectral range. So, resize the + * list of vertices to the effective number of registered vertices. */ + CHK(darray_vertex_resize(&tree->vertices, i) == RES_OK); + exit: darray_double_release(&values); darray_double_release(&wavenumbers); diff --git a/src/sln_tree_c.h b/src/sln_tree_c.h @@ -40,11 +40,6 @@ struct sln_node { /* 32 Bytes */ #define SLN_NODE_NULL__ {{0,0},0,0,0} static const struct sln_node SLN_NODE_NULL = SLN_NODE_NULL__; -struct vertex { /* 8 Bytes */ - float wavenumber; /* in cm^-1 */ - float ka; -}; - /* Generate the dynamic array of lines */ #define DARRAY_DATA struct line #define DARRAY_NAME line @@ -56,7 +51,7 @@ struct vertex { /* 8 Bytes */ #include <rsys/dynamic_array.h> /* Generate the dynamic array of vertices */ -#define DARRAY_DATA struct vertex +#define DARRAY_DATA struct sln_vertex #define DARRAY_NAME vertex #include <rsys/dynamic_array.h>