star-line

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

commit 2d7da76a223794081c173e8e234400d0aa8bacb4
parent b9a507dda31b40e9c2d7df291cd891217211d63a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 30 May 2022 15:12:01 +0200

Test the function sln_mesh_eval

Diffstat:
Mcmake/CMakeLists.txt | 1+
Msrc/sln_tree.c | 3+--
Asrc/test_sln_mesh.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -100,6 +100,7 @@ if(NOT NO_TEST) endfunction() new_test(test_sln_device) + new_test(test_sln_mesh) new_test(test_sln_mixture StarHITRAN) new_test(test_sln_tree StarHITRAN) endif() diff --git a/src/sln_tree.c b/src/sln_tree.c @@ -359,12 +359,11 @@ sln_mesh_eval(const struct sln_mesh* mesh, const double wavenumber) const float nu = (float)wavenumber; size_t n; /* #vertices */ float u; /* Linear interpolation paraeter */ - ASSERT(mesh && nu >= 0); + ASSERT(mesh && nu >= 0 && mesh->nvertices); 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; diff --git a/src/test_sln_mesh.c b/src/test_sln_mesh.c @@ -0,0 +1,81 @@ +/* Copyright (C) 2022 CNRS - LMD + * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com) + * Copyright (C) 2022 Université Paul Sabatier - IRIT + * Copyright (C) 2022 Université Paul Sabatier - Laplace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "sln.h" +#include <rsys/math.h> +#include <stdlib.h> + +static double +eval + (const struct sln_mesh* mesh, + const double nu) +{ + const struct sln_vertex* vtx0 = NULL; + const struct sln_vertex* vtx1 = NULL; + double u; + size_t i; + CHK(mesh && nu >= 0); + CHK(mesh->nvertices); + + FOR_EACH(i, 0, mesh->nvertices) { + if(nu <= mesh->vertices[i].wavenumber) break; + } + if(i == 0) return mesh->vertices[0].ka; + if(i == mesh->nvertices) return mesh->vertices[mesh->nvertices-1].ka; + + vtx1 = mesh->vertices+i; + vtx0 = mesh->vertices+i-1; + u = (nu - vtx0->wavenumber) / (vtx1->wavenumber - vtx0->wavenumber); + u = CLAMP(u, 0, 1); + + return u*vtx1->ka + (1.0-u)*vtx0->ka; +} + +int +main(int argc, char** argv) +{ + const struct sln_vertex vertices[] = { + {20, 20}, {40, 25}, {60, 40}, {80, 120}, {120, 140}, {200, 180} + }; + struct sln_mesh mesh = SLN_MESH_NULL; + size_t i; + (void)argc, (void)argv; + + mesh.vertices = vertices; + mesh.nvertices = sizeof(vertices)/sizeof(vertices[0]); + + CHK(sln_mesh_eval(&mesh, 10) == 20); + CHK(sln_mesh_eval(&mesh, 20) == 20); + CHK(sln_mesh_eval(&mesh, 201) == 180); + CHK(sln_mesh_eval(&mesh, 200) == 180); + + FOR_EACH(i, 0, 100) { + const double r = (double)rand() / (double)((size_t)RAND_MAX + 1); + const double nu = + mesh.vertices[0].wavenumber * (1.0 - r) + + mesh.vertices[mesh.nvertices-1].wavenumber * r; + const double val0 = eval(&mesh, nu); + const double val1 = sln_mesh_eval(&mesh, nu); + CHK(eq_eps(val0, val1, val1*1e-6)); + } + + mesh.nvertices = 1; + CHK(sln_mesh_eval(&mesh, 0) == 20); + CHK(sln_mesh_eval(&mesh, 40) == 20); + return 0; +}