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