rnatm

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

commit 9cead4c9c2977ce50c3763f108055ab7860adbf0
parent c11cb0ffc9b88987f2abdce15378e71768b13c36
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 21 Sep 2022 12:12:44 +0200

Implement the rnatm_validate function

Diffstat:
Msrc/rnatm.c | 16++++++++++++++++
Msrc/rnatm_c.h | 4++++
Msrc/rnatm_properties.c | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_rnatm.c | 13+++++++++++--
4 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/src/rnatm.c b/src/rnatm.c @@ -254,6 +254,22 @@ rnatm_ref_put(struct rnatm* atm) return RES_OK; } +res_T +rnatm_validate(const struct rnatm* atm) +{ + res_T res = RES_OK; + + if(!atm) { res = RES_BAD_ARG; goto error; } + + res = check_properties(atm); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + double rnatm_get_k_svx_voxel (const struct rnatm* atm, diff --git a/src/rnatm_c.h b/src/rnatm_c.h @@ -218,6 +218,10 @@ setup_properties const struct rnatm_create_args* args); extern LOCAL_SYM res_T +check_properties + (const struct rnatm* atm); + +extern LOCAL_SYM res_T setup_octrees (struct rnatm* atm, const struct rnatm_create_args* args); diff --git a/src/rnatm_properties.c b/src/rnatm_properties.c @@ -78,6 +78,34 @@ check_gas_temperatures_desc return RES_OK; } +static res_T +check_gas_temperatures(const struct rnatm* atm) +{ + struct sbuf_desc sbuf_desc = SBUF_DESC_NULL; + size_t i; + res_T res = RES_OK; + ASSERT(atm); + + /* The layout of sbuf_desc has already been checked when creating rnatm */ + res = sbuf_get_desc(atm->gas.temperatures, &sbuf_desc); + if(res != RES_OK) goto error; + + FOR_EACH(i, 0, sbuf_desc.size) { + const float temperature = *((const float*)sbuf_desc_at(&sbuf_desc, i)); + if(temperature != temperature /* NaN */ || temperature < 0) { + log_err(atm, "%s: node %lu: invalid gas temperature `%g'\n", + str_cget(&atm->name), i, temperature); + res = RES_BAD_ARG; + goto error; + } + } + +exit: + return res; +error: + goto exit; +} + static INLINE res_T check_gas_ck_desc (const struct rnatm* atm, @@ -119,6 +147,39 @@ check_aerosol_phase_fn_ids_desc return RES_OK; } +static res_T +check_aerosol_phase_fn_ids + (const struct rnatm* atm, + const struct aerosol* aerosol) +{ + struct sbuf_desc sbuf_desc = SBUF_DESC_NULL; + size_t i; + res_T res = RES_OK; + ASSERT(atm && aerosol); + + /* The layout of sbuf_desc has already been checked when creating rnatm */ + res = sbuf_get_desc(aerosol->phase_fn_ids, &sbuf_desc); + if(res != RES_OK) goto error; + + FOR_EACH(i, 0, sbuf_desc.size) { + const uint32_t id = *((uint32_t*)sbuf_desc_at(&sbuf_desc, i)); + + if(id >= darray_phase_fn_size_get(&aerosol->phase_fn_lst)) { + log_err(atm, + "%s: node %lu: invalid phase function id `%lu'. It must be in [0, %lu[\n", + str_cget(&atm->name), (unsigned long)i, (unsigned long)id, + (unsigned long)darray_phase_fn_size_get(&aerosol->phase_fn_lst)); + res = RES_BAD_ARG; + goto error; + } + } + +exit: + return res; +error: + goto exit; +} + static INLINE res_T check_aerosol_sars_desc (const struct rnatm* atm, @@ -384,3 +445,25 @@ error: } goto exit; } + +res_T +check_properties(const struct rnatm* atm) +{ + size_t i; + res_T res = RES_OK; + ASSERT(atm); + + res = check_gas_temperatures(atm); + if(res != RES_OK) goto error; + + FOR_EACH(i, 0, darray_aerosol_size_get(&atm->aerosols)) { + const struct aerosol* aerosol = darray_aerosol_cdata_get(&atm->aerosols)+i; + res = check_aerosol_phase_fn_ids(atm, aerosol); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/test_rnatm.c b/src/test_rnatm.c @@ -34,9 +34,10 @@ struct args { struct rnatm_create_args rnatm; const char* vtk_filename; + int check; int quit; }; -#define ARGS_DEFAULT__ { RNATM_CREATE_ARGS_DEFAULT__, NULL, 0 } +#define ARGS_DEFAULT__ { RNATM_CREATE_ARGS_DEFAULT__, NULL, 0, 0 } static const struct args ARGS_DEFAULT = ARGS_DEFAULT__; /******************************************************************************* @@ -61,6 +62,8 @@ print_help(const char* cmd) " phasefn=path list of phase functions (rnsl(5))\n" " phaseids=path phase function id by node (rnpfi(5))\n\n"); printf( +" -c check data\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" @@ -337,7 +340,7 @@ args_init(struct args* args, int argc, char** argv) *args = ARGS_DEFAULT; - while((opt = getopt(argc, argv, "a:d:g:hi:No:s:T:t:V:v")) != -1) { + while((opt = getopt(argc, argv, "a:cd:g:hi:No:s:T:t:V:v")) != -1) { switch(opt) { case 'a': sa_add(args->rnatm.aerosols, 1); @@ -345,6 +348,7 @@ args_init(struct args* args, int argc, char** argv) args->rnatm.naerosols += 1; res = cstr_parse_list(optarg, ':', parse_aerosol_parameters, args); break; + case 'c': args->check = 1; break; case 'd': args->vtk_filename = optarg; break; case 'g': res = cstr_parse_list(optarg, ':', parse_gas_parameters, args); @@ -479,6 +483,11 @@ main(int argc, char** argv) res = rnatm_create(&args.rnatm, &atm); if(res != RES_OK) goto error; + if(args.check) { + res = rnatm_validate(atm); + if(res != RES_OK) goto error; + } + if(args.vtk_filename) { res = write_vtk_octrees(atm, args.vtk_filename); if(res != RES_OK) goto error;