stardis-solver

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

commit a649c1fed2755d6f1cf2bfa0bd55cfd3005e4b9c
parent 2d58ad072e3323e67cd98c8a0971dad05ab00951
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon,  3 Jun 2024 19:58:02 +0200

Allow radiative path in enclosures with multiple media

Until recently, the sampled path kept track of the current medium. This
led to an error when we tried to retrieve the medium of an enclosure
that had more than one. This made it impossible, for example, to compute
the infrared image of a scene using several fluid media to define Robin
boundary conditions varying by surface. Since the ebe4a68 commit, the
path now records the enclosure in which it evolves, which is a
purely geometric data. Checking the coherence of the radiative path is
now done in relation to the current enclosure. Obtaining the medium
becomes unnecessary, and the above-mentioned error disappears.

In any case, we always check that the radiative path is sampled in the
right type of medium, i.e. fluids. But now we do this once the ray
intersects an interface, rather than from its starting position; we
check that the side of the intersecting surface points towards a fluid.
If it doesn't, it's an irrecoverable error caused by the user trying to
sample a radiative path in a solid.

Diffstat:
Msrc/sdis_heat_path_radiative_Xd.h | 22+++++++++++++++++++++-
Msrc/sdis_realisation.c | 23++++++++---------------
Msrc/sdis_solve_camera.c | 11-----------
3 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/src/sdis_heat_path_radiative_Xd.h b/src/sdis_heat_path_radiative_Xd.h @@ -56,6 +56,7 @@ XD(trace_radiative_path) /* Launch the radiative random walk */ for(;;) { const struct sdis_interface* interf = NULL; + struct sdis_medium* chk_mdm = NULL; struct hit_filter_data filter_data = HIT_FILTER_DATA_NULL; struct sdis_interface_fragment frag = SDIS_INTERFACE_FRAGMENT_NULL; unsigned enc_ids[2] = {ENCLOSURE_ID_NULL, ENCLOSURE_ID_NULL}; @@ -169,7 +170,6 @@ XD(trace_radiative_path) /* Check that the radiative path still lies in the same enclosure */ scene_get_enclosure_ids(scn, rwalk->XD(hit).prim.prim_id, enc_ids); chk_enc_id = rwalk->hit_side == SDIS_FRONT ? enc_ids[0] : enc_ids[1]; - if(chk_enc_id != rwalk->enc_id) { log_warn(scn->dev, "%s: the radiative path has escaped from its cavity -- pos=(%g, %g, %g)\n", @@ -178,6 +178,26 @@ XD(trace_radiative_path) goto error; } + /* Verify that the intersection, although in the same enclosure, touches the + * interface of a fluid. We verify this by interface, since a radiative path + * can be traced in an enclosure containing several media used to describe a + * set of boundary conditions. + * + * If the enclosure is good but the media type is not, this means that the + * radiative path is sampled in the wrong media. This is not a numerical + * problem, but a user problem: trying to sample a radiative path in a solid + * when semi-transparent solids are not yet supported by Stardis. This error + * is therefore fatal for the calculation */ + chk_mdm = rwalk->hit_side == SDIS_FRONT + ? interf->medium_front : interf->medium_back; + if(sdis_medium_get_type(chk_mdm)) { + log_err(scn->dev, + "%s: a radiative path cannot evolve in a solid -- pos=(%g, %g, %g)\n", + FUNC_NAME, SPLIT3(rwalk->vtx.P)); + res = RES_BAD_OP_IRRECOVERABLE; + goto error; + } + alpha = interface_side_get_specular_fraction(interf, SDIS_INTERN_SOURCE_ID, &frag); r = ssp_rng_canonical(rng); if(r < alpha) { /* Sample specular part */ diff --git a/src/sdis_realisation.c b/src/sdis_realisation.c @@ -20,15 +20,8 @@ * Helper functions ******************************************************************************/ static INLINE res_T -check_ray_realisation_args - (struct sdis_scene* scn, - const struct ray_realisation_args* args) +check_ray_realisation_args(const struct ray_realisation_args* args) { - const struct enclosure* enc = NULL; - struct sdis_medium* mdm = NULL; - res_T res = RES_OK; - ASSERT(scn); - /* Check pointers */ if(!args || !args->rng) return RES_BAD_ARG; @@ -39,15 +32,15 @@ check_ray_realisation_args return RES_BAD_ARG; } - /* Check the enclosure id */ + /* Check the enclosure identifier. Only its validity is checked, not the fact + * that the enclosure is a fluid. Even though Stardis doesn't allow you to + * sample a radiative path in a solid, we don't query the medium of the + * enclosure since it may contain several: querying the medium will therefore + * return an error. The type of medium is checked later, when sampling the + * radiative path, when it reaches an interface whose medium must be a fluid*/ if(args->enc_id == ENCLOSURE_ID_NULL) { return RES_BAD_ARG; } - enc = scene_get_enclosure(scn, args->enc_id); - if((res = scene_get_enclosure_medium(scn, enc, &mdm)) != RES_OK) return res; - if(sdis_medium_get_type(mdm) != SDIS_FLUID) { - return RES_BAD_ARG; - } return RES_OK; } @@ -72,7 +65,7 @@ ray_realisation_3d struct temperature T = TEMPERATURE_NULL; float dir[3]; res_T res = RES_OK; - ASSERT(scn && weight && check_ray_realisation_args(scn, args) == RES_OK); + ASSERT(scn && weight && check_ray_realisation_args(args) == RES_OK); d3_set(rwalk.vtx.P, args->position); rwalk.vtx.time = args->time; diff --git a/src/sdis_solve_camera.c b/src/sdis_solve_camera.c @@ -510,7 +510,6 @@ sdis_solve_camera struct ssp_rng** per_thread_rng = NULL; /* Enclosure & medium in which the probe lies */ - struct sdis_medium* mdm = NULL; unsigned enc_id = ENCLOSURE_ID_NULL; /* Miscellaneous */ @@ -542,16 +541,6 @@ sdis_solve_camera /* Retrieve the medium in which the submitted position lies */ res = scene_get_enclosure_id(scn, args->cam->position, &enc_id); if(res != RES_OK) goto error; - res = scene_get_enclosure_medium(scn, scene_get_enclosure(scn, enc_id), &mdm); - if(res != RES_OK) goto error; - - if(sdis_medium_get_type(mdm) != SDIS_FLUID) { - log_err(scn->dev, - "%s: the camera position (%g, %g, %g) must be in a fluid medium.\n", - FUNC_NAME, SPLIT3(args->cam->position)); - res = RES_BAD_ARG; - goto error; - } /* Create the per thread RNGs */ res = create_per_thread_rng