star-line

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

commit d22920c3f0f714d80ddaf777517fb27a2043be6b
parent 7b34ed7cc0268d32267ef232c9f3cb8535ef07f1
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 26 May 2022 12:37:27 +0200

Add the sln_mesh_eval function

Diffstat:
Msrc/sln.h | 5+++++
Msrc/sln_line.c | 2+-
Msrc/sln_tree.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Msrc/sln_tree_build.c | 2+-
4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/src/sln.h b/src/sln.h @@ -276,6 +276,11 @@ sln_node_get_mesh const struct sln_node* node, struct sln_mesh* mesh); +SLN_API float +sln_mesh_eval + (const struct sln_mesh* mesh, + const float wavenumber); /* In cm^-1 */ + SLN_API res_T sln_tree_write (const struct sln_tree* tree, diff --git a/src/sln_line.c b/src/sln_line.c @@ -634,7 +634,7 @@ line_mesh darray_double_init(tree->mixture->sln->allocator, &wavenumbers); /* Adjust the hint on the number of vertices. This is not actually the real - * number of vertices but a adjusted hint on it. This new value ensures that + * number of vertices but an adjusted hint on it. This new value ensures that * it is a power of 2 included in [MIN_NVERTICES_HINT, MAX_NVERTICES_HINT] */ nvertices_adjusted = CLAMP (nvertices_hint, MIN_NVERTICES_HINT, MAX_NVERTICES_HINT); diff --git a/src/sln_tree.c b/src/sln_tree.c @@ -23,6 +23,8 @@ #include "sln_tree_c.h" #include <star/shtr.h> + +#include <rsys/algorithm.h> #include <rsys/cstr.h> /******************************************************************************* @@ -109,6 +111,16 @@ store_input_args return RES_OK; } +static INLINE int +cmp_nu_vtx(const void* key, const void* item) +{ + const float nu = *((const float*)key); + const struct sln_vertex* vtx = item; + if(nu < vtx->wavenumber) return -1; + if(nu > vtx->wavenumber) return +1; + return 0; +} + static void release_tree(ref_T* ref) { @@ -317,6 +329,39 @@ sln_node_get_mesh return RES_OK; } +float +sln_mesh_eval(const struct sln_mesh* mesh, const float nu) +{ + const struct sln_vertex* vtx0 = NULL; + const struct sln_vertex* vtx1 = NULL; + size_t n; /* #vertices */ + float u; /* Linear interpolation paraeter */ + ASSERT(mesh && nu >= 0); + + n = mesh->nvertices; + + /* Handle special cases */ + if(n == 0) return 0; + if(n == 1) return mesh->vertices[0].ka; + if(nu <= mesh->vertices[0].wavenumber) return mesh->vertices[0].ka; + if(nu >= mesh->vertices[n-1].wavenumber) return mesh->vertices[n-1].ka; + + /* Dichotomic search of the mesh vertex whose wavenumber is greater than the + * submitted wavenumber 'nu' */ + vtx1 = search_lower_bound(&nu, mesh->vertices, n, sizeof(*vtx1), cmp_nu_vtx); + vtx0 = vtx1 - 1; + ASSERT(vtx1); /* A vertex is necessary found ...*/ + ASSERT(vtx1 > mesh->vertices); /* ... and it cannot be the first one */ + + /* Compute the linear interpolation parameter */ + u = (nu - vtx0->wavenumber) / (vtx1->wavenumber - vtx0->wavenumber); + u = CLAMP(u, 0, 1); /* Handle numerical imprecisions */ + + if(u == 0) return vtx0->ka; + if(u == 1) return vtx1->ka; + return u*(vtx1->ka - vtx0->ka) + vtx0->ka; +} + res_T sln_tree_write(const struct sln_tree* tree, FILE* stream) { diff --git a/src/sln_tree_build.c b/src/sln_tree_build.c @@ -294,7 +294,7 @@ partition_lines const size_t split = NODE(inode)->range[0] + (nlines + 1/*ceil*/)/2; /* Compute the index toward the 2 children (first is the left child, - * followed by the righ child) */ + * followed by the right child) */ size_t ichildren = darray_node_size_get(&tree->nodes); ASSERT(NODE(inode)->range[0] <= split);