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:
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;
+}