rnatm

Load and structure data describing an atmosphere
git clone git://git.meso-star.fr/rnatm.git
Log | Files | Refs | README | LICENSE

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:
Mcmake/CMakeLists.txt | 2++
Asrc/test_rnatm.c | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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; +}