stardis-solver

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

commit ccb1e120f3bf9f8fe18f6101500180a3c0c8c372
parent 786d3d74ec2776d8b25eef8e52f21294908091ba
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 20 Jun 2024 18:18:24 +0200

Refactoring of conductive path custom sampling

Move the code of the conductive_path function to a new
conductive_path_custom function, which has become the third way of
sampling a conductive path after the conductive_path_delta_sphere and
conductive_path_wos functions. This standardizes the code between the
three sampling procedures, each of which has its own function.

Check the validity of the path returned by the custom sampling function.
Make sure that the path reaches a boundary condition or that the
intersected boundary is valid.

Finally, fix some issues when updating the random walk from the
sampled path. The enclosure ID was not reset when required, and the side
of the intersecting boundary was not correctly defined.

Diffstat:
Msrc/sdis_heat_path_conductive_Xd.h | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 127 insertions(+), 22 deletions(-)

diff --git a/src/sdis_heat_path_conductive_Xd.h b/src/sdis_heat_path_conductive_Xd.h @@ -25,6 +25,127 @@ #include "sdis_Xd_begin.h" /******************************************************************************* + * Helper function + ******************************************************************************/ +static res_T +XD(check_sampled_path) + (struct sdis_scene* scn, + const struct sdis_path* path) +{ + const struct sXd(hit)* hit = NULL; + res_T res = RES_OK; + ASSERT(scn && path); + + hit = &path->XD(hit); + + /* Check end of path */ + if(!path->at_limit && SXD_HIT_NONE(hit)) { + log_err(scn->dev, + "%s: the sampled path should have reached a limit condition or a boundary" + " -- pos=("FORMAT_VECX")\n", + FUNC_NAME, SPLITX(path->vtx.P)); + res = RES_BAD_ARG; + goto error; + } + + if(!SXD_HIT_NONE(&path->XD(hit))) { + struct sXd(attrib) attr; + struct sXd(primitive) prim; + const unsigned iprim = hit->prim.prim_id; + float N[3] = {0,0,0}; + + /* Check intersected primitive */ + res = sXd(scene_view_get_primitive)(scn->sXd(view), iprim, &prim); + if(res != RES_OK) { + log_err(scn->dev, + "%s: invalid intersected primitive on sampled path -- %s\n", + FUNC_NAME, res_to_cstr(res)); + goto error; + } + + /* Check normal */ +#if DIM == 2 + SXD(primitive_get_attrib(&prim, SXD_GEOMETRY_NORMAL, hit->u, &attr)); +#else + SXD(primitive_get_attrib(&prim, SXD_GEOMETRY_NORMAL, hit->uv, &attr)); +#endif + fX(normalize)(attr.value, attr.value); + fX(normalize)(N, hit->normal); + if(!fX(eq)(attr.value, N)) { + log_err(scn->dev, + "%s: invalid normal on the intersected primitive\n", + FUNC_NAME); + res = RES_BAD_ARG; + goto error; + } + } + +exit: + return res; +error: + goto exit; +} + +static res_T +XD(conductive_path_custom) + (struct sdis_scene* scn, + const unsigned enc_id, + const struct sdis_medium* mdm, + struct rwalk* rwalk, + struct ssp_rng* rng, + struct temperature* T) +{ + struct sdis_path path = SDIS_PATH_NULL; + res_T res = RES_OK; + ASSERT(scn && rwalk && rng && T); + + /* Sample a conductive path */ + path.vtx = rwalk->vtx; + res = mdm->shader.solid.sample_path(scn, rng, &path, mdm->data); + if(res != RES_OK) { + log_err(scn->dev, + "%s: error in customized sampling of a conductive path " + "from pos=("FORMAT_VECX") -- %s\n", + FUNC_NAME, SPLITX(rwalk->vtx.P), res_to_cstr(res)); + goto error; + } + + res = XD(check_sampled_path)(scn, &path); + if(res != RES_OK) goto error; + + /* Update random walk position and time from sampled path */ + rwalk->vtx = path.vtx; + rwalk->XD(hit) = path.XD(hit); + rwalk->elapsed_time += path.elapsed_time; + + /* The path reached a boundary */ + if(!SXD_HIT_NONE(&rwalk->XD(hit))) { + unsigned enc_ids[2] = {ENCLOSURE_ID_NULL, ENCLOSURE_ID_NULL}; + + rwalk->enc_id = ENCLOSURE_ID_NULL; /* Not in an enclosure */ + + /* Define which side of the interface the path is on */ + scene_get_enclosure_ids(scn, rwalk->XD(hit).prim.prim_id, enc_ids); + if(enc_id == enc_ids[SDIS_FRONT]) rwalk->hit_side = SDIS_FRONT; + else if(enc_id == enc_ids[SDIS_BACK]) rwalk->hit_side = SDIS_BACK; + else FATAL("Unreachable code.\n"); + } + + /* Update Monte Carlo weight */ + T->value += path.weight; + T->done = path.at_limit; + + /* The path either reaches a boundary condition and will be stopped, or is + * on a boundary and a boundary path must be sampled */ + T->func = XD(boundary_path); + +exit: + return res; +error: + goto exit; +} + +/******************************************************************************* * Local functions ******************************************************************************/ res_T @@ -46,7 +167,12 @@ XD(conductive_path) if(res != RES_OK) goto error; ASSERT(sdis_medium_get_type(mdm) == SDIS_SOLID); - if(mdm->shader.solid.sample_path == NULL) { + /* The caller defined a custom function to sample the solid path */ + if(mdm->shader.solid.sample_path != NULL) { + res = XD(conductive_path_custom)(scn, enc_id, mdm, rwalk, rng, T); + if(res != RES_OK) goto error; + + } else { switch(ctx->diff_algo) { case SDIS_DIFFUSION_DELTA_SPHERE: res = XD(conductive_path_delta_sphere)(scn, ctx, rwalk, rng, T); @@ -57,27 +183,6 @@ XD(conductive_path) default: FATAL("Unreachable code.\n"); break; } if(res != RES_OK) goto error; - - /* The caller defined a custom function to sample the solid path */ - } else { - struct sdis_path path = SDIS_PATH_NULL; - path.vtx = rwalk->vtx; - res = mdm->shader.solid.sample_path(scn, rng, &path, mdm->data); - - if(res != RES_OK) { - log_err(scn->dev, - "%s: error in customized sampling of a conductive path " - "from pos=("FORMAT_VECX") -- %s\n", - FUNC_NAME, SPLITX(rwalk->vtx.P), res_to_cstr(res)); - goto error; - } - - /* Update the Monte Carlo realisation from the returned sampled path */ - rwalk->vtx = path.vtx; - rwalk->XD(hit) = path.XD(hit); - rwalk->elapsed_time += path.elapsed_time; - T->value += path.weight; - T->done = path.at_limit; } exit: