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