rnatm

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

commit d667a1e2a4f467df08f37bf617b36b7eb63e6c67
parent ebfc97ea4433deb355742718438259ef9f1dbe4b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 26 Aug 2022 12:10:47 +0200

Add aerosols support to test_rnatm program

Diffstat:
Msrc/rnatm.h | 2+-
Msrc/test_rnatm.c | 165++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 148 insertions(+), 19 deletions(-)

diff --git a/src/rnatm.h b/src/rnatm.h @@ -81,7 +81,7 @@ static const struct rnatm_aerosol_args RNATM_AEROSOL_ARGS_NULL = struct rnatm_create_args { struct rnatm_gas_args gas; - const struct rnatm_aerosol_args* aerosols; + struct rnatm_aerosol_args* aerosols; size_t naerosols; char* name; /* Name of the atmosphere */ diff --git a/src/test_rnatm.c b/src/test_rnatm.c @@ -25,6 +25,7 @@ #include <rsys/cstr.h> #include <rsys/mem_allocator.h> #include <rsys/rsys.h> +#include <rsys/stretchy_array.h> #include <getopt.h> #include <string.h> @@ -50,6 +51,16 @@ print_help(const char* cmd) "Test the Rad-Net ATMosphere library\n\n", cmd); printf( +" -a aerosol atmospheric aerosol. Use this option as many times as\n" +" there are aerosols to declare. An aerosol is defined\n" +" by the following parameters, each parameter is\n" +" separated from the previous one by a colon (:)\n\n"); + printf( +" mesh=path aerosol mesh (smsh(5))\n" +" radprop=path radiative properties (sars(5))\n" +" phasefn=path list of phase functions\n" +" phaseids=path phase function id per node\n\n"); + printf( " -d file write the builded octrees to file according to the VTK\n" " file format. The octrees are written to standard ouput\n" " if the file is a dash (-). To split the resulting file\n" @@ -59,20 +70,20 @@ print_help(const char* cmd) " csplit -f octree -k file %%^#\\ vtk%% /^#\\ vtk/ {2}\n\n"); 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"); +" -g gas atmospheric gas mixture. This mixture is defined by\n" +" the following parameters, each parameter is separated\n" +" from the previous one by a colon (:)\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"); +" 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( " -s nu0,nu1 spectral range to consider (in cm^-1).\n" -" Default is [%g, %g] cm^1\n", +" Default is visible spectrum, i.e [%g, %g] cm^1\n", ARGS_DEFAULT.rnatm.spectral_range[0], ARGS_DEFAULT.rnatm.spectral_range[1]); printf( @@ -80,7 +91,7 @@ print_help(const char* cmd) " Default is %g\n", ARGS_DEFAULT.rnatm.optical_thickness); printf( -" -t nthreads hint on the number of threads to use. By default use\n" +" -t nthreads hint on the number of threads. Default assumes\n" " as many threads as CPU cores\n"); printf( " -V definition advice on the definiton of the acceleration\n" @@ -120,13 +131,10 @@ parse_gas_parameters(const char* str, void* ptr) key = strtok_r(buf, "=", &tk_ctx); val = strtok_r(NULL, "", &tk_ctx); - if(!strcmp(key, "mesh")) { - iparam = MESH; - } else if(!strcmp(key, "ck")) { - iparam = CK; - } else if(!strcmp(key, "temp")) { - iparam = TEMP; - } else { + if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "ck")) iparam = CK; + else if(!strcmp(key, "temp")) iparam = TEMP; + else { fprintf(stderr, "Invalid gas parameter `%s'\n", key); res = RES_BAD_ARG; goto error; @@ -140,13 +148,13 @@ parse_gas_parameters(const char* str, void* ptr) err = wordexp(val, &wexp, 0/*flags*/); if(err) { - fprintf(stderr, "Unable to expand the parameter value `%s'\n", str); + fprintf(stderr, "Unable to expand the value of the gas parameter`%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); + fprintf(stderr, "Invalid value of the gas parameter`%s'\n", str); res = RES_BAD_ARG; goto error; } @@ -180,6 +188,97 @@ error: } static res_T +parse_aerosol_parameters(const char* str, void* ptr) +{ + enum { MESH, RADPROP, PHASEFN, PHASEIDS } iparam; + struct rnatm_aerosol_args* aerosol = NULL; + 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 aerosol 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); + + if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "radprop")) iparam = RADPROP; + else if(!strcmp(key, "phasefn")) iparam = PHASEFN; + else if(!strcmp(key, "phaseids")) iparam = PHASEIDS; + else { + fprintf(stderr, "Invalid aerosol parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for aerosol parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + err = wordexp(val, &wexp, 0/*flags*/); + if(err) { + fprintf(stderr, + "Unable to expand the value of the aerosol parameter `%s'\n", str); + res = RES_BAD_ARG; + goto error; + } + wexp_is_allocated = 1; + if(wexp.we_wordc != 1) { + fprintf(stderr, "Invalid value of the aerosol parameter `%s'\n", str); + res = RES_BAD_ARG; + goto error; + } + + ASSERT(args->rnatm.naerosols); + aerosol = args->rnatm.aerosols + (args->rnatm.naerosols - 1); + + switch(iparam) { + case MESH: + aerosol->smsh_filename = strdup(val); + if(!aerosol->smsh_filename) res = RES_MEM_ERR; + break; + case RADPROP: + aerosol->sars_filename = strdup(val); + if(!aerosol->sars_filename) res = RES_MEM_ERR; + break; + case PHASEFN: + aerosol->phase_fn_lst_filename = strdup(val); + if(!aerosol->phase_fn_lst_filename) res = RES_MEM_ERR; + break; + case PHASEIDS: + aerosol->phase_fn_ids_filename = strdup(val); + if(!aerosol->phase_fn_ids_filename) res = RES_MEM_ERR; + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the aerosol parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + if(wexp_is_allocated) wordfree(&wexp); + return res; +error: + goto exit; +} + +static res_T parse_spectral_range(struct args* args, char* str) { size_t len = 0; @@ -204,25 +303,42 @@ error: static void args_release(struct args* args) { + size_t i; 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); + + FOR_EACH(i, 0, args->rnatm.naerosols) { + struct rnatm_aerosol_args* aerosol = args->rnatm.aerosols + i; + if(aerosol->smsh_filename) free(aerosol->smsh_filename); + if(aerosol->sars_filename) free(aerosol->sars_filename); + if(aerosol->phase_fn_ids_filename) free(aerosol->phase_fn_ids_filename); + if(aerosol->phase_fn_lst_filename) free(aerosol->phase_fn_lst_filename); + } + sa_release(args->rnatm.aerosols); *args = ARGS_DEFAULT; } static res_T args_init(struct args* args, int argc, char** argv) { + size_t i = 0; res_T res = RES_OK; int opt; ASSERT(args && argc && argv); *args = ARGS_DEFAULT; - while((opt = getopt(argc, argv, "d:g:hNs:T:t:V:v")) != -1) { + while((opt = getopt(argc, argv, "a:d:g:hNs:T:t:V:v")) != -1) { switch(opt) { + case 'a': + sa_add(args->rnatm.aerosols, 1); + args->rnatm.aerosols[args->rnatm.naerosols] = RNATM_AEROSOL_ARGS_NULL; + args->rnatm.naerosols += 1; + res = cstr_parse_list(optarg, ':', parse_aerosol_parameters, args); + break; case 'd': args->vtk_filename = optarg; break; case 'g': res = cstr_parse_list(optarg, ':', parse_gas_parameters, args); @@ -269,6 +385,19 @@ args_init(struct args* args, int argc, char** argv) goto error; } + FOR_EACH(i, 0, args->rnatm.naerosols) { + struct rnatm_aerosol_args* aerosol = args->rnatm.aerosols + i; + if(!aerosol->smsh_filename + || !aerosol->sars_filename + || !aerosol->phase_fn_ids_filename + || !aerosol->phase_fn_lst_filename) { + fprintf(stderr, "Incomplete %lu^th aerosol definition -- option `-a'\n", + (unsigned long)i); + res = RES_BAD_ARG; + goto error; + } + } + exit: return res; error: