atrri

Refractive indices varying with wavelength
git clone git://git.meso-star.fr/atrri.git
Log | Files | Refs | README | LICENSE

commit e3bc6e2ef2f366f044aa0882f3c4ce78a9b1a043
parent 16e27c21f6711060abed6661e21fd404522d4985
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 13 Jan 2021 12:53:44 +0100

Implement the atrri_fetch_refractive_index function

Diffstat:
Msrc/atrri.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/atrri.h | 7++++++-
2 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/src/atrri.c b/src/atrri.c @@ -19,6 +19,7 @@ #include "atrri_c.h" #include "atrri_log.h" +#include <rsys/algorithm.h> #include <rsys/cstr.h> #include <rsys/text_reader.h> @@ -28,6 +29,21 @@ /******************************************************************************* * Local functions ******************************************************************************/ +static INLINE int +cmp_refractive_index(const void* key, const void* entry) +{ + const double wavelength = *((const double*)key); + const struct atrri_refractive_index* id = entry; + + if(wavelength < id->wavelength) { + return -1; + } else if(wavelength > id->wavelength) { + return 1; + } else { + return 0; + } +} + static INLINE void reset_atrri(struct atrri* atrri) { @@ -312,3 +328,66 @@ atrri_get_desc(const struct atrri* atrri, struct atrri_desc* desc) desc->nindices = darray_refractive_id_size_get(&atrri->refract_ids); return RES_OK; } + +res_T +atrri_fetch_refractive_index + (const struct atrri* atrri, + const double wavelength, + struct atrri_refractive_index* refract_id) +{ + struct atrri_desc desc = ATRRI_DESC_NULL; + struct atrri_refractive_index* found = NULL; + res_T res = RES_OK; + + if(!atrri || wavelength < 0 || !refract_id) { + res = RES_BAD_ARG; + goto error; + } + + ATRRI(get_desc(atrri, &desc)); + + /* Search for the registered refractive index whose corresponding wavelength + * is greater than or equal to the submitted wavelength */ + found = search_lower_bound(&wavelength, desc.indices, desc.nindices, + sizeof(*desc.indices), cmp_refractive_index); + + if(!found) { + /* All refractive indices are defined for wavelengths less than the + * submitted one. Clamp to the last registered refractive index */ + ASSERT(desc.nindices); + *refract_id = desc.indices[desc.nindices-1]; + + } else if(found == desc.indices) { + /* The submitted wavelength is less than the first wavelength for which a + * refractive index is registered. Clamp to the first registered refractive + * index */ + *refract_id = desc.indices[0]; + + } else { + const size_t inext = (size_t)(found - desc.indices); + const size_t iprev = inext - 1; + const struct atrri_refractive_index* next = desc.indices + inext; + const struct atrri_refractive_index* prev = desc.indices + iprev; + ASSERT(next->wavelength >= wavelength); + ASSERT(prev->wavelength < wavelength); + + if(next->wavelength == wavelength) { + /* The submitted wavelength strictly match a registered wavelength */ + *refract_id = *next; + + } else { + /* Linearly interpolate the refractive index */ + const double len = next->wavelength - prev->wavelength; + const double u = CLAMP((wavelength - prev->wavelength) / len, 0, 1); + ASSERT(len > 0); + refract_id->wavelength = wavelength; + refract_id->n = u*(prev->n - next->n) + next->n; + refract_id->kappa = u*(prev->kappa - next->kappa) + next->kappa; + } + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/atrri.h b/src/atrri.h @@ -92,6 +92,12 @@ atrri_load_stream const char* stream_name); /* Can be NULL */ ATRRI_API res_T +atrri_fetch_refractive_index + (const struct atrri* atrri, + const double wavelength, + struct atrri_refractive_index* refract_id); + +ATRRI_API res_T atrri_get_desc (const struct atrri* atrri, struct atrri_desc* desc); @@ -99,4 +105,3 @@ atrri_get_desc END_DECLS #endif /* ATRRI_H */ -