rnatm.h (15283B)
1 /* Copyright (C) 2022, 2023, 2025 Centre National de la Recherche Scientifique 2 * Copyright (C) 2022, 2023, 2025 Institut Pierre-Simon Laplace 3 * Copyright (C) 2022, 2023, 2025 Institut de Physique du Globe de Paris 4 * Copyright (C) 2022, 2023, 2025 |Méso|Star> (contact@meso-star.com) 5 * Copyright (C) 2022, 2023, 2025 Observatoire de Paris 6 * Copyright (C) 2022, 2023, 2025 Université de Reims Champagne-Ardenne 7 * Copyright (C) 2022, 2023, 2025 Université de Versaille Saint-Quentin 8 * Copyright (C) 2022, 2023, 2025 Université Paul Sabatier 9 * 10 * This program is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation, either version 3 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 22 23 #ifndef RNATM_H 24 #define RNATM_H 25 26 #include <star/suvm.h> 27 #include <star/svx.h> 28 29 #include <rsys/rsys.h> 30 31 /* Library symbol management */ 32 #if defined(RNATM_SHARED_BUILD) /* Build shared library */ 33 #define RNATM_API extern EXPORT_SYM 34 #elif defined(RNATM_STATIC) /* Use/build static library */ 35 #define RNATM_API extern LOCAL_SYM 36 #else /* Use shared library */ 37 #define RNATM_API extern IMPORT_SYM 38 #endif 39 40 /* Helper macro that asserts if the invocation of the rnatm function `Func' 41 * returns an error. One should use this macro on suvm function calls for 42 * which no explicit error checking is performed */ 43 #ifndef NDEBUG 44 #define RNATM(Func) ASSERT(rnatm_ ## Func == RES_OK) 45 #else 46 #define RNATM(Func) rnatm_ ## Func 47 #endif 48 49 /* Gas identifier */ 50 #define RNATM_GAS ((size_t)-1) 51 52 /* Maximum number of components supported by the library (gas included) */ 53 #define RNATM_MAX_COMPONENTS_COUNT 16 54 55 /* Forward declaration of external data types */ 56 struct logger; 57 struct mem_allocator; 58 struct ssf_phase; 59 60 enum rnatm_radcoef { 61 RNATM_RADCOEF_Ka, /* Absorption coefficient */ 62 RNATM_RADCOEF_Ks, /* Scattering coefficient */ 63 RNATM_RADCOEF_Kext, /* Extinction coefficient */ 64 RNATM_RADCOEFS_COUNT__ 65 }; 66 67 enum rnatm_svx_op { 68 RNATM_SVX_OP_MIN, 69 RNATM_SVX_OP_MAX, 70 RNATM_SVX_OPS_COUNT__ 71 }; 72 73 struct rnatm_gas_args { 74 char* smsh_filename; /* Geometry */ 75 char* sck_filename; /* Radiative properties */ 76 char* temperatures_filename; /* Temperature */ 77 }; 78 #define RNATM_GAS_ARGS_NULL__ {NULL, NULL, NULL} 79 static const struct rnatm_gas_args RNATM_GAS_ARGS_NULL = RNATM_GAS_ARGS_NULL__; 80 81 struct rnatm_aerosol_args { 82 char* name; /* NULL <=> use default name */ 83 char* smsh_filename; /* Geometry */ 84 char* sars_filename; /* Radiative properties */ 85 char* phase_fn_ids_filename; /* Per node phase function id */ 86 char* phase_fn_lst_filename; /* List of phase functions */ 87 }; 88 #define RNATM_AEROSOL_ARGS_NULL__ {NULL, NULL, NULL, NULL, NULL} 89 static const struct rnatm_aerosol_args RNATM_AEROSOL_ARGS_NULL = 90 RNATM_AEROSOL_ARGS_NULL__; 91 92 struct rnatm_cell_pos { 93 struct suvm_primitive prim; /* Volumetric primitive */ 94 double barycentric_coords[4]; /* position relative to `prim' */ 95 96 /* Component to which the cell belongs. This is either an aerosol index or 97 * the RNATM_GAS constant */ 98 size_t component; 99 }; 100 #define RNATM_CELL_POS_NULL__ {SUVM_PRIMITIVE_NULL__, {0,0,0,0}, RNATM_GAS} 101 static const struct rnatm_cell_pos RNATM_CELL_POS_NULL = RNATM_CELL_POS_NULL__; 102 103 struct rnatm_band_desc { 104 double lower; /* Lower band wavelength in nm (inclusive) */ 105 double upper; /* Upper band wavelength in nm (exclusive) */ 106 size_t quad_pts_count; /* #quadrature points */ 107 }; 108 #define RNATM_BAND_DESC_NULL__ {0,0,0} 109 static const struct rnatm_band_desc RNATM_BAND_DESC_NULL = 110 RNATM_BAND_DESC_NULL__; 111 112 struct rnatm_get_radcoef_args { 113 /* Cells to be queried. Refer to the rnatm_fetch_cell_list function */ 114 struct rnatm_cell_pos* cells; 115 116 size_t iband; /* Index of the spectral band to consider */ 117 size_t iquad; /* Index of the quadrature point to consider */ 118 119 enum rnatm_radcoef radcoef; 120 121 /* For debug: check that the retrieved radcoef is in [k_min, k_max] */ 122 double k_min; 123 double k_max; 124 }; 125 #define RNATM_GET_RADCOEF_ARGS_NULL__ { \ 126 NULL, 0, 0, RNATM_RADCOEFS_COUNT__, -DBL_MAX, DBL_MAX \ 127 } 128 static const struct rnatm_get_radcoef_args 129 RNATM_GET_RADCOEF_ARGS_NULL = RNATM_GET_RADCOEF_ARGS_NULL__; 130 131 struct rnatm_sample_component_args { 132 /* Cells to be queried. Refer to the rnatm_fetch_cell_list function */ 133 const struct rnatm_cell_pos* cells; 134 135 size_t iband; /* Index of the spectral band to consider */ 136 size_t iquad; /* Index of the quadrature point to consider */ 137 138 enum rnatm_radcoef radcoef; 139 140 double r; /* Random number uniformaly distributed in [0, 1[ */ 141 }; 142 #define RNATM_SAMPLE_COMPONENT_ARGS_NULL__ { \ 143 NULL, 0, 0, RNATM_RADCOEFS_COUNT__, 0 \ 144 } 145 static const struct rnatm_sample_component_args 146 RNATM_SAMPLE_COMPONENT_ARGS_NULL = RNATM_SAMPLE_COMPONENT_ARGS_NULL__; 147 148 struct rnatm_cell_get_radcoef_args { 149 struct rnatm_cell_pos cell; /* Cell to query */ 150 size_t iband; /* Index of the spectral band to query */ 151 size_t iquad; /* Index of the quadrature point to query in the band */ 152 153 enum rnatm_radcoef radcoef; 154 155 /* For debug: check that the retrieved radcoef is < k_max. Do not provide 156 * k_min because the radiative coefficient of a component may be less than 157 * the radiative coefficient of the mixture */ 158 double k_max; 159 }; 160 #define RNATM_CELL_GET_RADCOEF_ARGS_NULL__ { \ 161 RNATM_CELL_POS_NULL__, \ 162 0, 0, /* Spectral data (band, quadrature pointh) */ \ 163 RNATM_RADCOEFS_COUNT__, \ 164 DBL_MAX /* For debug: Radcoef range */ \ 165 } 166 static const struct rnatm_cell_get_radcoef_args 167 RNATM_CELL_GET_RADCOEF_ARGS_NULL = RNATM_CELL_GET_RADCOEF_ARGS_NULL__; 168 169 struct rnatm_cell_create_phase_fn_args { 170 struct rnatm_cell_pos cell; /* Cell to query */ 171 double wavelength; /* In nm */ 172 double r[2]; /* Random numbers uniformaly distributed in [0, 1[ */ 173 }; 174 #define RNATM_CELL_CREATE_PHASE_FN_ARGS_NULL__ { \ 175 RNATM_CELL_POS_NULL__, 0, {0,0} \ 176 } 177 static const struct rnatm_cell_create_phase_fn_args 178 RNATM_CELL_CREATE_PHASE_FN_ARGS_NULL = RNATM_CELL_CREATE_PHASE_FN_ARGS_NULL__; 179 180 struct rnatm_trace_ray_args { 181 double ray_org[3]; /* Origin of the ray */ 182 double ray_dir[3]; /* Direction of the ray */ 183 double ray_range[2]; /* Range of the ray */ 184 185 svx_hit_challenge_T challenge; /* NULL <=> Traversed up to the leaves */ 186 svx_hit_filter_T filter; /* NULL <=> Stop RT at the 1st intersected voxel */ 187 void* context; /* User data send to the 'challenge' & 'filter' function */ 188 189 size_t iband; /* Index of the spectral band to consider */ 190 size_t iquad; /* Index of the quadrature point to consider */ 191 }; 192 #define RNATM_TRACE_RAY_ARGS_NULL__ { \ 193 {0,0,0}, /* Ray origin */ \ 194 {0,0,0}, /* Ray direction */ \ 195 {0,DBL_MAX}, /* Ray range */ \ 196 \ 197 NULL, /* Challenge functor */ \ 198 NULL, /* Filter functor */ \ 199 NULL, /* User defined data */ \ 200 \ 201 SIZE_MAX, /* Index of the spectral band */ \ 202 SIZE_MAX /* Index of the quadrature point */ \ 203 } 204 static const struct rnatm_trace_ray_args 205 RNATM_TRACE_RAY_ARGS_NULL = RNATM_TRACE_RAY_ARGS_NULL__; 206 207 struct rnatm_create_args { 208 struct rnatm_gas_args gas; 209 struct rnatm_aerosol_args* aerosols; 210 size_t naerosols; 211 char* name; /* Name of the atmosphere */ 212 213 /* Read/write file where octrees are offloaded. May be NULL => octrees are 214 * built at runtime and kept in memory */ 215 FILE* octrees_storage; 216 217 /* Defines whether the octrees to be taken into account have already been 218 * unloaded into 'octrees_storage' at a previous run and, therefore, can be 219 * loaded from the provided file rather than built from scratch */ 220 int load_octrees_from_storage; 221 222 /* Spectral range to consider (in nanometers). Limits are inclusive */ 223 double spectral_range[2]; 224 double optical_thickness; /* Threshold used during octree building */ 225 226 unsigned grid_definition_hint; /* Hint on the grid definition */ 227 int precompute_normals; /* Pre-compute the tetrahedra normals */ 228 229 struct logger* logger; /* NULL <=> use default logger */ 230 struct mem_allocator* allocator; /* NULL <=> use default allocator */ 231 232 unsigned nthreads; /* Hint on the number of threads to use */ 233 int verbose; /* Verbosity level */ 234 }; 235 #define RNATM_CREATE_ARGS_DEFAULT__ { \ 236 RNATM_GAS_ARGS_NULL__, /* Gas */ \ 237 NULL, /* Aerosols */ \ 238 0, /* Number of aerosols */ \ 239 "atmosphere", /* Name */ \ 240 \ 241 NULL, /* octrees storage */ \ 242 0, \ 243 \ 244 {380, 780}, /* Spectral range */ \ 245 1, /* Optical thickness */ \ 246 \ 247 512, /* Hint on the grid definition */ \ 248 0, /* Precompute tetrahedra normals */ \ 249 \ 250 NULL, /* Logger */ \ 251 NULL, /* Allocator */ \ 252 \ 253 (unsigned)~0, /* #threads */ \ 254 0 /* Verbosity level */ \ 255 } 256 static const struct rnatm_create_args RNATM_CREATE_ARGS_DEFAULT = 257 RNATM_CREATE_ARGS_DEFAULT__; 258 259 /* Opaque data types */ 260 struct rnatm; 261 262 /* Helper macro that returns the cell of a component from a list of 263 * rnatm_cell_pos returned by the rnatm_fetch_cell_list function */ 264 #define RNATM_GET_COMPONENT_CELL(Cells, Cpnt) ((Cells)[(Cpnt)+1]) 265 266 BEGIN_DECLS 267 268 /******************************************************************************* 269 * API of the Rad-Net ATMosphere library 270 ******************************************************************************/ 271 RNATM_API res_T 272 rnatm_create 273 (const struct rnatm_create_args* args, 274 struct rnatm** atm); 275 276 RNATM_API res_T 277 rnatm_ref_get 278 (struct rnatm* atm); 279 280 RNATM_API res_T 281 rnatm_ref_put 282 (struct rnatm* atm); 283 284 /* Validates the atmosphere data. Data checks have already been done on load, 285 * but this function performs longer tests: for example, it iterates over all 286 * indices of the aerosol phase function check their validity against the mesh 287 * they are associated with and the phase function list loaded */ 288 RNATM_API res_T 289 rnatm_validate 290 (const struct rnatm* atm); 291 292 RNATM_API double 293 rnatm_get_k_svx_voxel 294 (const struct rnatm* atm, 295 const struct svx_voxel* voxel, 296 const enum rnatm_radcoef radcoef, 297 const enum rnatm_svx_op op); 298 299 RNATM_API res_T 300 rnatm_get_radcoef 301 (const struct rnatm* atm, 302 const struct rnatm_get_radcoef_args* args, 303 double* k); 304 305 RNATM_API res_T 306 rnatm_sample_component 307 (const struct rnatm* atm, 308 const struct rnatm_sample_component_args* args, 309 size_t* cpnt); 310 311 RNATM_API res_T 312 rnatm_fetch_cell 313 (const struct rnatm* atm, 314 const double pos[3], 315 /* Component. This is either an aerosol index or the RNATM_GAS constant */ 316 const size_t cpnt, 317 struct rnatm_cell_pos* cell); 318 319 /* Returns the cells of each component corresponding to the given position */ 320 RNATM_API res_T 321 rnatm_fetch_cell_list 322 (const struct rnatm* atm, 323 const double pos[3], 324 /* The capacity of the submitted cell array must be greater than or equal to 325 * the number of atmospheric components. If you are not sure, allocate (on 326 * the stack or on the heap) an array whose capacity is 327 * RNATM_MAX_COMPONENTS_COUNT */ 328 struct rnatm_cell_pos* cells, 329 size_t* ncells); /* Total number of atmospheric components. May be NULL */ 330 331 RNATM_API res_T 332 rnatm_cell_get_radcoef 333 (const struct rnatm* atm, 334 const struct rnatm_cell_get_radcoef_args* args, 335 double* k); 336 337 RNATM_API res_T 338 rnatm_cell_create_phase_fn 339 (struct rnatm* atm, 340 const struct rnatm_cell_create_phase_fn_args* args, 341 struct ssf_phase** phase_fn); 342 343 RNATM_API res_T 344 rnatm_cell_get_gas_temperature 345 (const struct rnatm* atm, 346 const struct rnatm_cell_pos* cell, /* Must belongs to the gas */ 347 double* temperature); 348 349 RNATM_API res_T 350 rnatm_trace_ray 351 (struct rnatm* rnatm, 352 const struct rnatm_trace_ray_args* args, 353 struct svx_hit* hit); 354 355 RNATM_API size_t 356 rnatm_get_aerosols_count 357 (const struct rnatm* atm); 358 359 /* Returns the number of spectral items. One acceleration structure is built 360 * per spectral item from the gas and aerosols meshes */ 361 RNATM_API size_t 362 rnatm_get_spectral_items_count 363 (const struct rnatm* atm); 364 365 /* Returns the range of band indices covered by a given spectral range. The 366 * returned index range is degenerated (i.e. ibands[0] > ibands[1]) if no band 367 * is found */ 368 RNATM_API res_T 369 rnatm_find_bands 370 (const struct rnatm* rnatm, 371 const double range[2], /* In nm. Limits are inclusive */ 372 size_t ibands[2]); /* Range of overlaped bands. Limits are inclusive */ 373 374 RNATM_API res_T 375 rnatm_band_sample_quad_pt 376 (const struct rnatm* rnatm, 377 const double r, /* Canonical random number in [0, 1[ */ 378 const size_t iband, /* Index of the band to sample */ 379 size_t* iquad); 380 381 RNATM_API res_T 382 rnatm_band_get_desc 383 (const struct rnatm* rnatm, 384 const size_t iband, /* Index of the band to query */ 385 struct rnatm_band_desc* band); 386 387 /* Writes a set of octrees following the VTK file format */ 388 RNATM_API res_T 389 rnatm_write_vtk_octrees 390 (struct rnatm* atm, 391 /* Spectral items to consider. Limits are inclusive. There is one octree per 392 * spectral item */ 393 const size_t spectral_items[2], 394 FILE* stream); 395 396 END_DECLS 397 398 #endif /* RNATM_H */