rnatm

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

commit 28c0320033aa55b0ed0558a5450f7d7ea8759acc
parent 0422bc026e0c7df925984fc55daed40b85d6ab31
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 21 Sep 2022 17:43:12 +0200

Add the rnatm_fetch_cell function

Diffstat:
Msrc/rnatm.h | 21+++++++++++++++++++++
Msrc/rnatm_mesh.c | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/rnatm_octree.c | 15+++++++--------
3 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/src/rnatm.h b/src/rnatm.h @@ -22,6 +22,7 @@ #define RNATM_H #include <star/s3d.h> +#include <star/suvm.h> #include <rsys/rsys.h> @@ -43,9 +44,13 @@ #define RNATM(Func) rnatm_ ## Func #endif +/* Gas identifier */ +#define RNATM_GAS ((size_t)-1) + /* Forward declaration of external data types */ struct logger; struct mem_allocator; +struct suvm_primitive; struct svx_voxel; enum rnatm_radcoef { @@ -80,6 +85,13 @@ struct rnatm_aerosol_args { static const struct rnatm_aerosol_args RNATM_AEROSOL_ARGS_NULL = RNATM_AEROSOL_ARGS_NULL__; +struct rnatm_cell { + struct suvm_primitive prim; /* Volumetric primitive */ + /* Component to which the cell belongs. This is either an aerosol index or + * the RNATM_GAS constant */ + size_t component; +}; + struct rnatm_create_args { struct rnatm_gas_args gas; struct rnatm_aerosol_args* aerosols; @@ -168,6 +180,15 @@ rnatm_get_k_svx_voxel const enum rnatm_radcoef radcoef, const enum rnatm_svx_op op); +RNATM_API res_T +rnatm_fetch_cell + (const struct rnatm* atm, + const double pos[3], + /* Component. This is either an aerosol index or the RNATM_GAS constant */ + const size_t cpnt, + struct rnatm_cell* cell, + double barycentric_coords[4]); /* `pos' relative to the returned `cell' */ + /* Returns the number of spectral items. One acceleration structure is built * per spectral item from the gas and aerosols meshes */ RNATM_API size_t diff --git a/src/rnatm_mesh.c b/src/rnatm_mesh.c @@ -124,6 +124,57 @@ error: } /******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +rnatm_fetch_cell + (const struct rnatm* atm, + const double pos[3], + const size_t cpnt, + struct rnatm_cell* cell, + double barycentric_coords[4]) +{ + res_T res = RES_OK; + + if(!atm || !pos || !cell || !barycentric_coords) { + res = RES_BAD_ARG; + goto error; + } + + cell->component = cpnt; + + /* Gas */ + if(cpnt == RNATM_GAS) { + res = suvm_volume_at(atm->gas.volume, pos, &cell->prim, barycentric_coords); + if(res != RES_OK) { + log_err(atm, "Error retrieving gas cell at %g, %g, %g\n", + SPLIT3(pos)); + goto error; + } + + /* Aerosol */ + } else if(cpnt < rnatm_get_aerosols_count(atm)) { + const struct aerosol* aerosol = darray_aerosol_cdata_get(&atm->aerosols) + cpnt; + res = suvm_volume_at(aerosol->volume, pos, &cell->prim, barycentric_coords); + if(res != RES_OK) { + log_err(atm, "Error retrieving %s cell at %g, %g, %g\n", + str_cget(&aerosol->name), SPLIT3(pos)); + goto error; + } + + /* Invalid component */ + } else { + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + goto exit; +} + +/******************************************************************************* * Local functions ******************************************************************************/ res_T diff --git a/src/rnatm_octree.c b/src/rnatm_octree.c @@ -44,7 +44,6 @@ #include <math.h> /* lround */ #include <omp.h> -#define GAS SIZE_MAX #define VOXELIZE_MSG "voxelize atmosphere: %3d%%\r" /* Structure used to synchronise the voxelization and the build threads */ @@ -586,9 +585,9 @@ setup_tetra_radcoefs struct radcoefs* radcoefs) { ASSERT(atm && tetra && radcoefs); - ASSERT(cpnt == GAS || cpnt < darray_aerosol_size_get(&atm->aerosols)); + ASSERT(cpnt == RNATM_GAS || cpnt < darray_aerosol_size_get(&atm->aerosols)); - if(cpnt == GAS) { + if(cpnt == RNATM_GAS) { setup_tetra_radcoefs_gas(atm, tetra, iband, iquad_pt, radcoefs); } else { const struct aerosol* aerosol = darray_aerosol_cdata_get(&atm->aerosols)+cpnt; @@ -637,10 +636,10 @@ voxelize_tetra const struct suvm_volume* volume = NULL; size_t i; ASSERT(atm && check_voxelize_args(args) == RES_OK); - ASSERT(cpnt == GAS || cpnt < darray_aerosol_size_get(&atm->aerosols)); + ASSERT(cpnt == RNATM_GAS || cpnt < darray_aerosol_size_get(&atm->aerosols)); /* Fetch the component volumetric mesh */ - if(cpnt == GAS) { + if(cpnt == RNATM_GAS) { volume = atm->gas.volume; } else { volume = darray_aerosol_cdata_get(&atm->aerosols)[cpnt].volume; @@ -739,10 +738,10 @@ voxelize_partition_component struct suvm_volume* volume = NULL; res_T res = RES_OK; ASSERT(atm && args); - ASSERT(cpnt == GAS || cpnt < darray_aerosol_size_get(&atm->aerosols)); + ASSERT(cpnt == RNATM_GAS || cpnt < darray_aerosol_size_get(&atm->aerosols)); /* Get the volumetric mesh of the component */ - if(cpnt == GAS) { + if(cpnt == RNATM_GAS) { volume = atm->gas.volume; } else { volume = darray_aerosol_cdata_get(&atm->aerosols)[cpnt].volume; @@ -777,7 +776,7 @@ voxelize_partition(struct rnatm* atm, const struct voxelize_args* args) partition_clear_voxels(args->part); /* Voxelize the gas */ - res = voxelize_partition_component(atm, args, GAS); + res = voxelize_partition_component(atm, args, RNATM_GAS); if(res != RES_OK) goto error; part_is_empty = part_is_empty && !darray_size_t_size_get(args->tetra_ids);