rnatm

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

commit 0422bc026e0c7df925984fc55daed40b85d6ab31
parent 9cead4c9c2977ce50c3763f108055ab7860adbf0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 21 Sep 2022 15:36:40 +0200

Add user defined aerosol name support

Diffstat:
Msrc/rnatm.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/rnatm.h | 3++-
Msrc/rnatm_c.h | 1+
Msrc/rnatm_mesh.c | 10++++++----
Msrc/rnatm_properties.c | 10+++-------
Msrc/test_rnatm.c | 52+++++++++++++++++++++++-----------------------------
6 files changed, 107 insertions(+), 43 deletions(-)

diff --git a/src/rnatm.c b/src/rnatm.c @@ -106,12 +106,57 @@ check_rnatm_create_args(const struct rnatm_create_args* args) } static res_T +setup_aerosol_name + (struct rnatm* atm, + const struct rnatm_create_args* args, + const size_t iaerosol) +{ + struct aerosol* aerosol = NULL; + res_T res = RES_OK; + ASSERT(atm && args); + ASSERT(iaerosol < args->naerosols); + ASSERT(args->naerosols == darray_aerosol_size_get(&atm->aerosols)); + + aerosol = darray_aerosol_data_get(&atm->aerosols)+iaerosol; + + /* Use user-defined name */ + if(args->aerosols[iaerosol].name) { + res = str_set(&aerosol->name, args->aerosols[iaerosol].name); + if(res != RES_OK) { + log_err(atm, "could not set the name of the aerosol %lu to `%s' -- %s\n", + (unsigned long)iaerosol, + args->aerosols[iaerosol].name, + res_to_cstr(res)); + goto error; + } + + /* Use default name */ + } else { + res = str_printf(&aerosol->name, "aerosol%lu", (unsigned long)iaerosol); + if(res != RES_OK) { + log_err(atm, + "could not set the name of the aerosol %lu to `aerosol%lu' -- %s\n", + (unsigned long)iaerosol, + (unsigned long)iaerosol, + res_to_cstr(res)); + goto error; + } + } + +exit: + return res; +error: + goto exit; +} + +static res_T create_rnatm (const struct rnatm_create_args* args, struct rnatm** out_atm) { struct rnatm* atm = NULL; struct mem_allocator* allocator = NULL; + size_t i = 0; int nthreads_max = 0; res_T res = RES_OK; @@ -174,6 +219,11 @@ create_rnatm goto error; } + FOR_EACH(i, 0, args->naerosols) { + res = setup_aerosol_name(atm, args, i); + if(res != RES_OK) goto error; + } + res = mem_init_regular_allocator(&atm->svx_allocator); if(res != RES_OK) { log_err(atm, @@ -422,6 +472,7 @@ aerosol_init(struct mem_allocator* allocator, struct aerosol* aerosol) (void)allocator; ASSERT(aerosol); darray_phase_fn_init(allocator, &aerosol->phase_fn_lst); + str_init(allocator, &aerosol->name); aerosol->volume = NULL; aerosol->phase_fn_ids = NULL; aerosol->sars = NULL; @@ -435,6 +486,7 @@ aerosol_release(struct aerosol* aerosol) { ASSERT(aerosol); darray_phase_fn_release(&aerosol->phase_fn_lst); + str_release(&aerosol->name); if(aerosol->volume) SUVM(volume_ref_put(aerosol->volume)); if(aerosol->phase_fn_ids) SBUF(ref_put(aerosol->phase_fn_ids)); if(aerosol->sars) SARS(ref_put(aerosol->sars)); @@ -443,25 +495,37 @@ aerosol_release(struct aerosol* aerosol) res_T aerosol_copy(struct aerosol* dst, const struct aerosol* src) { + res_T res = RES_OK; ASSERT(dst && src); + if(dst->volume) SUVM(volume_ref_put(dst->volume)); if(dst->phase_fn_ids) SBUF(ref_put(dst->phase_fn_ids)); if(dst->sars) SARS(ref_put(dst->sars)); + dst->volume = src->volume; dst->phase_fn_ids = src->phase_fn_ids; dst->sars = src->sars; dst->ntetrahedra = src->ntetrahedra; dst->nvertices = src->nvertices; + if(dst->volume) SUVM(volume_ref_get(dst->volume)); if(dst->phase_fn_ids) SBUF(ref_get(dst->phase_fn_ids)); if(dst->sars) SARS(ref_get(dst->sars)); - return darray_phase_fn_copy(&dst->phase_fn_lst, &src->phase_fn_lst); + + res = darray_phase_fn_copy(&dst->phase_fn_lst, &src->phase_fn_lst); + if(res != RES_OK) return res; + res = str_copy(&dst->name, &src->name); + if(res != RES_OK) return res; + + return RES_OK; } res_T aerosol_copy_and_release(struct aerosol* dst, struct aerosol* src) { + res_T res = RES_OK; ASSERT(dst && src); + if(dst->volume) SUVM(volume_ref_put(dst->volume)); if(dst->phase_fn_ids) SBUF(ref_put(dst->phase_fn_ids)); if(dst->sars) SARS(ref_put(dst->sars)); @@ -473,7 +537,13 @@ aerosol_copy_and_release(struct aerosol* dst, struct aerosol* src) src->volume = NULL; src->phase_fn_ids = NULL; src->sars = NULL; - return darray_phase_fn_copy_and_release(&dst->phase_fn_lst, &src->phase_fn_lst); + + res = darray_phase_fn_copy_and_release(&dst->phase_fn_lst, &src->phase_fn_lst); + if(res != RES_OK) return res; + res = str_copy_and_release(&dst->name, &src->name); + if(res != RES_OK) return res; + + return RES_OK; } res_T diff --git a/src/rnatm.h b/src/rnatm.h @@ -70,12 +70,13 @@ struct rnatm_gas_args { static const struct rnatm_gas_args RNATM_GAS_ARGS_NULL = RNATM_GAS_ARGS_NULL__; struct rnatm_aerosol_args { + char* name; /* NULL <=> use default name */ char* smsh_filename; /* Geometry */ char* sars_filename; /* Radiative properties */ char* phase_fn_ids_filename; /* Per node phase function id */ char* phase_fn_lst_filename; /* List of phase functions */ }; -#define RNATM_AEROSOL_ARGS_NULL__ {NULL, NULL, NULL, NULL} +#define RNATM_AEROSOL_ARGS_NULL__ {NULL, NULL, NULL, NULL, NULL} static const struct rnatm_aerosol_args RNATM_AEROSOL_ARGS_NULL = RNATM_AEROSOL_ARGS_NULL__; diff --git a/src/rnatm_c.h b/src/rnatm_c.h @@ -104,6 +104,7 @@ gas_copy_and_release ******************************************************************************/ struct aerosol { struct darray_phase_fn phase_fn_lst; + struct str name; struct suvm_volume* volume; struct sbuf* phase_fn_ids; struct sars* sars; diff --git a/src/rnatm_mesh.c b/src/rnatm_mesh.c @@ -167,10 +167,11 @@ setup_meshes(struct rnatm* atm, const struct rnatm_create_args* args) double aerosol_low[3]; double aerosol_upp[3]; struct aerosol* aerosol = darray_aerosol_data_get(&atm->aerosols)+i; + const char* aerosol_name = str_cget(&aerosol->name); const char* filename = args->aerosols[i].smsh_filename; /* Load and structure the aerosol mesh */ - log_info(atm, "aerosol mesh: %s\n", filename); + log_info(atm, "%s mesh: %s\n", aerosol_name, filename); res = setup_uvm(atm, args, filename, suvm, smsh, &aerosol->volume, &aerosol->ntetrahedra, &aerosol->nvertices); if(res != RES_OK) goto error; @@ -185,12 +186,13 @@ setup_meshes(struct rnatm* atm, const struct rnatm_create_args* args) || gas_upp[1] < aerosol_upp[1] || gas_upp[2] < aerosol_upp[2]) { log_err(atm, - "The aerosol %lu may not be included in the gas " + "The %s may not be included in the gas " "(gas AABB: {%g, %g, %g} - {%g, %g, %g}; " - "aerosol AABB: {%g, %g, %g} - {%g, %g, %g})\n", - (unsigned long)i, + "%s AABB: {%g, %g, %g} - {%g, %g, %g})\n", + aerosol_name, SPLIT3(gas_low), SPLIT3(gas_upp), + aerosol_name, SPLIT3(aerosol_low), SPLIT3(aerosol_upp)); res = RES_BAD_ARG; diff --git a/src/rnatm_properties.c b/src/rnatm_properties.c @@ -356,7 +356,6 @@ setup_aerosol_properties const struct rnatm_aerosol_args* aerosol_args) { char buf[128]; - size_t iaerosol; struct time t0, t1; struct sars_create_args sars_args = SARS_CREATE_ARGS_DEFAULT; struct sbuf_create_args sbuf_args = SBUF_CREATE_ARGS_DEFAULT; @@ -365,11 +364,8 @@ setup_aerosol_properties res_T res = RES_OK; ASSERT(atm && aerosol_args); - /* Recover the index of the current aerosol */ - iaerosol = (size_t)(aerosol - darray_aerosol_cdata_get(&atm->aerosols)); - /* Start time recording */ - log_info(atm, "load aerosol%lu properties\n", (unsigned long)iaerosol); + log_info(atm, "load %s properties\n", str_cget(&aerosol->name)); time_current(&t0); res = load_phase_fn_list(atm, aerosol, aerosol_args); @@ -406,8 +402,8 @@ setup_aerosol_properties /* Print elapsed time */ time_sub(&t0, time_current(&t1), &t0); time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); - log_info(atm, "aerosol%lu properties loaded in %s\n", - (unsigned long)iaerosol, buf); + log_info(atm, "%s properties loaded in %s\n", + str_cget(&aerosol->name), buf); exit: return res; diff --git a/src/test_rnatm.c b/src/test_rnatm.c @@ -58,6 +58,7 @@ print_help(const char* cmd) " separated from the previous one by a colon (:)\n\n"); printf( " mesh=path aerosol mesh (smsh(5))\n" +" name=string aerosol name\n" " radprop=path radiative properties (sars(5))\n" " phasefn=path list of phase functions (rnsl(5))\n" " phaseids=path phase function id by node (rnpfi(5))\n\n"); @@ -85,6 +86,9 @@ print_help(const char* cmd) printf( " -i file octrees are loaded from file\n"); printf( +" -n atmosphere name. Default is `%s'\n", + ARGS_DEFAULT.rnatm.name); + printf( " -N precompute_normals the tetrahedra normals\n"); printf( " -o file offload octrees to file\n"); @@ -94,18 +98,18 @@ print_help(const char* cmd) ARGS_DEFAULT.rnatm.spectral_range[0], ARGS_DEFAULT.rnatm.spectral_range[1]); printf( +" -t nthreads hint on the number of threads. Default assumes\n" +" as many threads as CPU cores\n"); + printf( " -T threshold optical thickness criteria for octree building.\n" " Default is %g\n", ARGS_DEFAULT.rnatm.optical_thickness); printf( -" -t nthreads hint on the number of threads. Default assumes\n" -" as many threads as CPU cores\n"); +" -v make the program verbose\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" @@ -197,17 +201,14 @@ error: static res_T parse_aerosol_parameters(const char* str, void* ptr) { - enum { MESH, RADPROP, PHASEFN, PHASEIDS } iparam; + enum { MESH, NAME, 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*/) { @@ -221,6 +222,7 @@ parse_aerosol_parameters(const char* str, void* ptr) val = strtok_r(NULL, "", &tk_ctx); if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "name")) iparam = NAME; else if(!strcmp(key, "radprop")) iparam = RADPROP; else if(!strcmp(key, "phasefn")) iparam = PHASEFN; else if(!strcmp(key, "phaseids")) iparam = PHASEIDS; @@ -236,20 +238,6 @@ parse_aerosol_parameters(const char* str, void* ptr) 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); @@ -258,6 +246,10 @@ parse_aerosol_parameters(const char* str, void* ptr) aerosol->smsh_filename = strdup(val); if(!aerosol->smsh_filename) res = RES_MEM_ERR; break; + case NAME: + aerosol->name = strdup(val); + if(!aerosol->name) res = RES_MEM_ERR; + break; case RADPROP: aerosol->sars_filename = strdup(val); if(!aerosol->sars_filename) res = RES_MEM_ERR; @@ -279,7 +271,6 @@ parse_aerosol_parameters(const char* str, void* ptr) } exit: - if(wexp_is_allocated) wordfree(&wexp); return res; error: goto exit; @@ -320,6 +311,7 @@ args_release(struct args* args) FOR_EACH(i, 0, args->rnatm.naerosols) { struct rnatm_aerosol_args* aerosol = args->rnatm.aerosols + i; + if(aerosol->name) free(aerosol->name); 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); @@ -340,7 +332,7 @@ args_init(struct args* args, int argc, char** argv) *args = ARGS_DEFAULT; - while((opt = getopt(argc, argv, "a:cd:g:hi:No:s:T:t:V:v")) != -1) { + while((opt = getopt(argc, argv, "a:cd:g:hi:n:No:s:t:T:vV:")) != -1) { switch(opt) { case 'a': sa_add(args->rnatm.aerosols, 1); @@ -358,6 +350,7 @@ args_init(struct args* args, int argc, char** argv) args_release(args); args->quit = 1; goto exit; + case 'n': args->rnatm.name = optarg; break; case 'N': args->rnatm.precompute_normals = 1; break; case 'o': args->rnatm.load_octrees_from_storage = 0; @@ -370,19 +363,19 @@ args_init(struct args* args, int argc, char** argv) case 's': res = parse_spectral_range(args, optarg); break; - case 'T': - res = cstr_to_double(optarg, &args->rnatm.optical_thickness); - if(res != RES_OK && args->rnatm.optical_thickness<=0) res = RES_BAD_ARG; - break; case 't': res = cstr_to_uint(optarg, &args->rnatm.nthreads); if(res == RES_OK && !args->rnatm.nthreads) res = RES_BAD_ARG; break; + case 'T': + res = cstr_to_double(optarg, &args->rnatm.optical_thickness); + if(res != RES_OK && args->rnatm.optical_thickness<=0) res = RES_BAD_ARG; + break; + case 'v': args->rnatm.verbose = 1; 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) { @@ -416,6 +409,7 @@ args_init(struct args* args, int argc, char** argv) 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