commit 9944f8cb2ed045e8a5d4f68cae978269516e08fd
parent 7176d1321f3feec29c5587a3d06854a109e7bfcb
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 25 Jul 2022 12:04:17 +0200
Start implementing the test_rnatm program
Diffstat:
2 files changed, 242 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -107,6 +107,8 @@ if(NOT NO_TEST)
add_test(${_name} ${_name})
endfunction()
+ build_test(test_rnatm)
+
endif()
################################################################################
diff --git a/src/test_rnatm.c b/src/test_rnatm.c
@@ -0,0 +1,240 @@
+/* Copyright (C) 2022 Centre National de la Recherche Scientifique
+ * Copyright (C) 2022 Institut de Physique du Globe de Paris
+ * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université de Reims Champagne-Ardenne
+ * Copyright (C) 2022 Université de Versaille Saint-Quentin
+ * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr)
+ *
+ * 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/>. */
+
+#define _POSIX_C_SOURCE 200809L /* strdup, strtok_r & wordexp */
+
+#include "rnatm.h"
+
+#include <rsys/cstr.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/rsys.h>
+
+#include <getopt.h>
+#include <string.h>
+#include <wordexp.h>
+
+struct args {
+ struct rnatm_create_args rnatm;
+ int quit;
+};
+#define ARGS_DEFAULT__ { RNATM_CREATE_ARGS_DEFAULT__, 0 }
+static const struct args ARGS_DEFAULT = ARGS_DEFAULT__;
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+print_help(const char* cmd)
+{
+ ASSERT(cmd);
+ printf(
+"Usage: %s -g gas\n"
+"Test the Rad-Net ATMosphere library\n\n",
+ cmd);
+ printf(
+" -g gas Atmospheric gas mixture. This mixture is defined by\n"
+" the following list of parameters, each parameter\n"
+" separated from the previous one by the character ':'\n\n");
+ printf(
+" mesh=path Gas mesh (smsh(5))\n"
+" ck=path Correlated-K of the mixture (sck(5))\n"
+" temp=path Temperatures\n\n");
+ printf(
+" -h display this help and exit\n");
+ printf(
+" -N precompute_normals the tetrahedra normals\n");
+ printf(
+" -t nthreads hint on the number of threads to use. By default use\n"
+" as many threads as CPU cores\n");
+ printf(
+" -V definition advice on the definiton of the acceleration\n"
+" structure along the 3 axes. Default is %u\n",
+ ARGS_DEFAULT.rnatm.grid_definition_hint);
+ printf(
+" -v make the program verbose\n");
+ printf("\n");
+ printf(
+"This is free software released under the GNU GPL license, version 3 or\n"
+"later. You are free to change or redistribute it under certain\n"
+"conditions <http://gnu.org.licenses/gpl.html>\n");
+}
+
+static res_T
+parse_gas_parameters(const char* str, void* ptr)
+{
+ char buf[BUFSIZ];
+ wordexp_t wexp;
+ struct args* args = ptr;
+ char* key;
+ char* val;
+ char* tk_ctx;
+ res_T res = RES_OK;
+ int wexp_is_allocated = 0;
+ int err = 0;
+ ASSERT(args && str);
+
+ if(strlen(str) >= sizeof(buf) -1/*NULL char*/) {
+ fprintf(stderr, "Could not duplicate the gas parameter `%s'\n", str);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ strncpy(buf, str, sizeof(buf));
+
+ key = strtok_r(buf, "=", &tk_ctx);
+ val = strtok_r(NULL, "", &tk_ctx);
+
+ err = wordexp(val, &wexp, 0/*flags*/);
+ if(err) {
+ fprintf(stderr, "Unable to expand the parameter value `%s'\n", str);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ wexp_is_allocated = 1;
+ if(wexp.we_wordc != 1) {
+ fprintf(stderr, "Invalid parameter value `%s'\n", str);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(!strcmp(key, "mesh")) {
+ args->rnatm.gas.smsh_filename = strdup(val);
+ if(!args->rnatm.gas.smsh_filename) res = RES_MEM_ERR;
+ } else if(!strcmp(key, "ck")) {
+ args->rnatm.gas.sck_filename = strdup(val);
+ if(!args->rnatm.gas.sck_filename) res = RES_MEM_ERR;
+ } else if(!strcmp(key, "temp")) {
+ args->rnatm.gas.temperatures_filename = strdup(val);
+ if(!args->rnatm.gas.temperatures_filename) res = RES_MEM_ERR;
+ } else {
+ fprintf(stderr, "Invalid gas parameter `%s'\n", key);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(res != RES_OK) {
+ fprintf(stderr, "Unable to parse the gas parameter `%s' -- %s\n",
+ str, res_to_cstr(res));
+ goto error;
+ }
+
+exit:
+ if(wexp_is_allocated) wordfree(&wexp);
+ return res;
+error:
+ goto exit;
+}
+
+static void
+args_release(struct args* args)
+{
+ ASSERT(args);
+ if(args->rnatm.gas.smsh_filename) free(args->rnatm.gas.smsh_filename);
+ if(args->rnatm.gas.sck_filename) free(args->rnatm.gas.sck_filename);
+ if(args->rnatm.gas.temperatures_filename)
+ free(args->rnatm.gas.temperatures_filename);
+ *args = ARGS_DEFAULT;
+}
+
+static res_T
+args_init(struct args* args, int argc, char** argv)
+{
+ res_T res = RES_OK;
+ int opt;
+ ASSERT(args && argc && argv);
+
+ *args = ARGS_DEFAULT;
+
+ while((opt = getopt(argc, argv, "g:hN:t:V:v")) != -1) {
+ switch(opt) {
+ case 'g':
+ res = cstr_parse_list(optarg, ':', parse_gas_parameters, args);
+ break;
+ case 'h':
+ print_help(argv[0]);
+ args_release(args);
+ args->quit = 1;
+ goto exit;
+ case 'N': args->rnatm.precompute_normals = 1; break;
+ case 't':
+ res = cstr_to_uint(optarg, &args->rnatm.nthreads);
+ if(res == RES_OK && !args->rnatm.nthreads) res = RES_BAD_ARG;
+ break;
+ case 'V':
+ res = cstr_to_uint(optarg, &args->rnatm.grid_definition_hint);
+ if(res == RES_OK && !args->rnatm.grid_definition_hint) res = RES_BAD_ARG;
+ break;
+ case 'v': args->rnatm.verbose = 1; break;
+ default: res = RES_BAD_ARG; break;
+ }
+ if(res != RES_OK) {
+ if(optarg) {
+ fprintf(stderr, "%s: invalid option args `%s' -- `%c'\n",
+ argv[0], optarg, opt);
+ }
+ goto error;
+ }
+ }
+
+ /* Check the required options */
+ if(!args->rnatm.gas.smsh_filename
+ || !args->rnatm.gas.sck_filename
+ || !args->rnatm.gas.temperatures_filename) {
+ fprintf(stderr, "Incomplete gas definition -- option `-g'\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ args_release(args);
+ goto exit;
+}
+
+/*******************************************************************************
+ * Main function
+ ******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct args args = ARGS_DEFAULT;
+ struct rnatm* rnatm = NULL;
+ res_T res = RES_OK;
+ int err = 0;
+
+ res = args_init(&args, argc, argv);
+ if(res != RES_OK) goto error;
+
+ res = rnatm_create(&args.rnatm, &rnatm);
+ if(res != RES_OK) goto error;
+
+exit:
+ args_release(&args);
+ if(rnatm) RNATM(ref_put(rnatm));
+ if(mem_allocated_size() != 0) {
+ fprintf(stderr, "Memory leaks: %lu bytes\n",
+ (unsigned long)mem_allocated_size());
+ err = -1;
+ }
+ return err;
+error:
+ err = -1;
+ goto exit;
+}