star-line

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

commit 2ac21f91e0b8983625b0a4218d22697e24d839f4
parent d22920c3f0f714d80ddaf777517fb27a2043be6b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 26 May 2022 17:40:59 +0200

Add the sln_node_eval function

Diffstat:
Msrc/sln.h | 10++++++++--
Msrc/sln_tree.c | 22++++++++++++++++++++--
Msrc/sln_tree_build.c | 35++++++++++++++++++++---------------
3 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/src/sln.h b/src/sln.h @@ -276,10 +276,16 @@ sln_node_get_mesh const struct sln_node* node, struct sln_mesh* mesh); -SLN_API float +SLN_API double +sln_node_eval + (const struct sln_tree* tree, + const struct sln_node* node, + const double wavenumber); /* In cm^-1 */ + +SLN_API double sln_mesh_eval (const struct sln_mesh* mesh, - const float wavenumber); /* In cm^-1 */ + const double wavenumber); /* In cm^-1 */ SLN_API res_T sln_tree_write diff --git a/src/sln_tree.c b/src/sln_tree.c @@ -18,6 +18,7 @@ #include "sln.h" #include "sln_device_c.h" +#include "sln_line.h" #include "sln_log.h" #include "sln_mixture_c.h" #include "sln_tree_c.h" @@ -329,11 +330,27 @@ sln_node_get_mesh return RES_OK; } -float -sln_mesh_eval(const struct sln_mesh* mesh, const float nu) +double +sln_node_eval + (const struct sln_tree* tree, + const struct sln_node* node, + const double nu) +{ + double ka = 0; + size_t iline; + ASSERT(tree && node && nu >= 0); + FOR_EACH(iline, node->range[0], node->range[1]+1) { + ka += line_value(tree->mixture, iline, tree->line_profile, nu); + } + return ka; +} + +double +sln_mesh_eval(const struct sln_mesh* mesh, const double wavenumber) { const struct sln_vertex* vtx0 = NULL; const struct sln_vertex* vtx1 = NULL; + const float nu = (float)wavenumber; size_t n; /* #vertices */ float u; /* Linear interpolation paraeter */ ASSERT(mesh && nu >= 0); @@ -352,6 +369,7 @@ sln_mesh_eval(const struct sln_mesh* mesh, const float nu) vtx0 = vtx1 - 1; ASSERT(vtx1); /* A vertex is necessary found ...*/ ASSERT(vtx1 > mesh->vertices); /* ... and it cannot be the first one */ + ASSERT(vtx0->wavenumber <= nu && nu < vtx1->wavenumber); /* Compute the linear interpolation parameter */ u = (nu - vtx0->wavenumber) / (vtx1->wavenumber - vtx0->wavenumber); diff --git a/src/sln_tree_build.c b/src/sln_tree_build.c @@ -83,19 +83,26 @@ error: } static INLINE double -compute_ka - (const struct sln_mixture* mixture, - const double wavenumber, - const enum sln_line_profile line_profile, - const size_t line_range[2]) +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; - size_t iline = 0; - ASSERT(mixture && wavenumber >= 0 && line_range); - ASSERT(line_range[0] <= line_range[1]); - - FOR_EACH(iline, line_range[0], line_range[1]+1) { - ka += line_value(mixture, iline, line_profile, wavenumber); + ASSERT(tree && node && wavenumber >= 0); + ASSERT((unsigned)type < MESH_TYPES_COUNT__); + + switch(type) { + case MESH_UPPER_BOUND: + SLN(node_get_mesh(tree, node, &mesh)); + ka = sln_mesh_eval(&mesh, wavenumber); + break; + case MESH_USUAL: + ka = sln_node_eval(tree, node, wavenumber); + break; + default: FATAL("Unreachable code.\n"); break; } return ka; } @@ -141,14 +148,12 @@ merge_node_polylines if(nu0 < nu1) { /* The vertex comes from the node0 */ nu = vertices[ivtx0].wavenumber; - ka = (float)(vertices[ivtx0].ka - + compute_ka(tree->mixture, nu, tree->line_profile, node1->range)); + ka = (float)(vertices[ivtx0].ka + eval_ka(tree, node1, MESH_USUAL, nu)); ++ivtx0; } else if(nu0 > nu1) { /* The vertex comes from the node1 */ nu = vertices[ivtx1].wavenumber; - ka = (float)(vertices[ivtx1].ka - + compute_ka(tree->mixture, nu, tree->line_profile, node0->range)); + ka = (float)(vertices[ivtx1].ka + eval_ka(tree, node0, MESH_USUAL, nu)); ++ivtx1; } else { /* The vertex is shared by node0 and node1 */