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:
| M | src/atrri.c | | | 79 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/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 */
-