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:
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);