htmie

Optical properties of water droplets
git clone git://git.meso-star.fr/htmie.git
Log | Files | Refs | README | LICENSE

commit dc8518ff8d2f4ae34af2ab71cff43fe0293c2813
parent 7335d853d797ee252a3c432aceadc95a880dd8a7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  3 Jul 2018 12:20:28 +0200

Implement accessors toward the loaded data

Diffstat:
Msrc/htmie.c | 135++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/htmie.h | 44++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 171 insertions(+), 8 deletions(-)

diff --git a/src/htmie.c b/src/htmie.c @@ -15,6 +15,7 @@ #include "htmie.h" +#include <rsys/algorithm.h> #include <rsys/dynamic_array_double.h> #include <rsys/logger.h> #include <rsys/mem_allocator.h> @@ -426,14 +427,13 @@ error: static INLINE res_T massic_to_per_particle_xsections (const struct htmie* htmie, - const char* var_name, struct darray_double* xsections) { double radius_barre; double avg_volume; size_t i; res_T res = RES_OK; - ASSERT(htmie && var_name && xsections); + ASSERT(htmie && xsections); /* Convert data from massic cross sections to per particle cross sections */ radius_barre = exp(htmie->rmod); /* in micrometer */ @@ -448,6 +448,52 @@ massic_to_per_particle_xsections return res; } +static FINLINE double +fetch_data + (const struct htmie* htmie, + const double wavelength, + const enum htmie_filter_type type, + const double* data) /* Data to interpolate */ +{ + size_t nwlens; + const double* wlens; + const double* wlen_upp; + double val; + ASSERT(htmie && (unsigned)type < HTMIE_FILTER_TYPES_COUNT__ && data); + + wlens = htmie_get_wavelengths(htmie); + nwlens = htmie_get_wavelengths_count(htmie); + ASSERT(nwlens); + + wlen_upp = search_lower_bound + (&wavelength, wlens, nwlens, sizeof(double), cmp_dbl); + + if(!wlen_upp) { /* Clamp to upper */ + val = data[nwlens-1]; + } else if(wlen_upp == wlens) { /* Clamp to lower */ + val = data[0]; + } else { + const size_t i = (size_t)(wlen_upp - wlens); + const double a = data[i-1]; + const double b = data[i-0]; + const double u = (wavelength - wlens[i-1]) / (wlens[i] - wlens[i-1]); + ASSERT(i < nwlens && (wlens[i] >= wavelength || wlens[i-1] <= wavelength)); + ASSERT(eq_eps(u, 1, 1.e-6)); + + switch(type) { + case HTMIE_FILTER_NEAREST: + val = u < 0.5 ? a : b; + break; + case HTMIE_FILTER_LINEAR: + CLAMP(u, 0, 1); /* Handle numerical inaccuracy */ + val = u*b + (1-u)*a; + break; + default: FATAL("Unreachable code.\n"); break; + } + } + return val; +} + static void release_htmie(ref_T* ref) { @@ -555,15 +601,19 @@ htmie_load(struct htmie* htmie, const char* path) #define CALL(Func) { res = Func; if(res != RES_OK) goto error; } (void)0 CALL(load_wavelengths(htmie, nc, range)); - CALL(load_droplet_distribution_variable(htmie, nc, "rmod", range, &htmie->rmod)); - CALL(load_droplet_distribution_variable(htmie, nc, "smod", range, &htmie->smod)); - CALL(load_distrib_x_lambda_array(htmie, nc, "macs", range, &htmie->xsections_absorption)); - CALL(load_distrib_x_lambda_array(htmie, nc, "mscs", range, &htmie->xsections_scattering)); + CALL(load_droplet_distribution_variable + (htmie, nc, "rmod", range, &htmie->rmod)); + CALL(load_droplet_distribution_variable + (htmie, nc, "smod", range, &htmie->smod)); + CALL(load_distrib_x_lambda_array + (htmie, nc, "macs", range, &htmie->xsections_absorption)); + CALL(load_distrib_x_lambda_array + (htmie, nc, "mscs", range, &htmie->xsections_scattering)); CALL(load_distrib_x_lambda_array(htmie, nc, "g", range, &htmie->g)); /* The rmod and smod parameter must be loaded */ - CALL(massic_to_per_particle_xsections(htmie, "macs", &htmie->xsections_absorption)); - CALL(massic_to_per_particle_xsections(htmie, "mscs", &htmie->xsections_scattering)); + CALL(massic_to_per_particle_xsections(htmie, &htmie->xsections_absorption)); + CALL(massic_to_per_particle_xsections(htmie, &htmie->xsections_scattering)); #undef CALL exit: @@ -572,3 +622,72 @@ exit: error: goto exit; } + +const double* +htmie_get_wavelengths(const struct htmie* htmie) +{ + ASSERT(htmie); + return darray_double_cdata_get(&htmie->wavelengths); +} + +const double* +htmie_get_xsections_absorption(const struct htmie* htmie) +{ + ASSERT(htmie); + return darray_double_cdata_get(&htmie->xsections_absorption); +} + +const double* +htmie_get_xsections_scattering(const struct htmie* htmie) +{ + ASSERT(htmie); + return darray_double_cdata_get(&htmie->xsections_scattering); +} + +const double* +htmie_get_asymmetric_parameter(const struct htmie* htmie) +{ + ASSERT(htmie); + return darray_double_cdata_get(&htmie->g); +} + +size_t +htmie_get_wavelengths_count(const struct htmie* htmie) +{ + ASSERT(htmie); + return darray_double_size_get(&htmie->wavelengths); +} + +double +htmie_fetch_xsection_absorption + (const struct htmie* htmie, + const double wavelength, + const enum htmie_filter_type type) +{ + ASSERT(htmie); + return fetch_data + (htmie, wavelength, type, htmie_get_xsections_absorption(htmie)); +} + +double +htmie_fetch_xsection_scattering + (const struct htmie* htmie, + const double wavelength, + const enum htmie_filter_type type) +{ + ASSERT(htmie); + return fetch_data + (htmie, wavelength, type, htmie_get_xsections_scattering(htmie)); +} + +double +htmie_fetch_asymmetric_parameter + (const struct htmie* htmie, + const double wavelength, + const enum htmie_filter_type type) +{ + ASSERT(htmie); + return fetch_data + (htmie, wavelength, type, htmie_get_asymmetric_parameter(htmie)); +} + diff --git a/src/htmie.h b/src/htmie.h @@ -40,6 +40,12 @@ struct logger; struct mem_allocator; +enum htmie_filter_type { + HTMIE_FILTER_LINEAR, + HTMIE_FILTER_NEAREST, + HTMIE_FILTER_TYPES_COUNT__ +}; + /* Forward declaration of opaque data types */ struct htmie; @@ -68,6 +74,44 @@ htmie_load (struct htmie *htmie, const char* path); +HTMIE_API const double* +htmie_get_wavelengths + (const struct htmie* htmie); + +HTMIE_API const double* +htmie_get_xsections_absorption + (const struct htmie* htmie); + +HTMIE_API const double* +htmie_get_xsections_scattering + (const struct htmie* htmie); + +HTMIE_API const double* +htmie_get_asymmetric_parameter + (const struct htmie* htmie); + +HTMIE_API size_t +htmie_get_wavelengths_count + (const struct htmie* htmie); + +HTMIE_API double +htmie_fetch_xsection_absorption + (const struct htmie* htmie, + const double wavelength, + const enum htmie_filter_type type); + +HTMIE_API double +htmie_fetch_xsection_scattering + (const struct htmie* htmie, + const double wavelength, + const enum htmie_filter_type type); + +HTMIE_API double +htmie_fetch_asymmetric_parameter + (const struct htmie* htmie, + const double wavelength, + const enum htmie_filter_type type); + END_DECLS #endif /* HTMIE_H */