stardis-solver

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

sdis_heat_path.h (13765B)


      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_HEAT_PATH_H
     17 #define SDIS_HEAT_PATH_H
     18 
     19 #include "sdis.h"
     20 #include "sdis_scene_c.h"
     21 
     22 #include <rsys/dynamic_array.h>
     23 #include <rsys/dynamic_array_size_t.h>
     24 #include <rsys/rsys.h>
     25 
     26 /* Forward declarations */
     27 struct green_path_handle;
     28 struct sdis_scene;
     29 struct ssp_rng;
     30 
     31 /*******************************************************************************
     32  * Context of a random walk, i.e. its data concerning the current system and the
     33  * solve parameters.
     34  ******************************************************************************/
     35  struct rwalk_context {
     36   struct green_path_handle* green_path;
     37   struct sdis_heat_path* heat_path;
     38 
     39   double Tmin; /* Lower bound temperature */
     40   double Tmin2; /* Tmin^2 */
     41   double Tmin3; /* Tmin^3 */
     42 
     43   double That; /* Upper bound temperature */
     44   double That2; /* That^2 */
     45   double That3; /* That^3 */
     46 
     47   /* Maximum branchings i.e. the maximum number of times XD(sample_coupled_path)
     48    * can be called. It controls the number of ramifications of the heat path and
     49    * currently is correlated to the Picard order used to estimate the radiative
     50    * temperature. max_branchings == picard_order-1 */
     51   size_t max_branchings;
     52 
     53   /* Number of heat path branchings */
     54   size_t nbranchings;
     55 
     56   /* Id of the realisation (for debug) */
     57   size_t irealisation;
     58 
     59   /* Algorithm used for the diffusive random walks,
     60    * i.e. for sampling conductive paths */
     61   enum sdis_diffusion_algorithm diff_algo;
     62 };
     63 #define RWALK_CONTEXT_NULL__ {                                                 \
     64   NULL, /* Green path */                                                       \
     65   NULL, /* Heat path */                                                        \
     66   0, /* Tmin */                                                                \
     67   0, /* Tmin^2 */                                                              \
     68   0, /* Tmin^3 */                                                              \
     69   0, /* That */                                                                \
     70   0, /* That^2 */                                                              \
     71   0, /* That^3 */                                                              \
     72   0, /* Max #branchings */                                                     \
     73   SIZE_MAX, /* #branchings */                                                  \
     74   SIZE_MAX, /* realisation id */                                               \
     75   SDIS_DIFFUSION_NONE /* Diffusion algorithm */                                \
     76 }
     77 static const struct rwalk_context RWALK_CONTEXT_NULL = RWALK_CONTEXT_NULL__;
     78 
     79 static INLINE size_t
     80 get_picard_order(const struct rwalk_context* ctx)
     81 {
     82   ASSERT(ctx);
     83   return ctx->max_branchings + 1;
     84 }
     85 
     86 /*******************************************************************************
     87  * 2D/3D random walk and associated temperature, i.e. current state of the
     88  * sampled path
     89  ******************************************************************************/
     90 struct rwalk {
     91   struct sdis_rwalk_vertex vtx; /* Position and time of the Random walk */
     92   unsigned enc_id; /* Id of the enclosure in which the random walk lies */
     93   struct s2d_hit hit_2d;
     94   struct s3d_hit hit_3d;
     95 
     96   /* Direction along which the random walk reached the radiative environment */
     97   double dir[3];
     98 
     99   double elapsed_time;
    100   enum sdis_side hit_side;
    101 };
    102 #define RWALK_NULL__ {                                                         \
    103   SDIS_RWALK_VERTEX_NULL__,                                                    \
    104   ENCLOSURE_ID_NULL,                                                           \
    105   S2D_HIT_NULL__,                                                              \
    106   S3D_HIT_NULL__,                                                              \
    107   {0,0,0},                                                                     \
    108   0,                                                                           \
    109   SDIS_SIDE_NULL__                                                             \
    110 }
    111 static const struct rwalk RWALK_NULL = RWALK_NULL__;
    112 
    113 struct temperature {
    114   res_T (*func)/* Next function to invoke in order to compute the temperature */
    115     (struct sdis_scene* scn,
    116      struct rwalk_context* ctx,
    117      struct rwalk* rwalk,
    118      struct ssp_rng* rng,
    119      struct temperature* temp);
    120   double value; /* Current value of the temperature */
    121   int done;
    122 };
    123 #define TEMPERATURE_NULL__ {NULL,0,0}
    124 static const struct temperature TEMPERATURE_NULL = TEMPERATURE_NULL__;
    125 
    126 /*******************************************************************************
    127  * Heat path data structure used to record the geometry of sampled paths
    128  ******************************************************************************/
    129 /* Generate the dynamic array of heat vertices */
    130 #define DARRAY_NAME heat_vertex
    131 #define DARRAY_DATA struct sdis_heat_vertex
    132 #include <rsys/dynamic_array.h>
    133 
    134 struct sdis_heat_path {
    135   /* List of the path vertices */
    136   struct darray_heat_vertex vertices;
    137 
    138   /* Indices of the vertices that mark a break in the path */
    139   struct darray_size_t breaks;
    140 
    141   enum sdis_heat_path_flag status;
    142 };
    143 
    144 static INLINE void
    145 heat_path_init(struct mem_allocator* allocator, struct sdis_heat_path* path)
    146 {
    147   ASSERT(path);
    148   path->status = SDIS_HEAT_PATH_NONE;
    149   darray_heat_vertex_init(allocator, &path->vertices);
    150   darray_size_t_init(allocator, &path->breaks);
    151 }
    152 
    153 static INLINE void
    154 heat_path_release(struct sdis_heat_path* path)
    155 {
    156   ASSERT(path);
    157   darray_heat_vertex_release(&path->vertices);
    158   darray_size_t_release(&path->breaks);
    159 }
    160 
    161 static INLINE res_T
    162 heat_path_copy(struct sdis_heat_path* dst, const struct sdis_heat_path* src)
    163 {
    164   res_T res = RES_OK;
    165   ASSERT(dst && src);
    166   dst->status = src->status;
    167   res = darray_heat_vertex_copy(&dst->vertices, &src->vertices);
    168   if(res != RES_OK) return res;
    169   res = darray_size_t_copy(&dst->breaks, &src->breaks);
    170   if(res != RES_OK) return res;
    171   return RES_OK;
    172 }
    173 
    174 static INLINE res_T
    175 heat_path_copy_and_release(struct sdis_heat_path* dst, struct sdis_heat_path* src)
    176 {
    177   res_T res = RES_OK;
    178   ASSERT(dst && src);
    179   dst->status = src->status;
    180   res = darray_heat_vertex_copy_and_release(&dst->vertices, &src->vertices);
    181   if(res != RES_OK) return res;
    182   res = darray_size_t_copy_and_release(&dst->breaks, &src->breaks);
    183   if(res != RES_OK) return res;
    184   return RES_OK;
    185 }
    186 
    187 static INLINE res_T
    188 heat_path_copy_and_clear(struct sdis_heat_path* dst, struct sdis_heat_path* src)
    189 {
    190   res_T res = RES_OK;
    191   ASSERT(dst && src);
    192   dst->status = src->status;
    193   res = darray_heat_vertex_copy_and_clear(&dst->vertices, &src->vertices);
    194   if(res != RES_OK) return res;
    195   res = darray_size_t_copy_and_clear(&dst->breaks, &src->breaks);
    196   if(res != RES_OK) return res;
    197   return RES_OK;
    198 }
    199 
    200 static INLINE res_T
    201 heat_path_add_vertex(struct sdis_heat_path* path, const struct sdis_heat_vertex* vtx)
    202 {
    203   ASSERT(path && vtx);
    204   return darray_heat_vertex_push_back(&path->vertices, vtx);
    205 }
    206 
    207 static INLINE size_t
    208 heat_path_get_vertices_count(const struct sdis_heat_path* path)
    209 {
    210   ASSERT(path);
    211   return darray_heat_vertex_size_get(&path->vertices);
    212 }
    213 
    214 static INLINE struct sdis_heat_vertex*
    215 heat_path_get_vertex(struct sdis_heat_path* path, const size_t ivert)
    216 {
    217   ASSERT(path && ivert < heat_path_get_vertices_count(path));
    218   return darray_heat_vertex_data_get(&path->vertices) + ivert;
    219 }
    220 
    221 static INLINE struct sdis_heat_vertex*
    222 heat_path_get_last_vertex(struct sdis_heat_path* path)
    223 {
    224   size_t sz;
    225   ASSERT(path);
    226   sz = heat_path_get_vertices_count(path);
    227   ASSERT(sz);
    228   return heat_path_get_vertex(path, sz-1);
    229 }
    230 
    231 static INLINE res_T
    232 heat_path_add_break(struct sdis_heat_path* path)
    233 {
    234   size_t id;
    235   size_t sz;
    236   ASSERT(path);
    237   sz = darray_heat_vertex_size_get(&path->vertices);
    238   if(sz == 0) return RES_OK; /* Nothing to do */
    239   id = sz-1;
    240   return darray_size_t_push_back(&path->breaks, &id);
    241 }
    242 
    243 static INLINE res_T
    244 heat_path_restart
    245   (struct sdis_heat_path* path,
    246    const struct sdis_heat_vertex* vtx) /* Vertex to restart from */
    247 {
    248   size_t nverts = 0;
    249   size_t nbreaks = 0;
    250   res_T res = RES_OK;
    251 
    252   if(!path) goto exit;
    253   ASSERT(vtx);
    254 
    255   nbreaks = darray_size_t_size_get(&path->breaks);
    256   nverts = darray_heat_vertex_size_get(&path->vertices);
    257 
    258   res = heat_path_add_break(path);
    259   if(res != RES_OK) goto error;
    260   res = heat_path_add_vertex(path, vtx);
    261   if(res != RES_OK) goto error;
    262 
    263 exit:
    264   return res;
    265 error:
    266   CHK(darray_size_t_resize(&path->breaks, nbreaks) == RES_OK);
    267   CHK(darray_heat_vertex_resize(&path->vertices, nverts) == RES_OK);
    268   goto exit;
    269 }
    270 
    271 static INLINE void
    272 heat_path_increment_sub_path_branch_id
    273   (struct sdis_heat_path* path,
    274    const size_t ivtx_begin,
    275    const size_t ivtx_end)
    276 {
    277   size_t ivtx;
    278   FOR_EACH(ivtx, ivtx_begin, ivtx_end) {
    279     struct sdis_heat_vertex* vtx = heat_path_get_vertex(path, ivtx);
    280     vtx->branch_id += 1;
    281   }
    282 }
    283 
    284 /* Generate the dynamic array of heat paths */
    285 #define DARRAY_NAME heat_path
    286 #define DARRAY_DATA struct sdis_heat_path
    287 #define DARRAY_FUNCTOR_INIT heat_path_init
    288 #define DARRAY_FUNCTOR_RELEASE heat_path_release
    289 #define DARRAY_FUNCTOR_COPY heat_path_copy
    290 #define DARRAY_FUNCTOR_COPY_AND_RELEASE heat_path_copy_and_release
    291 #include <rsys/dynamic_array.h>
    292 
    293 /*******************************************************************************
    294  * Trace or pursue a radiative path
    295  ******************************************************************************/
    296 extern LOCAL_SYM res_T
    297 trace_radiative_path_2d
    298   (struct sdis_scene* scn,
    299    const float ray_dir[3],
    300    struct rwalk_context* ctx,
    301    struct rwalk* rwalk,
    302    struct ssp_rng* rng,
    303    struct temperature* temperature);
    304 
    305 extern LOCAL_SYM res_T
    306 trace_radiative_path_3d
    307   (struct sdis_scene* scn,
    308    const float ray_dir[3],
    309    struct rwalk_context* ctx,
    310    struct rwalk* rwalk,
    311    struct ssp_rng* rng,
    312    struct temperature* temperature);
    313 
    314 extern LOCAL_SYM res_T
    315 radiative_path_2d
    316   (struct sdis_scene* scn,
    317    struct rwalk_context* ctx,
    318    struct rwalk* rwalk,
    319    struct ssp_rng* rng,
    320    struct temperature* temperature);
    321 
    322 extern LOCAL_SYM res_T
    323 radiative_path_3d
    324   (struct sdis_scene* scn,
    325    struct rwalk_context* ctx,
    326    struct rwalk* rwalk,
    327    struct ssp_rng* rng,
    328    struct temperature* temperature);
    329 
    330 extern LOCAL_SYM void
    331 trace_ray_2d
    332   (struct sdis_scene* scn,
    333    const double pos[2],
    334    const double dir[3], /* Always in 3D */
    335    const double distance,
    336    const unsigned enc_id,
    337    const struct s2d_hit* hit_from,
    338    struct s2d_hit* hit);
    339 
    340 extern LOCAL_SYM void
    341 trace_ray_3d
    342   (struct sdis_scene* scn,
    343    const double pos[3],
    344    const double dir[3], /* Always in 3D */
    345    const double distance,
    346    const unsigned enc_id,
    347    const struct s3d_hit* hit_from,
    348    struct s3d_hit* hit);
    349 
    350 /* Trace a ray and setup the fragment at the intersection found, if any. */
    351 extern LOCAL_SYM res_T
    352 find_next_fragment_2d
    353   (struct sdis_scene* scn,
    354    const double in_pos[2],
    355    const double in_dir[3], /* Always in 3D */
    356    const struct s2d_hit* in_hit,
    357    const double time,
    358    const unsigned enc_id,
    359    struct s2d_hit* out_hit,
    360    struct sdis_interface** out_interf,
    361    struct sdis_interface_fragment* out_frag);
    362 
    363 extern LOCAL_SYM res_T
    364 find_next_fragment_3d
    365   (struct sdis_scene* scn,
    366    const double in_pos[3],
    367    const double in_dir[3], /* Always in 3D */
    368    const struct s3d_hit* in_hit,
    369    const double time,
    370    const unsigned enc_id,
    371    struct s3d_hit* out_hit,
    372    struct sdis_interface** out_interf,
    373    struct sdis_interface_fragment* out_frag);
    374 
    375 /*******************************************************************************
    376  * Convective path
    377  ******************************************************************************/
    378 extern LOCAL_SYM res_T
    379 convective_path_2d
    380   (struct sdis_scene* scn,
    381    struct rwalk_context* ctx,
    382    struct rwalk* rwalk,
    383    struct ssp_rng* rng,
    384    struct temperature* temperature);
    385 
    386 extern LOCAL_SYM res_T
    387 convective_path_3d
    388   (struct sdis_scene* scn,
    389    struct rwalk_context* ctx,
    390    struct rwalk* rwalk,
    391    struct ssp_rng* rng,
    392    struct temperature* temperature);
    393 
    394 /*******************************************************************************
    395  * Conductive path
    396  ******************************************************************************/
    397 extern LOCAL_SYM res_T
    398 conductive_path_2d
    399   (struct sdis_scene* scn,
    400    struct rwalk_context* ctx,
    401    struct rwalk* rwalk,
    402    struct ssp_rng* rng,
    403    struct temperature* temperature);
    404 
    405 extern LOCAL_SYM res_T
    406 conductive_path_3d
    407   (struct sdis_scene* scn,
    408    struct rwalk_context* ctx,
    409    struct rwalk* rwalk,
    410    struct ssp_rng* rng,
    411    struct temperature* temperature);
    412 
    413 /*******************************************************************************
    414  * Boundary sub-path
    415  ******************************************************************************/
    416 extern LOCAL_SYM res_T
    417 boundary_path_2d
    418   (struct sdis_scene* scn,
    419    struct rwalk_context* ctx,
    420    struct rwalk* rwalk,
    421    struct ssp_rng* rng,
    422    struct temperature* temperature);
    423 
    424 extern LOCAL_SYM res_T
    425 boundary_path_3d
    426   (struct sdis_scene* scn,
    427    struct rwalk_context* ctx,
    428    struct rwalk* rwalk,
    429    struct ssp_rng* rng,
    430    struct temperature* temperature);
    431 
    432 #endif /* SDIS_HEAT_PATH_H */