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:
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