rnatm

Load and structure data describing an atmosphere
git clone git://git.meso-star.fr/rnatm.git
Log | Files | Refs | README | LICENSE

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 */