rnatm

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

commit 1ffd05e761af377f02d7b42a1ce2bbc85142827f
parent 6cc415ceb369c624c5b6de17520d947ff2ff7010
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 18 Nov 2022 17:28:49 +0100

Add the rnatm_cell_get_gas_temperature function

Diffstat:
Msrc/rnatm.h | 6++++++
Msrc/rnatm_properties.c | 105++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
2 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/src/rnatm.h b/src/rnatm.h @@ -340,6 +340,12 @@ rnatm_cell_create_phase_fn struct ssf_phase** phase_fn); RNATM_API res_T +rnatm_cell_get_gas_temperature + (const struct rnatm* atm, + const struct rnatm_cell_pos* cell, /* Must belongs to the gas */ + double* temperature); + +RNATM_API res_T rnatm_trace_ray (struct rnatm* rnatm, const struct rnatm_trace_ray_args* args, diff --git a/src/rnatm_properties.c b/src/rnatm_properties.c @@ -107,36 +107,50 @@ check_rnatm_sample_component_args return RES_OK; } +static INLINE res_T +check_cell(const struct rnatm_cell_pos* cell) +{ + double sum_bcoords; + + if(!cell) return RES_BAD_ARG; + + /* Invalid geometric primitive */ + if(SUVM_PRIMITIVE_NONE(&cell->prim) + || cell->prim.nvertices != 4) /* Expect a tetraheron */ + return RES_BAD_ARG; + + /* Invalid barycentric coordinates */ + sum_bcoords = + cell->barycentric_coords[0] + + cell->barycentric_coords[1] + + cell->barycentric_coords[2] + + cell->barycentric_coords[3]; + if(!eq_eps(sum_bcoords, 1, 1.e-6)) + return RES_BAD_ARG; + + return RES_OK; +} + static res_T check_rnatm_cell_get_radcoef_args (const struct rnatm* atm, const struct rnatm_cell_get_radcoef_args* args) { - double sum_bcoords; size_t i, n; + res_T res = RES_OK; ASSERT(atm && darray_band_size_get(&atm->bands)); if(!args) return RES_BAD_ARG; - /* Invalid geometric primitive */ - if(SUVM_PRIMITIVE_NONE(&args->cell.prim) - || args->cell.prim.nvertices != 4) /* Expect a tetraheron */ - return RES_BAD_ARG; + /* Invalid cell */ + res = check_cell(&args->cell); + if(res != RES_OK) return res; /* Invalid component */ if(args->cell.component != RNATM_GAS && args->cell.component >= darray_aerosol_size_get(&atm->aerosols)) return RES_BAD_ARG; - /* Invalid barycentric coordinates */ - sum_bcoords = - args->cell.barycentric_coords[0] - + args->cell.barycentric_coords[1] - + args->cell.barycentric_coords[2] - + args->cell.barycentric_coords[3]; - if(!eq_eps(sum_bcoords, 1, 1.e-6)) - return RES_BAD_ARG; - /* Invalid band index */ n = darray_band_size_get(&atm->bands) - 1; if(args->iband < darray_band_cdata_get(&atm->bands)[0].index @@ -165,32 +179,20 @@ check_rnatm_cell_create_phase_fn_args (struct rnatm* atm, const struct rnatm_cell_create_phase_fn_args* args) { - double sum_bcoords; + res_T res = RES_OK; ASSERT(atm); if(!args) return RES_BAD_ARG; - /* Invalid geometric primitive */ - if(SUVM_PRIMITIVE_NONE(&args->cell.prim) - || args->cell.prim.nvertices != 4) /* Expect a tetraheron */ - return RES_BAD_ARG; - - /* Invalid component */ + /* Invalid cell */ + res = check_cell(&args->cell); + if(res != RES_OK) return res; /* Invalid component */ if(args->cell.component != RNATM_GAS && args->cell.component >= darray_aerosol_size_get(&atm->aerosols)) return RES_BAD_ARG; - /* Invalid barycentric coordinates */ - sum_bcoords = - args->cell.barycentric_coords[0] - + args->cell.barycentric_coords[1] - + args->cell.barycentric_coords[2] - + args->cell.barycentric_coords[3]; - if(!eq_eps(sum_bcoords, 1, 1.e-6)) - return RES_BAD_ARG; - /* Invalid wavelength */ if(args->wavelength < 0) return RES_BAD_ARG; @@ -1189,6 +1191,49 @@ error: goto exit; } +res_T +rnatm_cell_get_gas_temperature + (const struct rnatm* atm, + const struct rnatm_cell_pos* cell, + double* temperature) +{ + struct sbuf_desc sbuf_desc; + float vtx_T[4]; + res_T res = RES_OK; + + if(!atm || !temperature) return RES_OK; + res = check_cell(cell); + if(res != RES_OK) goto error; + + /* Invalid cell regarding gas */ + SBUF(get_desc(atm->gas.temperatures, &sbuf_desc)); + if(cell->prim.indices[0] >= sbuf_desc.size + || cell->prim.indices[1] >= sbuf_desc.size + || cell->prim.indices[2] >= sbuf_desc.size + || cell->prim.indices[3] >= sbuf_desc.size) + return RES_BAD_ARG; + + /* Get the temperature per vertex */ + vtx_T[0] = *((float*)sbuf_desc_at(&sbuf_desc, cell->prim.indices[0])); + vtx_T[1] = *((float*)sbuf_desc_at(&sbuf_desc, cell->prim.indices[1])); + vtx_T[2] = *((float*)sbuf_desc_at(&sbuf_desc, cell->prim.indices[2])); + vtx_T[3] = *((float*)sbuf_desc_at(&sbuf_desc, cell->prim.indices[3])); + + + /* Calculate the temperature at the input position by linearly interpolating + * the temperatures defined by tetrahedron vertex */ + *temperature = + vtx_T[0] * cell->barycentric_coords[0] + + vtx_T[1] * cell->barycentric_coords[1] + + vtx_T[2] * cell->barycentric_coords[2] + + vtx_T[3] * cell->barycentric_coords[3]; + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/