star-phor

Radiative transfer solver for photoreactors.
git clone https://www.edstar.cnrs.fr/git/star-phor.git
Log | Files | Refs | README | LICENSE

sphor_accum.h (6335B)


      1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique
      2  * Copyright (C) 2024-2026 Clermont Auvergne INP
      3  * Copyright (C) 2024-2026 INSA Lyon
      4  * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux
      5  * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse
      6  * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com)
      7  * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com)
      8  * Copyright (C) 2024-2026 Université de Lorraine
      9  * Copyright (C) 2024-2026 Université Paul Sabatier
     10  * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès
     11  *
     12  * This program is free software: you can redistribute it and/or modify
     13  * it under the terms of the GNU General Public License as published by
     14  * the Free Software Foundation, either version 3 of the License, or
     15  * (at your option) any later version.
     16  *
     17  * This program is distributed in the hope that it will be useful,
     18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     20  * GNU General Public License for more details.
     21  *
     22  * You should have received a copy of the GNU General Public License
     23  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     24 
     25 #ifndef SPHOR_ACCUM_H
     26 #define SPHOR_ACCUM_H
     27 
     28 #include "sphor_interface.h"
     29 
     30 #include <rsys/dynamic_array.h>
     31 #include <rsys/hash.h>             /* hash_fnv64 */
     32 #include <rsys/hash_table.h>
     33 #include <rsys/rsys.h>
     34 #include <rsys/str.h>
     35 
     36 struct mem_allocator;
     37 
     38 struct accum {
     39   struct str observable; /* Type of observable */
     40   struct str sensor;     /* Volume name or surface name */
     41   struct str component;  /* Optional: used to discriminate part of the events
     42                            (ex:  prop_rad name in volumes) */
     43   double sum;
     44   double sum2;
     45   size_t n_realizations;
     46 };
     47 #define ACCUM_NULL__ {0}
     48 static const struct accum ACCUM_NULL = ACCUM_NULL__;
     49 
     50 struct estim {
     51   double mean;
     52   double var;
     53   double std_err;
     54 };
     55 #define ESTIM_NULL__ {0}
     56 static const struct estim ESTIM_NULL = ESTIM_NULL__;
     57 
     58 enum sphor_sensor_type {
     59   SPHOR_SENSOR_VOLUME,
     60   SPHOR_SENSOR_SURFACE,
     61   SPHOR_SENSOR_NONE
     62 };
     63 
     64 struct accum_key {
     65   enum sphor_sensor_type sensor_type;
     66   size_t sensor_id;
     67   size_t component_id;
     68 };
     69 #define ACCUM_KEY_NULL__ {SPHOR_SENSOR_NONE, INVALID_ID, INVALID_ID}
     70 static const struct accum_key ACCUM_KEY_NULL = ACCUM_KEY_NULL__;
     71 
     72 extern LOCAL_SYM void
     73 accum_init
     74   (struct mem_allocator* allocator,
     75    struct accum* accum);
     76 
     77 extern LOCAL_SYM void
     78 accum_release
     79   (struct accum* accum);
     80 
     81 extern LOCAL_SYM res_T
     82 accum_copy
     83   (struct accum* dst,
     84    const struct accum* src);
     85 
     86 extern LOCAL_SYM res_T
     87 accum_copy_and_release
     88   (struct accum* dst,
     89    struct accum* src);
     90 
     91 extern LOCAL_SYM void
     92 accum_compute_estim
     93   (const struct accum* accum,
     94    struct estim* estim);
     95 
     96 extern LOCAL_SYM void
     97 write_accum_estim
     98   (const struct accum* accum,
     99    FILE* stream);
    100 
    101 /* Add two accums and return it in result */
    102 extern LOCAL_SYM void
    103 accum_add
    104   (const struct accum* op0,
    105    const struct accum* op1,
    106    struct accum* result);
    107 
    108 /* Generate darray_accum data type and API */
    109 #define DARRAY_NAME accum
    110 #define DARRAY_DATA struct accum
    111 #define DARRAY_FUNCTOR_INIT accum_init
    112 #define DARRAY_FUNCTOR_RELEASE accum_release
    113 #define DARRAY_FUNCTOR_COPY accum_copy
    114 #define DARRAY_FUNCTOR_COPY_AND_RELEASE accum_copy_and_release
    115 #include <rsys/dynamic_array.h>
    116 
    117 /* Generate darray of darray_accum data type and API */
    118 #define DARRAY_NAME accum_list
    119 #define DARRAY_DATA struct darray_accum
    120 #define DARRAY_FUNCTOR_INIT darray_accum_init
    121 #define DARRAY_FUNCTOR_RELEASE darray_accum_release
    122 #define DARRAY_FUNCTOR_COPY darray_accum_copy
    123 #define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_accum_copy_and_release
    124 #include <rsys/dynamic_array.h>
    125 
    126 static INLINE char
    127 accum_key_eq
    128   (const struct accum_key* a,
    129    const struct accum_key* b)
    130 {
    131   ASSERT(NULL != a);
    132   ASSERT(NULL != b);
    133 
    134   return a->sensor_type == b->sensor_type
    135       && a->sensor_id == b->sensor_id
    136       && a->component_id == b->component_id;
    137 }
    138 
    139 /* In many general cases, when using hash functions, we can directly apply the
    140  * hash function to the key as is.
    141  * This is not the case here, since using an enum may lead to different
    142  * hashes for the same accum_key structure across different function calls,
    143  * due to data alignment performed by the compiler
    144  * (see https://en.wikipedia.org/wiki/Data_structure_alignment). */
    145 static INLINE size_t
    146 accum_key_hash
    147   (const struct accum_key* accum_key)
    148 {
    149   size_t key[3] = {0};
    150   size_t hash = 0;
    151 
    152   ASSERT(NULL != accum_key);
    153 
    154   /* We convert the key into an array to ensure that all data is stored in a
    155    * contiguous memory block, with no padding bytes added by the compiler.
    156    * This guarantees that the same key will always produce the same hash. */
    157   key[0] = accum_key->sensor_type;
    158   key[1] = accum_key->sensor_id;
    159   key[2] = accum_key->component_id;
    160 
    161   hash = hash_fnv64(key, sizeof(key));
    162 
    163   return hash;
    164 }
    165 
    166 /* Generate the hash table that maps accum_key to an index used to access the
    167  * corresponding accum in the dynamic array */
    168 #define HTABLE_NAME accum2id
    169 #define HTABLE_KEY struct accum_key
    170 #define HTABLE_DATA size_t
    171 #define HTABLE_KEY_FUNCTOR_EQ accum_key_eq
    172 #define HTABLE_KEY_FUNCTOR_HASH accum_key_hash
    173 
    174 /* Include rsys/hash_table a second time to generate the hash table */
    175 #include <rsys/hash_table.h>
    176 
    177 extern LOCAL_SYM res_T
    178 register_accum
    179   (struct mem_allocator* allocator,
    180    char* observable,
    181    char* sensor,
    182    char* component,
    183    struct darray_accum *accums);
    184 
    185 /* Add all the elements (sum) of an accum list and return it in result */
    186 extern LOCAL_SYM void
    187 sum_accums
    188   (const struct darray_accum* accums,
    189    struct accum* result);
    190 
    191 /* Add the elements of same index in two different accum lists and return it in
    192  * result */
    193 extern LOCAL_SYM void
    194 accums_add
    195   (const struct darray_accum* op0,
    196    const struct darray_accum* op1,
    197    struct darray_accum* result);
    198 
    199 /* Add all the elements (sum) of same index of a list of darray_accums and
    200  * return it in result */
    201 extern LOCAL_SYM void
    202 sum_accum_lists
    203   (const struct darray_accum_list* accum_lists,
    204    struct darray_accum* accums);
    205 
    206 extern LOCAL_SYM void
    207 update_accum
    208   (const struct htable_accum2id* accum2id,
    209    const struct accum_key* accum_key,
    210    const double weight,
    211    struct darray_accum* accums);
    212 
    213 #endif /* SPHOR_ACCUM_H */