stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

sdis_scene_c.h (11364B)


      1 /* Copyright (C) 2016-2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #ifndef SDIS_SCENE_C_H
     17 #define SDIS_SCENE_C_H
     18 
     19 #include <star/s2d.h>
     20 #include <star/s3d.h>
     21 
     22 #include <rsys/dynamic_array_uint.h>
     23 #include <rsys/hash.h>
     24 #include <rsys/hash_table.h>
     25 #include <rsys/ref_count.h>
     26 
     27 #include <limits.h>
     28 
     29 #define MEDIUM_ID_MULTI UINT_MAX
     30 #define ENCLOSURE_ID_NULL UINT_MAX
     31 
     32 struct prim_prop {
     33   struct sdis_interface* interf;
     34   unsigned front_enclosure; /* Id of the front facing enclosure  */
     35   unsigned back_enclosure; /* Id of the back facing enclosure */
     36 };
     37 
     38 struct hit_filter_data {
     39   struct s2d_hit hit_2d;
     40   struct s3d_hit hit_3d;
     41   double epsilon; /* Threshold defining roughly equal intersections */
     42 
     43   /* When a scene is defined, primitives that do not point to the defined
     44    * enclosure are filtered out */
     45   struct sdis_scene* scn; /* NULL <=> do not filter wrt enc_id */
     46   unsigned enc_id;
     47 
     48   /* Bypass the regular filter function */
     49   s2d_hit_filter_function_T custom_filter_2d;
     50   s3d_hit_filter_function_T custom_filter_3d;
     51 
     52   /* Custom filter query data. It is ignored if custom_filter is NULL */
     53   void* custom_filter_data;
     54 };
     55 #define HIT_FILTER_DATA_NULL__ \
     56   {S2D_HIT_NULL__,S3D_HIT_NULL__,0,NULL,ENCLOSURE_ID_NULL,NULL,NULL,NULL}
     57 static const struct hit_filter_data HIT_FILTER_DATA_NULL =
     58   HIT_FILTER_DATA_NULL__;
     59 
     60 static INLINE void
     61 prim_prop_init(struct mem_allocator* allocator, struct prim_prop* prim)
     62 {
     63   (void)allocator;
     64   prim->interf = NULL;
     65   prim->front_enclosure = UINT_MAX;
     66   prim->back_enclosure = UINT_MAX;
     67 }
     68 
     69 static INLINE void
     70 interface_init(struct mem_allocator* allocator, struct sdis_interface** interf)
     71 {
     72   (void)allocator;
     73   *interf = NULL;
     74 }
     75 
     76 static INLINE void
     77 medium_init(struct mem_allocator* allocator, struct sdis_medium** medium)
     78 {
     79   (void)allocator;
     80   *medium = NULL;
     81 }
     82 
     83 struct enclosure {
     84   struct s2d_scene_view* s2d_view;
     85   struct s3d_scene_view* s3d_view;
     86   /* Map the id of the enclosure primitives to their primitive id into the
     87    * whole scene */
     88   struct darray_uint local2global;
     89 
     90   double hc_upper_bound;
     91   double S_over_V; /* in 3D = surface/volume; in 2D = perimeter/area */
     92   double V; /* 3D = volume; 2D = area; */
     93 
     94   unsigned medium_id;
     95 };
     96 
     97 static INLINE void
     98 enclosure_init(struct mem_allocator* allocator, struct enclosure* enc)
     99 {
    100   ASSERT(allocator && enc);
    101   enc->s2d_view = NULL;
    102   enc->s3d_view = NULL;
    103   darray_uint_init(allocator, &enc->local2global);
    104   enc->S_over_V = 0;
    105   enc->V = 0;
    106   enc->hc_upper_bound = 0;
    107   enc->medium_id = MEDIUM_ID_MULTI;
    108 }
    109 
    110 static INLINE void
    111 enclosure_release(struct enclosure* enc)
    112 {
    113   if(enc->s2d_view) S2D(scene_view_ref_put(enc->s2d_view));
    114   if(enc->s3d_view) S3D(scene_view_ref_put(enc->s3d_view));
    115   darray_uint_release(&enc->local2global);
    116 }
    117 
    118 static INLINE res_T
    119 enclosure_copy(struct enclosure* dst, const struct enclosure* src)
    120 {
    121   if(src->s3d_view) {
    122     S3D(scene_view_ref_get(src->s3d_view));
    123     dst->s3d_view = src->s3d_view;
    124   }
    125   if(src->s2d_view) {
    126     S2D(scene_view_ref_get(src->s2d_view));
    127     dst->s2d_view = src->s2d_view;
    128   }
    129   dst->S_over_V = src->S_over_V;
    130   dst->V = src->V;
    131   dst->hc_upper_bound = src->hc_upper_bound;
    132   dst->medium_id = src->medium_id;
    133   return darray_uint_copy(&dst->local2global, &src->local2global);
    134 }
    135 
    136 static INLINE res_T
    137 enclosure_copy_and_release(struct enclosure* dst, struct enclosure* src)
    138 {
    139   res_T res = RES_OK;
    140   res = darray_uint_copy_and_release(&dst->local2global, &src->local2global);
    141   if(res != RES_OK) return res;
    142   if(src->s3d_view) {
    143     /* Only transfer ownership */
    144     dst->s3d_view = src->s3d_view;
    145     src->s3d_view = NULL;
    146   }
    147   if(src->s2d_view) {
    148     /* Only transfer ownership */
    149     dst->s2d_view = src->s2d_view;
    150     src->s2d_view = NULL;
    151   }
    152   dst->S_over_V = src->S_over_V;
    153   dst->V = src->V;
    154   dst->hc_upper_bound = src->hc_upper_bound;
    155   dst->medium_id = src->medium_id;
    156   return RES_OK;
    157 }
    158 
    159 static INLINE unsigned
    160 enclosure_local2global_prim_id
    161   (const struct enclosure* enc,
    162    const size_t local_prim_id)
    163 {
    164   ASSERT(enc && local_prim_id < darray_uint_size_get(&enc->local2global));
    165   return darray_uint_cdata_get(&enc->local2global)[local_prim_id];
    166 }
    167 
    168 static INLINE void
    169 primkey_init
    170   (const struct mem_allocator* allocator,
    171    struct sdis_primkey* key)
    172 {
    173   ASSERT(allocator && key);
    174   (void)allocator;
    175   *key = SDIS_PRIMKEY_NULL;
    176 }
    177 
    178 /* Declare the array of interfaces */
    179 #define DARRAY_NAME interf
    180 #define DARRAY_DATA struct sdis_interface*
    181 #define DARRAY_FUNCTOR_INIT interface_init
    182 #include <rsys/dynamic_array.h>
    183 
    184 /* Declare the array of media */
    185 #define DARRAY_NAME medium
    186 #define DARRAY_DATA struct sdis_medium*
    187 #define DARRAY_FUNCTOR_INIT medium_init
    188 #include <rsys/dynamic_array.h>
    189 
    190 /* Declare the array of primitives */
    191 #define DARRAY_NAME prim_prop
    192 #define DARRAY_DATA struct prim_prop
    193 #define DARRAY_FUNCTOR_INIT prim_prop_init
    194 #include <rsys/dynamic_array.h>
    195 
    196 /* Declare the hash table that maps an enclosure id to its data */
    197 #define HTABLE_NAME enclosure
    198 #define HTABLE_KEY unsigned
    199 #define HTABLE_DATA struct enclosure
    200 #define HTABLE_DATA_FUNCTOR_INIT enclosure_init
    201 #define HTABLE_DATA_FUNCTOR_RELEASE enclosure_release
    202 #define HTABLE_DATA_FUNCTOR_COPY enclosure_copy
    203 #define HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE enclosure_copy_and_release
    204 #include <rsys/hash_table.h>
    205 
    206 /* Declare the hash table that maps an enclosure id to hc upper bound */
    207 #define HTABLE_NAME d
    208 #define HTABLE_KEY unsigned
    209 #define HTABLE_DATA double
    210 #include <rsys/hash_table.h>
    211 
    212 /* Declare the hash table that maps the primitive key to its 2D primitve */
    213 #define HTABLE_NAME key2prim2d
    214 #define HTABLE_KEY struct sdis_primkey
    215 #define HTABLE_KEY_FUNCTOR_INIT primkey_init
    216 #define HTABLE_KEY_FUNCTOR_HASH sdis_primkey_hash
    217 #define HTABLE_KEY_FUNCTOR_EQ sdis_primkey_eq
    218 #define HTABLE_DATA struct s2d_primitive
    219 #include <rsys/hash_table.h>
    220 
    221 /* Declare the hash table that maps the primitive key to its 3D primitive */
    222 #define HTABLE_NAME key2prim3d
    223 #define HTABLE_KEY struct sdis_primkey
    224 #define HTABLE_KEY_FUNCTOR_INIT primkey_init
    225 #define HTABLE_KEY_FUNCTOR_HASH sdis_primkey_hash
    226 #define HTABLE_KEY_FUNCTOR_EQ sdis_primkey_eq
    227 #define HTABLE_DATA struct s3d_primitive
    228 #include <rsys/hash_table.h>
    229 
    230 struct sdis_scene {
    231   struct darray_interf interfaces; /* List of interfaces own by the scene */
    232   struct darray_medium media; /* List of media own by the scene */
    233   struct darray_prim_prop prim_props; /* Per primitive properties */
    234   struct s2d_scene_view* s2d_view;
    235   struct s3d_scene_view* s3d_view;
    236   struct senc2d_scene* senc2d_scn;
    237   struct senc3d_scene* senc3d_scn;
    238 
    239   struct htable_d tmp_hc_ub; /* Map an enclosure id to its hc upper bound */
    240   struct htable_enclosure enclosures; /* Map an enclosure id to its data */
    241   unsigned outer_enclosure_id;
    242 
    243   /* Map a primivei key to its Star-2D/Star-3D primitive */
    244   struct htable_key2prim2d key2prim2d;
    245   struct htable_key2prim3d key2prim3d;
    246 
    247   double fp_to_meter;
    248   double tmin; /* Minimum temperature of the system (In Kelvin) */
    249   double tmax; /* Maximum temperature of the system (In Kelvin) */
    250 
    251   struct sdis_source* source; /* External source. May be NULL */
    252   struct sdis_radiative_env* radenv; /* Radiative environment. May be NULL */
    253 
    254   ref_T ref;
    255   struct sdis_device* dev;
    256 };
    257 
    258 static FINLINE size_t
    259 scene_get_primitives_count(const struct sdis_scene* scn)
    260 {
    261   ASSERT(scn);
    262   return darray_prim_prop_size_get(&scn->prim_props);
    263 }
    264 
    265 extern LOCAL_SYM struct sdis_interface*
    266 scene_get_interface
    267   (const struct sdis_scene* scene,
    268    const unsigned iprim);
    269 
    270 extern LOCAL_SYM res_T
    271 scene_get_enclosure_id
    272   (struct sdis_scene* scene,
    273    const double position[],
    274    unsigned* enclosure_id);
    275 
    276 /* This function assumes that the position under test lies within a finite
    277  * enclosure. The enclosure in which it is located is therefore retrieved by
    278  * tracing a random ray around the current position. For infinite enclosures,
    279  * you need to use the `scene_get_enclosure_id' function, which in turn may take
    280  * longer.
    281  *
    282  * Note that the function actually calls scene_get_enclosure internally if no
    283  * valid enclosure is found with the normal procedure. This may be due to
    284  * numerical problems or incorrect assumptions about the current enclosure (its
    285  * limits are open to infinity). */
    286 extern LOCAL_SYM res_T
    287 scene_get_enclosure_id_in_closed_boundaries
    288   (struct sdis_scene* scene,
    289    const double position[],
    290    unsigned* enclosure_id);
    291 
    292 extern LOCAL_SYM res_T
    293 scene_get_enclosure_medium
    294   (struct sdis_scene* scene,
    295    const struct enclosure* enclosure,
    296    struct sdis_medium** medium);
    297 
    298 extern LOCAL_SYM res_T
    299 scene_compute_hash
    300   (const struct sdis_scene* scn,
    301    hash256_T hash);
    302 
    303 /* Check that the primitive identifier is valid wrt the scene. If not, the
    304  * function prints an error message and returns RES_BAD_ARG. */
    305 extern LOCAL_SYM res_T
    306 scene_check_primitive_index
    307   (const struct sdis_scene* scn,
    308    const size_t iprim);
    309 
    310 /* Check that the scene is 2D. If not, the function prints an error message and
    311  * returns RES_BAD_ARG */
    312 extern LOCAL_SYM res_T
    313 scene_check_dimensionality_2d
    314   (const struct sdis_scene* scn);
    315 
    316 /* Check that the scene is 3D. If not, the function prints an error message and
    317  * returns RES_BAD_ARG */
    318 extern LOCAL_SYM res_T
    319 scene_check_dimensionality_3d
    320   (const struct sdis_scene* scn);
    321 
    322 /* Check that the temperature range of the scene is well defined, i.e. that the
    323  * minimum and maximum temperatures are known and that they define a valid
    324  * range. If this is not the case, the function displays an error message and
    325  * returns RES_BAD_ARG */
    326 extern LOCAL_SYM res_T
    327 scene_check_temperature_range
    328   (const struct sdis_scene* scn);
    329 
    330 static INLINE void
    331 scene_get_enclosure_ids
    332   (const struct sdis_scene* scn,
    333    const unsigned iprim,
    334    unsigned encs[2]) /* Front and Back enclosure identifiers */
    335 {
    336   ASSERT(scn && iprim < darray_prim_prop_size_get(&scn->prim_props));
    337   ASSERT(encs);
    338   encs[0] = darray_prim_prop_cdata_get(&scn->prim_props)[iprim].front_enclosure;
    339   encs[1] = darray_prim_prop_cdata_get(&scn->prim_props)[iprim].back_enclosure;
    340 }
    341 
    342 static INLINE int
    343 scene_is_outside
    344   (const struct sdis_scene* scn,
    345    const enum sdis_side side,
    346    const unsigned iprim)
    347 {
    348   unsigned encs[2];
    349   ASSERT(scn && scn->outer_enclosure_id != UINT_MAX);
    350   scene_get_enclosure_ids(scn, iprim, encs);
    351   return (encs[side] == scn->outer_enclosure_id);
    352 }
    353 
    354 static INLINE const struct enclosure*
    355 scene_get_enclosure(struct sdis_scene* scn, const unsigned ienc)
    356 {
    357   const struct enclosure* enc = NULL;
    358   ASSERT(scn);
    359   enc = htable_enclosure_find(&scn->enclosures, &ienc);
    360   return enc;
    361 }
    362 
    363 static INLINE int
    364 scene_is_2d(const struct sdis_scene* scn)
    365 {
    366   ASSERT(scn && (scn->s2d_view || scn->s3d_view));
    367   return scn->s2d_view != NULL;
    368 }
    369 
    370 #endif /* SDIS_SCENE_C_H */
    371