schiff

Estimate the radiative properties of soft particless
git clone git://git.meso-star.com/schiff.git
Log | Files | Refs | README | LICENSE

schiff_optical_properties.c (6440B)


      1 /* Copyright (C) 2015, 2016, 2026 Centre National de la Recherche Scientifique
      2  * Copyright (C) 2026 Clermont Auvergne INP
      3  * Copyright (C) 2026 Institut Mines Télécom Albi-Carmaux
      4  * Copyright (C) 2017, 2019-2021, 2026 |Méso|Star> (contact@meso-star.com)
      5  * Copyright (C) 2026 Université de Lorraine
      6  * Copyright (C) 2026 Université de Toulouse
      7  *
      8  * This program is free software: you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation, either version 3 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     20 
     21 #include "schiff_optical_properties.h"
     22 #include "schiff_streamline.h"
     23 
     24 #include <rsys/algorithm.h>
     25 #include <rsys/cstr.h>
     26 #include <rsys/stretchy_array.h>
     27 
     28 #include <star/sschiff.h>
     29 
     30 /*******************************************************************************
     31  * Helper functions
     32  ******************************************************************************/
     33 static res_T
     34 parse_optical_properties
     35   (struct schiff_optical_properties* out_props,
     36    const char* filename,
     37    const size_t iline,
     38    const char* str)
     39 {
     40   char buf[128];
     41   char* tk;
     42   int i = 0;
     43   double props[4];
     44   res_T res = RES_OK;
     45   ASSERT(filename && str && out_props);
     46 
     47   if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) {
     48     fprintf(stderr,
     49       "%s:%lu: not enough memory: cannot parse the properties `%s'.\n",
     50       filename, (unsigned long)iline, str);
     51     return RES_MEM_ERR;
     52   }
     53 
     54   strncpy(buf, str, sizeof(buf));
     55   for(i=0, tk=strtok(buf, " \t"); tk && i < 4; ++i, tk=strtok(NULL, " \t")) {
     56     res = cstr_to_double(tk, props + i);
     57     if(res != RES_OK) {
     58       fprintf(stderr,
     59         "%s:%lu: cannot read the optical property `%s'.\n",
     60         filename, (unsigned long)iline, tk);
     61       return res;
     62     }
     63   }
     64   if(i < 4) {
     65     fprintf(stderr,
     66       "%s:%lu: not enough optical properties.\n"
     67       "Expect 4 parameters while %d is submitted - `%s'.\n",
     68       filename, (unsigned long)iline, i, str);
     69     return RES_BAD_ARG;
     70   }
     71 
     72   out_props->W  = props[0];
     73   out_props->Ne = props[3];
     74   out_props->Nr = props[1] / out_props->Ne; /* Absolute to relative */
     75   out_props->Kr = props[2] / out_props->Ne; /* Absolute to relative */
     76   if(!schiff_optical_properties_check(out_props)) {
     77     fprintf(stderr, "%s:%lu: invalid optical properties `%s'.\n",
     78       filename, (unsigned long)iline, str);
     79     return RES_BAD_ARG;
     80   }
     81   return RES_OK;
     82 }
     83 
     84 static FINLINE int
     85 cmp_properties(const void* op0, const void* op1)
     86 {
     87   const struct schiff_optical_properties* prop0 = op0;
     88   const struct schiff_optical_properties* prop1 = op1;
     89   return prop0->W < prop1->W ? -1 : (prop0->W > prop1->W ? 1 : 0);
     90 }
     91 
     92 static FINLINE int
     93 cmp_wavelength_to_properties(const void* wavelength, const void* op)
     94 {
     95   const double* W = wavelength;
     96   const struct schiff_optical_properties* prop = op;
     97   return *W < prop->W ? -1 : (*W > prop->W ? 1 : 0);
     98 }
     99 
    100 /*******************************************************************************
    101  * Local function
    102  ******************************************************************************/
    103 res_T
    104 schiff_optical_properties_load
    105   (struct schiff_optical_properties** props, const char* filename)
    106 {
    107   FILE* fp = NULL;
    108   res_T res = RES_OK;
    109   ASSERT(filename && props);
    110 
    111   fp = fopen(filename, "r");
    112   if(!fp) {
    113     fprintf(stderr, "Cannot open the file of optical properties `%s'.\n",
    114       filename);
    115     res = RES_IO_ERR;
    116     goto error;
    117   }
    118 
    119   res = schiff_optical_properties_load_stream(props, fp, filename);
    120   if(res != RES_OK) goto error;
    121 
    122 exit:
    123   if(fp) fclose(fp);
    124   return res;
    125 error:
    126   goto exit;
    127 }
    128 
    129 res_T
    130 schiff_optical_properties_load_stream
    131   (struct schiff_optical_properties** out_props,
    132    FILE* stream,
    133    const char* stream_name)
    134 {
    135   struct schiff_optical_properties* props = NULL;
    136   struct schiff_streamline streamline;
    137   size_t iline;
    138   char* line;
    139   res_T res = RES_OK;
    140   ASSERT(out_props && stream && stream_name);
    141 
    142   schiff_streamline_init(&streamline);
    143 
    144   for(iline=1;
    145     (res = schiff_streamline_read(&streamline, stream, &line)) != RES_EOF;
    146     ++iline) {
    147     struct schiff_optical_properties tmp_props;
    148 
    149     if(strcspn(line, "# \t") == 0) /* Empty line */
    150       continue;
    151 
    152     /* Read optical properties */
    153     line = strtok(line, "#");
    154     res = parse_optical_properties(&tmp_props, stream_name, iline, line);
    155     if(res == RES_OK) { /* *NO* error */
    156       sa_push(props, tmp_props);
    157     }
    158   }
    159 
    160   /* Sort the optical properties in ascending order with respect to the
    161    * wavelength */
    162   qsort(props, sa_size(props),
    163     sizeof(struct schiff_optical_properties), cmp_properties);
    164 
    165   *out_props = props;
    166   schiff_streamline_release(&streamline);
    167   return RES_OK;
    168 }
    169 
    170 void
    171 schiff_optical_properties_fetch
    172   (struct schiff_optical_properties* properties, /* Stetchy array */
    173    const double wavelength,
    174    struct sschiff_material_properties* props)
    175 {
    176   const size_t nproperties = sa_size(properties);
    177   struct schiff_optical_properties* find;
    178   double Ne, Kr, Nr;
    179   ASSERT(properties && props && wavelength > 0.0);
    180 
    181   /* Assume that properties are sorted in ascending order with respect to the
    182    * wavelength. */
    183   find = search_lower_bound(&wavelength, properties, nproperties,
    184     sizeof(struct schiff_optical_properties), cmp_wavelength_to_properties);
    185   ASSERT(!find || find->W >= wavelength);
    186 
    187   if(!find) /* Clamp to upper wavelength */
    188     find = properties + (nproperties - 1);
    189 
    190   if(find == properties || find == (properties + (nproperties - 1))
    191   || eq_eps(find->W, wavelength, 1.e-12)) {
    192     Ne = find[0].Ne;
    193     Kr = find[0].Kr;
    194     Nr = find[0].Nr;
    195   } else { /* Linear interpolation of optical properties */
    196     const double d = find[0].W - find[-1].W;
    197     const double u = (wavelength - find[-1].W) / d;
    198     const double v = 1.0 - u;
    199     Ne = u * find[0].Ne + v * find[-1].Ne;
    200     Kr = u * find[0].Kr + v * find[-1].Kr;
    201     Nr = u * find[0].Nr + v * find[-1].Nr;
    202   }
    203 
    204   props->medium_refractive_index = Ne;
    205   props->relative_imaginary_refractive_index = Kr;
    206   props->relative_real_refractive_index = Nr;
    207 }
    208