diff options
| author | tlatorre <tlatorre@uchicago.edu> | 2018-10-01 13:32:27 -0500 | 
|---|---|---|
| committer | tlatorre <tlatorre@uchicago.edu> | 2018-10-01 13:32:27 -0500 | 
| commit | 4f194cc0c05e8f086e213a2ec59065590b87b16e (patch) | |
| tree | 9807d95c8e4ed6ecb0cf1446a5000ee8fc935f80 /src/optics.c | |
| parent | 6f2ee27f80b8275e3ea7c4e284689fd16c868288 (diff) | |
| download | sddm-4f194cc0c05e8f086e213a2ec59065590b87b16e.tar.gz sddm-4f194cc0c05e8f086e213a2ec59065590b87b16e.tar.bz2 sddm-4f194cc0c05e8f086e213a2ec59065590b87b16e.zip | |
fix a bug when computing the absorption length in H2O and D2O
Previously I was interpolating the absorption lengths using interp1d() but that
only works when the x array is uniform. Since the wavelengths are not spaced
uniformly, we have to use the GSL interpolation routines.
Diffstat (limited to 'src/optics.c')
| -rw-r--r-- | src/optics.c | 40 | 
1 files changed, 38 insertions, 2 deletions
| diff --git a/src/optics.c b/src/optics.c index b01ce7d..57c9d57 100644 --- a/src/optics.c +++ b/src/optics.c @@ -5,6 +5,12 @@  #include <stdio.h> /* for fprintf() */  #include <gsl/gsl_integration.h>  #include <gsl/gsl_errno.h> /* for gsl_strerror() */ +#include <gsl/gsl_spline.h> + +/* Macro to compute the size of a static C array. + * + * See https://stackoverflow.com/questions/1598773. */ +#define LEN(x) ((sizeof(x)/sizeof(0[x]))/((size_t)(!(sizeof(x) % sizeof(0[x])))))  /* Absorption coefficients for H2O and D2O as a function of wavelength from   * SNOMAN. @@ -149,7 +155,22 @@ double get_weighted_absorption_length_snoman_h2o(void)  double get_absorption_length_snoman_h2o(double wavelength)  {      /* Returns the absorption length in H2O in cm. */ -    return 1.0/interp1d(wavelength, absorption_coefficient_h2o_wavelengths, absorption_coefficient_h2o, sizeof(absorption_coefficient_h2o_wavelengths)/sizeof(absorption_coefficient_h2o_wavelengths[0])); +    static gsl_spline *spline; +    static gsl_interp_accel *acc; + +    if (!spline) { +        spline = gsl_spline_alloc(gsl_interp_linear, LEN(absorption_coefficient_h2o_wavelengths)); +        gsl_spline_init(spline, absorption_coefficient_h2o_wavelengths, absorption_coefficient_h2o, LEN(absorption_coefficient_h2o_wavelengths)); +        acc = gsl_interp_accel_alloc(); +    } + +    if (wavelength < absorption_coefficient_h2o_wavelengths[0]) +        wavelength = absorption_coefficient_h2o_wavelengths[0]; + +    if (wavelength > absorption_coefficient_h2o_wavelengths[LEN(absorption_coefficient_h2o_wavelengths)-1]) +        wavelength = absorption_coefficient_h2o_wavelengths[LEN(absorption_coefficient_h2o_wavelengths)-1]; + +    return 1.0/gsl_spline_eval(spline, wavelength, acc);  }  double get_weighted_absorption_length_snoman_d2o(void) @@ -167,7 +188,22 @@ double get_weighted_absorption_length_snoman_d2o(void)  double get_absorption_length_snoman_d2o(double wavelength)  {      /* Returns the absorption length in D2O in cm. */ -    return 1.0/interp1d(wavelength, absorption_coefficient_d2o_wavelengths, absorption_coefficient_d2o, sizeof(absorption_coefficient_d2o_wavelengths)/sizeof(absorption_coefficient_d2o_wavelengths[0])); +    static gsl_spline *spline; +    static gsl_interp_accel *acc; + +    if (!spline) { +        spline = gsl_spline_alloc(gsl_interp_linear, LEN(absorption_coefficient_d2o_wavelengths)); +        gsl_spline_init(spline, absorption_coefficient_d2o_wavelengths, absorption_coefficient_d2o, LEN(absorption_coefficient_d2o_wavelengths)); +        acc = gsl_interp_accel_alloc(); +    } + +    if (wavelength < absorption_coefficient_d2o_wavelengths[0]) +        wavelength = absorption_coefficient_d2o_wavelengths[0]; + +    if (wavelength > absorption_coefficient_d2o_wavelengths[LEN(absorption_coefficient_d2o_wavelengths)-1]) +        wavelength = absorption_coefficient_d2o_wavelengths[LEN(absorption_coefficient_d2o_wavelengths)-1]; + +    return 1.0/gsl_spline_eval(spline, wavelength, acc);  }  double get_index(double p, double wavelength, double T) | 
