sschiff.h (11145B)
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) 2020, 2021, 2023, 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 #ifndef SSCHIFF_H 22 #define SSCHIFF_H 23 24 #include <rsys/rsys.h> 25 26 /* Library symbol management */ 27 #if defined(SSCHIFF_SHARED_BUILD) /* Build shared library */ 28 #define SSCHIFF_API extern EXPORT_SYM 29 #elif defined(SSCHIFF_STATIC) /* Use/build static library */ 30 #define SSCHIFF_API extern LOCAL_SYM 31 #else /* Use shared library */ 32 #define SSCHIFF_API extern IMPORT_SYM 33 #endif 34 35 /* Helper macro that asserts if the invocation of the schiff function `Func' 36 * returns an error. One should use this macro on sschiff function calls for 37 * which no explicit error checking is performed */ 38 #ifndef NDEBUG 39 #define SSCHIFF(Func) ASSERT(sschiff_ ## Func == RES_OK) 40 #else 41 #define SSCHIFF(Func) sschiff_ ## Func 42 #endif 43 44 #define SSCHIFF_NTHREADS_DEFAULT (~0u) 45 46 /* Forward declaration of external types. */ 47 struct mem_allocator; 48 struct logger; 49 struct s3d_device; 50 struct s3d_shape; 51 struct ssp_rng; 52 53 /* Optical properties of a material handled by the Schiff integrator */ 54 struct sschiff_material_properties { 55 double medium_refractive_index; 56 double relative_real_refractive_index; 57 double relative_imaginary_refractive_index; 58 }; 59 60 /* Client side material used by the Schiff integrator */ 61 struct sschiff_material { 62 /* Retrieve the optical properties of the material */ 63 void (*get_property) 64 (void* material, 65 const double wavelength, /* In micron */ 66 struct sschiff_material_properties* properties); 67 void* material; /* Opaque user defined representation of the material */ 68 }; 69 70 static const struct sschiff_material SSCHIFF_NULL_MATERIAL = { NULL, NULL }; 71 72 /* User defined distribution of the geometries. The unit of the geometry is the 73 * micron, i.e. 1.0f == 1 micron */ 74 struct sschiff_geometry_distribution { 75 struct sschiff_material material; /* Material of the geometry distribution */ 76 double characteristic_length; 77 res_T (*sample) /* Sample a geometry i.e. a shape */ 78 (struct ssp_rng* rng, 79 void** shape, /* Returned client side data of the sampled shape */ 80 struct s3d_shape* s3d_shape, /* Star-3D shape where geometry are stored */ 81 void* context); 82 res_T (*sample_volume_scaling) /* Can be NULL <=> No volume scaling */ 83 (struct ssp_rng* rng, 84 void* shape, /* Client side shape into which a volume scaling is sampled */ 85 double* scale_factor, /* Scale factor to apply to the shape volume */ 86 void* context); 87 void* context; 88 }; 89 90 static const struct sschiff_geometry_distribution 91 SSCHIFF_NULL_GEOMETRY_DISTRIBUTION = { {NULL, NULL}, -1.0, NULL, NULL, NULL }; 92 93 /* State of the Monte Carlo estimation */ 94 struct sschiff_state { 95 double E; /* Expected value */ 96 double V; /* Variance */ 97 double SE; /* Standard error */ 98 }; 99 100 struct sschiff_cross_section { 101 struct sschiff_state extinction; 102 struct sschiff_state absorption; 103 struct sschiff_state scattering; 104 struct sschiff_state average_projected_area; 105 }; 106 107 /* Type of the function used to distribute the scattering angles in [0, PI]. 108 * nangles is assumed to be greater than or equal to 2 and the angles is 109 * ensured to have `nangles' entries. */ 110 typedef void (*sschiff_scattering_angles_distribution_T) 111 (double angles[], const size_t nangles); 112 113 /* Opaque types */ 114 struct sschiff_device; 115 struct sschiff_estimator; 116 117 BEGIN_DECLS 118 119 /* Built-in uniform distribution of scattering angles */ 120 SSCHIFF_API const sschiff_scattering_angles_distribution_T 121 sschiff_uniform_scattering_angles; 122 123 /******************************************************************************* 124 * Star Schiff API 125 ******************************************************************************/ 126 127 SSCHIFF_API res_T 128 sschiff_device_create 129 (struct logger* logger, /* May be NULL <=> use default logger */ 130 struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ 131 const unsigned nthreads_hint, /* Hint on the number of threads to use */ 132 const int verbose, /* Make the command more verbose */ 133 struct s3d_device* s3d, /* May be NULL <=> internally create a S3D device */ 134 struct sschiff_device** dev); 135 136 /* Return the number of threads effectively used by the Star-Schiff device */ 137 SSCHIFF_API res_T 138 sschiff_device_get_threads_count 139 (struct sschiff_device* dev, 140 unsigned* nthreads); 141 142 SSCHIFF_API res_T 143 sschiff_device_ref_get 144 (struct sschiff_device* dev); 145 146 SSCHIFF_API res_T 147 sschiff_device_ref_put 148 (struct sschiff_device* dev); 149 150 SSCHIFF_API res_T 151 sschiff_integrate 152 (struct sschiff_device* dev, 153 struct ssp_rng* rng, 154 struct sschiff_geometry_distribution* distribution, 155 /* Wavelengths to estimate in micron. Must be sorted in ascending order. */ 156 const double* wavelengths, 157 const size_t wavelengths_count, /* # wavelengths to estimate */ 158 const sschiff_scattering_angles_distribution_T angles, /* angles distrib */ 159 const size_t scattering_angles_count, /* # scattering angles. Must be >= 3 */ 160 const size_t sampled_geometries_count, /* # geometries to sample */ 161 const size_t sampled_directions_count, /* # directions to sample per geometry */ 162 const int discard_wide_angles, /* Avoid analytic model for wide angles */ 163 struct sschiff_estimator** estimator); 164 165 SSCHIFF_API res_T 166 sschiff_estimator_ref_get 167 (struct sschiff_estimator* estimator); 168 169 SSCHIFF_API res_T 170 sschiff_estimator_ref_put 171 (struct sschiff_estimator* estimator); 172 173 /* Return the list of estimated wavelengths. */ 174 SSCHIFF_API res_T 175 sschiff_estimator_get_wavelengths 176 (const struct sschiff_estimator* estimator, 177 const double** wavelengths, /* May be NULL, i.e. do not return this list */ 178 size_t* count); /* May be NULL, i.e. do not return the # wavelengths */ 179 180 /* Return the list of scattering angles. */ 181 SSCHIFF_API res_T 182 sschiff_estimator_get_scattering_angles 183 (const struct sschiff_estimator* estimator, 184 const double** angles, /* May be NULL, i.e. do not return the angles */ 185 size_t* count); /* May be NULL, i.e. do not return the # scattering angles */ 186 187 /* Return the number of Monte Carlo realisations */ 188 SSCHIFF_API res_T 189 sschiff_estimator_get_realisations_count 190 (const struct sschiff_estimator* estimator, 191 size_t* count); 192 193 /* Retrieve the estimation state of a given wavelength. */ 194 SSCHIFF_API res_T 195 sschiff_estimator_get_cross_section 196 (const struct sschiff_estimator* estimator, 197 const size_t wavelength_index, /* Id of the wavelengths */ 198 struct sschiff_cross_section* cross_section); 199 200 /* Retrieve the estimated cross sections of all wavelengths. The length of 201 * `cross_sections' must be at least equal to the count of integrated 202 * wavelengths. One can use the sschiff_estimator_get_wavelengths function to 203 * retrieve this information. */ 204 SSCHIFF_API res_T 205 sschiff_estimator_get_cross_sections 206 (const struct sschiff_estimator* estimator, 207 struct sschiff_cross_section cross_sections[]); 208 209 /* Retrieve a pointer onto the estimated phase function for the scattering 210 * angles of the estimator. Use the sschiff_estimator_get_scattering_angles 211 * function to retrieve these scattering angles. Return RES_BAD_OP if the phase 212 * function couldn't be estimated for this wavelength */ 213 SSCHIFF_API res_T 214 sschiff_estimator_get_phase_function 215 (const struct sschiff_estimator* estimator, 216 const size_t wavelength_index, 217 const struct sschiff_state** states); 218 219 /* Retrieve a pointer onto the estimated phase function cumulative for the 220 * scattering angles of the estimator. Use the 221 * sschiff_estimator_get_scattering_angles function to retrieve these 222 * scattering angles. Return RES_BAD_OP if the phase function couldn't be 223 * estimated for this wavelength */ 224 SSCHIFF_API res_T 225 sschiff_estimator_get_phase_function_cumulative 226 (const struct sschiff_estimator* estimator, 227 const size_t wavelength_index, 228 const struct sschiff_state** states); 229 230 /* Compute the inverse cumulative of the estimated phase function. The inverse 231 * cumulative is computed for a set of `nthetas' values distributed in [0, 1] 232 * as [0, 1*S, 2*S, ..., i*S, ..., (nthetas-1)*S] with S=1/(nthetas-1). The 233 * ouput array `thetas' stored the angles corresponding to these cumulative 234 * values. Its length must be at least equal to `nthetas'. Return RES_BAD_OP of 235 * the cumulative phase function cannot be inverted. */ 236 SSCHIFF_API res_T 237 sschiff_estimator_inverse_cumulative_phase_function 238 (const struct sschiff_estimator* estimator, 239 const size_t wavelength_index, 240 double thetas[], 241 const size_t nthetas); /* Must be >= 2 */ 242 243 244 /* Retrieve, for the submitted wavelength, the index of the last small 245 * scattering angle, i.e. the last angle from which the phase function 246 * [cumulative] is estimated by Monte Carlo. One can use this index to get the 247 * value of the limit angle from the scattering angles returned by the 248 * sschiff_estimator_get_scattering_angles function. Return RES_BAD_OP if the 249 * phase function is not computable for this wavelength. */ 250 SSCHIFF_API res_T 251 sschiff_estimator_get_limit_scattering_angle_index 252 (const struct sschiff_estimator* estimator, 253 const size_t wavelength_index, 254 size_t* scattering_angle_index); 255 256 /* Return the `n' parameter of the model used to compute the phase function of 257 * the wide scattering angles for a given wavelength. Return RES_BAD_OP if the 258 * phase function is not computable for this wavelength */ 259 SSCHIFF_API res_T 260 sschiff_estimator_get_wide_scattering_angle_model_parameter 261 (const struct sschiff_estimator* estimator, 262 const size_t wavelength_index, 263 double* n); 264 265 /* Return the estimated differential cross section for a wavelength at a given 266 * scattering angle. Return RES_BAD_OP if it was not computable. */ 267 SSCHIFF_API res_T 268 sschiff_estimator_get_differential_cross_section 269 (const struct sschiff_estimator* estimator, 270 const size_t wavelength_index, 271 const size_t scattering_angle_index, 272 struct sschiff_state* state); 273 274 /* Return the estimated differential cross section cumulative for a wavelength 275 * at a given scattering angle. Return RES_BAD_OP if it was not computable. */ 276 SSCHIFF_API res_T 277 sschiff_estimator_get_differential_cross_section_cumulative 278 (const struct sschiff_estimator* estimator, 279 const size_t wavelength_index, 280 const size_t scanttering_angle_index, 281 struct sschiff_state* state); 282 283 END_DECLS 284 285 #endif /* SSCHIFF_H */ 286