stardis-solver

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

commit b7e3fba6d3d04c3eb4813876ced3822ef070a409
parent fd4595ca75d2c0e06d52244f7900e015fcaf2c20
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 21 Oct 2021 15:16:10 +0200

Rewrite of the heat_path_boundary routines

Add the generic functions sample_reinjection_step_solid_<fluid|solid>
and solid_reinjection that factorise the sampling of a reinjection step,
and the reinjection step itself.

Diffstat:
Mcmake/CMakeLists.txt | 2+-
Msrc/sdis.h | 5++++-
Msrc/sdis_Xd_begin.h | 14+++++++++++++-
Msrc/sdis_device.c | 4++--
Msrc/sdis_green.c | 55+++++--------------------------------------------------
Msrc/sdis_heat_path_boundary_Xd_c.h | 394++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/sdis_heat_path_boundary_Xd_fixed_flux.h | 154+++++++++++++++++++++++++++----------------------------------------------------
Msrc/sdis_heat_path_boundary_Xd_solid_fluid.h | 210++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/sdis_heat_path_boundary_Xd_solid_solid.h | 215+++++++++++++++++++++++++++++--------------------------------------------------
Msrc/sdis_heat_path_boundary_c.h | 164+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/sdis_interface_c.h | 16++++++++++++++++
Msrc/sdis_solve.c | 2+-
Msrc/sdis_solve_boundary_Xd.h | 4++--
Msrc/sdis_solve_medium_Xd.h | 4++--
Msrc/sdis_solve_probe_Xd.h | 2+-
Msrc/sdis_solve_probe_boundary_Xd.h | 4++--
Msrc/test_sdis_conducto_radiative.c | 2+-
Msrc/test_sdis_conducto_radiative_2d.c | 2+-
Msrc/test_sdis_contact_resistance.c | 2+-
Msrc/test_sdis_contact_resistance_2.c | 2+-
Msrc/test_sdis_flux.c | 2+-
Msrc/test_sdis_solve_probe.c | 2+-
Msrc/test_sdis_unstationary_atm.c | 2+-
Msrc/test_sdis_utils.h | 41+++++++++++++++++++++--------------------
Msrc/test_sdis_volumic_power.c | 2+-
25 files changed, 759 insertions(+), 547 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -31,7 +31,7 @@ CMAKE_DEPENDENT_OPTION(ALL_TESTS find_package(RCMake 0.4 REQUIRED) find_package(Star2D 0.5 REQUIRED) find_package(Star3D 0.8 REQUIRED) -find_package(StarSP 0.8 REQUIRED) +find_package(StarSP 0.12 REQUIRED) find_package(StarEnc2D 0.5 REQUIRED) find_package(StarEnc3D 0.5 REQUIRED) find_package(RSys 0.12 REQUIRED) diff --git a/src/sdis.h b/src/sdis.h @@ -207,8 +207,11 @@ struct sdis_interface_side_shader { * interface or if the emissivity is 0 onto the whole interface. */ sdis_interface_getter_T emissivity; /* Overall emissivity. */ sdis_interface_getter_T specular_fraction; /* Specular part in [0,1] */ + + /* Reference temperature used in Picard 1 */ + sdis_interface_getter_T reference_temperature; }; -#define SDIS_INTERFACE_SIDE_SHADER_NULL__ { NULL, NULL, NULL, NULL } +#define SDIS_INTERFACE_SIDE_SHADER_NULL__ { NULL, NULL, NULL, NULL, NULL } static const struct sdis_interface_side_shader SDIS_INTERFACE_SIDE_SHADER_NULL = SDIS_INTERFACE_SIDE_SHADER_NULL__; diff --git a/src/sdis_Xd_begin.h b/src/sdis_Xd_begin.h @@ -27,8 +27,20 @@ struct rwalk_context { struct sdis_heat_path* heat_path; double Tarad; /* Ambient radiative temperature */ double Tref3; /* Reference temperature ^ 3 */ + + double That; /* Upper bound temperature */ + double That2; /* That^2 */ + double That3; /* That^3 */ }; -#define RWALK_CONTEXT_NULL__ {NULL, NULL, 0, 0} +#define RWALK_CONTEXT_NULL__ { \ + NULL, /* Green path */ \ + NULL, /* Heat path */ \ + 0, /* Ambient radiative temperature */ \ + 0, /* (Reference temperature)^3 */ \ + 0, /* Temperature upper bound */ \ + 0, /* (Temperature upper bound)^2 */ \ + 0 /* (Temperature upper bound)^3 */ \ +} static const struct rwalk_context RWALK_CONTEXT_NULL = RWALK_CONTEXT_NULL__; #endif /* SDIS_XD_BEGIN_H */ diff --git a/src/sdis_device.c b/src/sdis_device.c @@ -148,7 +148,7 @@ create_rng_from_rng_proxy const struct ssp_rng_proxy* proxy, struct ssp_rng** out_rng) { - struct ssp_rng_type rng_type; + enum ssp_rng_type rng_type; struct ssp_rng* rng = NULL; FILE* stream = NULL; res_T res = RES_OK; @@ -163,7 +163,7 @@ create_rng_from_rng_proxy } SSP(rng_proxy_get_type(proxy, &rng_type)); - res = ssp_rng_create(dev->allocator, &rng_type, &rng); + res = ssp_rng_create(dev->allocator, rng_type, &rng); if(res != RES_OK) { log_err(dev, "Could not create the RNG -- %s\n", res_to_cstr(res)); goto error; diff --git a/src/sdis_green.c b/src/sdis_green.c @@ -303,7 +303,7 @@ struct sdis_green_function { struct accum realisation_time; /* Time per realisation */ - struct ssp_rng_type rng_type; + enum ssp_rng_type rng_type; FILE* rng_state; ref_T ref; @@ -313,38 +313,6 @@ struct sdis_green_function { /******************************************************************************* * Helper functions ******************************************************************************/ -enum rng_type { - RNG_KISS, - RNG_MT_19937_64, - RNG_RANLUX48, - RNG_THREEFRY, - RNG_UNKNOWN -}; - -static INLINE enum rng_type -get_rng_type_enum(const struct ssp_rng_type* type) -{ - ASSERT(type); - if(ssp_rng_type_eq(type, &ssp_rng_kiss)) return RNG_KISS; - if(ssp_rng_type_eq(type, &ssp_rng_mt19937_64)) return RNG_MT_19937_64; - if(ssp_rng_type_eq(type, &ssp_rng_ranlux48)) return RNG_RANLUX48; - if(ssp_rng_type_eq(type, &ssp_rng_threefry)) return RNG_THREEFRY; - return RNG_UNKNOWN; -} - -static INLINE void -get_rng_type_ssp(const enum rng_type type, struct ssp_rng_type* ssp_type) -{ - switch(type) { - case RNG_KISS: *ssp_type = ssp_rng_kiss; break; - case RNG_MT_19937_64: *ssp_type = ssp_rng_mt19937_64; break; - case RNG_RANLUX48: *ssp_type = ssp_rng_ranlux48; break; - case RNG_THREEFRY: *ssp_type = ssp_rng_threefry; break; - case RNG_UNKNOWN: memset(ssp_type, 0, sizeof(*ssp_type)); break; - default: FATAL("Unreachable code.\n"); break; - } -} - static res_T ensure_medium_registration (struct sdis_green_function* green, @@ -894,7 +862,6 @@ res_T sdis_green_function_write(struct sdis_green_function* green, FILE* stream) { struct ssp_rng* rng = NULL; - enum rng_type rng_type = RNG_UNKNOWN; hash256_T hash; res_T res = RES_OK; @@ -910,15 +877,6 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) } \ } (void)0 - rng_type = get_rng_type_enum(&green->rng_type); - if(rng_type == RNG_UNKNOWN) { - log_err(green->scn->dev, - "%s: could not function a green function with an unknown RNG type.\n", - FUNC_NAME); - res = RES_BAD_ARG; - goto error; - } - WRITE(&SDIS_GREEN_FUNCTION_VERSION, 1); res = scene_compute_hash(green->scn, hash); @@ -935,11 +893,11 @@ sdis_green_function_write(struct sdis_green_function* green, FILE* stream) WRITE(&green->npaths_valid, 1); WRITE(&green->npaths_invalid, 1); WRITE(&green->realisation_time, 1); - WRITE(&rng_type, 1); + WRITE(&green->rng_type, 1); #undef WRITE /* Create a temporary RNG used to serialise the RNG state */ - res = ssp_rng_create(green->scn->dev->allocator, &green->rng_type, &rng); + res = ssp_rng_create(green->scn->dev->allocator, green->rng_type, &rng); if(res != RES_OK) goto error; rewind(green->rng_state); res = ssp_rng_read(rng, green->rng_state); @@ -963,7 +921,6 @@ sdis_green_function_create_from_stream hash256_T hash0, hash1; struct sdis_green_function* green = NULL; struct ssp_rng* rng = NULL; - enum rng_type rng_type = RNG_UNKNOWN; int version = 0; res_T res = RES_OK; @@ -1020,13 +977,11 @@ sdis_green_function_create_from_stream READ(&green->npaths_valid, 1); READ(&green->npaths_invalid, 1); READ(&green->realisation_time, 1); - READ(&rng_type, 1); + READ(&green->rng_type, 1); #undef READ - get_rng_type_ssp(rng_type, &green->rng_type); - /* Create a temporary RNG used to deserialise the RNG state */ - res = ssp_rng_create(green->scn->dev->allocator, &green->rng_type, &rng); + res = ssp_rng_create(green->scn->dev->allocator, green->rng_type, &rng); if(res != RES_OK) goto error; res = ssp_rng_read(rng, stream); if(res != RES_OK) goto error; diff --git a/src/sdis_heat_path_boundary_Xd_c.h b/src/sdis_heat_path_boundary_Xd_c.h @@ -13,6 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "sdis_green.h" #include "sdis_heat_path_boundary_c.h" #include "sdis_interface_c.h" #include "sdis_log.h" @@ -27,9 +28,70 @@ /******************************************************************************* * Helper functions ******************************************************************************/ -static INLINE void +static INLINE int +XD(check_sample_reinjection_step_args) + (const struct XD(sample_reinjection_step_args)* args) +{ + return args + && args->rng + && args->solid + && args->solid->type == SDIS_SOLID + && args->rwalk + && args->distance > 0 + && (unsigned)args->side < SDIS_SIDE_NULL__; +} + +static INLINE int +XD(check_reinjection_step)(const struct XD(reinjection_step)* step) +{ + return step + && fX(is_normalized)(step->direction) + && step->distance > 0; +} + +static INLINE int +XD(check_solid_reinjection_args)(const struct XD(solid_reinjection_args)* args) +{ + return args + && XD(check_reinjection_step)(args->reinjection) + && args->rng + && args->rwalk + && args->rwalk_ctx + && args->T + && args->fp_to_meter > 0; +} + +/* Check that the interface fragment is consistent with the current state of + * the random walk */ +static INLINE int +XD(check_rwalk_fragment_consistency) + (const struct XD(rwalk)* rwalk, + const struct sdis_interface_fragment* frag) +{ + double N[DIM]; + double uv[2] = {0, 0}; + ASSERT(rwalk && frag); + dX(normalize)(N, dX_set_fX(N, rwalk->hit.normal)); + if( SXD_HIT_NONE(&rwalk->hit) + || !dX(eq_eps)(rwalk->vtx.P, frag->P, 1.e-6) + || !dX(eq_eps)(N, frag->Ng, 1.e-6) + || !( (IS_INF(rwalk->vtx.time) && IS_INF(frag->time)) + || eq_eps(rwalk->vtx.time, frag->time, 1.e-6))) { + return 0; + } +#if (SDIS_XD_DIMENSION == 2) + uv[0] = rwalk->hit.u; +#else + d2_set_f2(uv, rwalk->hit.uv); +#endif + return d2_eq_eps(uv, frag->uv, 1.e-6); +} + +static void XD(sample_reinjection_dir) - (const struct XD(rwalk)* rwalk, struct ssp_rng* rng, float dir[DIM]) + (const struct XD(rwalk)* rwalk, + struct ssp_rng* rng, + float dir[DIM]) { #if DIM == 2 /* The sampled directions is defined by rotating the normal around the Z axis @@ -43,7 +105,10 @@ XD(sample_reinjection_dir) * Note that since the sampled direction is finally normalized, we can * discard the sqrt(2)/2 constant. */ const uint64_t r = ssp_rng_uniform_uint64(rng, 0, 1); - ASSERT(rwalk && dir); + ASSERT(rwalk && rng && dir); + ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!rwalk->mdm); + if(r) { dir[0] = rwalk->hit.normal[0] - rwalk->hit.normal[1]; dir[1] = rwalk->hit.normal[0] + rwalk->hit.normal[1]; @@ -57,6 +122,9 @@ XD(sample_reinjection_dir) * do so we sample a position onto a cone whose height is 1/sqrt(2) and the * radius of its base is 1. */ float frame[9]; + ASSERT(rwalk && rng && dir); + ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!rwalk->mdm); ASSERT(fX(is_normalized)(rwalk->hit.normal)); ssp_ran_circle_uniform_float(rng, dir, NULL); @@ -69,6 +137,7 @@ XD(sample_reinjection_dir) #endif } + #if DIM == 2 static void XD(move_away_primitive_boundaries) @@ -190,10 +259,7 @@ XD(move_away_primitive_boundaries) } #endif -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T +static res_T XD(select_reinjection_dir) (const struct sdis_scene* scn, const struct sdis_medium* mdm, /* Medium into which the reinjection occurs */ @@ -220,6 +286,7 @@ XD(select_reinjection_dir) struct sXd(hit) hit; struct sXd(hit) hit0; struct sXd(hit) hit1; + double rwalk_pos_backup[DIM]; double tmp[DIM]; double dst; double dst0; @@ -236,6 +303,9 @@ XD(select_reinjection_dir) ASSERT(scn && mdm && rwalk && dir0 && dir1 && delta > 0); ASSERT(reinject_dir && reinject_dst && reinject_hit); + /* Save the submitted position to restore it if an error occurs */ + dX(set)(rwalk_pos_backup, rwalk->vtx.P); + if(move_pos) *move_pos = 0; do { @@ -291,7 +361,7 @@ XD(select_reinjection_dir) /* No valid reinjection. Maybe the random walk is near a sharp corner and * thus the ray-tracing misses the enclosure geometry. Another possibility * is that the random walk lies roughly on an edge. In this case, sampled - * reinjecton dirs can intersect the primitive on the other side of the + * reinjection dirs can intersect the primitive on the other side of the * edge. Normally, this primitive should be filtered by the "hit_filter" * function but this may be not the case due to a "threshold effect". In * both situations, try to slightly move away from the primitive boundaries @@ -376,10 +446,11 @@ XD(select_reinjection_dir) exit: return res; error: + dX(set)(rwalk->vtx.P, rwalk_pos_backup); /* Restore the rwalk position */ goto exit; } -res_T +static res_T XD(select_reinjection_dir_and_check_validity) (const struct sdis_scene* scn, const struct sdis_medium* mdm, /* Medium into which the reinjection occurs */ @@ -432,30 +503,291 @@ error: goto exit; } -/* Check that the interface fragment is consistent with the current state of - * the random walk */ -int -XD(check_rwalk_fragment_consistency) - (const struct XD(rwalk)* rwalk, - const struct sdis_interface_fragment* frag) +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +XD(sample_reinjection_step_solid_fluid) + (const struct sdis_scene* scn, + const struct XD(sample_reinjection_step_args)* args, + struct XD(reinjection_step)* step) { - double N[DIM]; - double uv[2] = {0, 0}; - ASSERT(rwalk && frag); - dX(normalize)(N, dX_set_fX(N, rwalk->hit.normal)); - if( SXD_HIT_NONE(&rwalk->hit) - || !dX(eq_eps)(rwalk->vtx.P, frag->P, 1.e-6) - || !dX(eq_eps)(N, frag->Ng, 1.e-6) - || !( (IS_INF(rwalk->vtx.time) && IS_INF(frag->time)) - || eq_eps(rwalk->vtx.time, frag->time, 1.e-6))) { - return 0; + /* In 2D it is useless to try to resample a reinjection direction since there + * is only one possible direction */ + const int MAX_ATTEMPTS = DIM == 2 ? 1 : 10; + + /* Control if the position of the random walk can be slightly move to handle + * numerical uncertainty */ + const int RWALK_POS_CAN_BE_UPDATED = 1; + + /* Miscellaneous variables */ + float dir0[DIM]; /* Sampled direction */ + float dir1[DIM]; /* Sampled direction reflected */ + int reinjection_is_valid = 0; /* Can reinjection be performed */ + int iattempt = 0; /* #attempts to find a reinjection dir */ + res_T res = RES_OK; + + /* Pre-conditions */ + ASSERT(scn && args && step); + ASSERT(XD(check_sample_reinjection_step_args)(args)); + + reinjection_is_valid = 0; + iattempt = 0; + do { + /* Sample a reinjection direction */ + XD(sample_reinjection_dir)(args->rwalk, args->rng, dir0); + + /* Reflect the sampled direction around the normal */ + XD(reflect)(dir1, dir0, args->rwalk->hit.normal); + + /* Flip the sampled directions if one wants to reinject to back side */ + if(args->side == SDIS_BACK) { + fX(minus)(dir0, dir0); + fX(minus)(dir1, dir1); + } + + /* Find the reinjection step */ + res = XD(select_reinjection_dir_and_check_validity) + (scn, + args->solid, + args->rwalk, + dir0, + dir1, + args->distance, + step->direction, + &step->distance, + RWALK_POS_CAN_BE_UPDATED, + NULL, + &reinjection_is_valid, + &step->hit); + if(res != RES_OK) goto error; + + } while(!reinjection_is_valid && ++iattempt < MAX_ATTEMPTS); + + /* Could not find a valid reinjecton step */ + if(iattempt >= MAX_ATTEMPTS) { + log_warn(scn->dev, + "%s: could not find a valid reinjection step at `%g %g %g'.\n", + FUNC_NAME, SPLIT3(args->rwalk->vtx.P)); + res = RES_BAD_OP_IRRECOVERABLE; + goto error; } -#if (SDIS_XD_DIMENSION == 2) - uv[0] = rwalk->hit.u; -#else - d2_set_f2(uv, rwalk->hit.uv); -#endif - return d2_eq_eps(uv, frag->uv, 1.e-6); + + /* Post-conditions */ + ASSERT(XD(check_reinjection_step)(step)); + +exit: + return res; +error: + goto exit; +} + +res_T +XD(sample_reinjection_step_solid_solid) + (const struct sdis_scene* scn, + const struct XD(sample_reinjection_step_args)* args_front, + const struct XD(sample_reinjection_step_args)* args_back, + struct XD(reinjection_step)* step_front, + struct XD(reinjection_step)* step_back) +{ + /* Initial random walk position used as a backup */ + double rwalk_pos_backup[DIM]; + + /* Input arguments shared by the 2 sides of the boundary */ + struct XD(rwalk)* rwalk = NULL; + struct ssp_rng* rng = NULL; + + /* In 2D it is useless to try to resample a reinjection direction since there + * is only one possible direction */ + const int MAX_ATTEMPTS = DIM == 2 ? 1 : 10; + + float dir_front_samp[DIM]; /* Sampled direction */ + float dir_front_refl[DIM]; /* Sampled direction reflected */ + float dir_back_samp[DIM]; /* Negated sampled direction */ + float dir_back_refl[DIM]; /* Negated sampled direction reflected */ + int reinjection_is_valid = 0; /* Can reinjection be performed */ + int iattempt = 0; /* #attempts to find a reinjection dir */ + res_T res = RES_OK; + + /* Pre-conditions */ + ASSERT(scn && args_front && args_back && step_front && step_back); + ASSERT(XD(check_sample_reinjection_step_args)(args_front)); + ASSERT(XD(check_sample_reinjection_step_args)(args_back)); + ASSERT(args_front->side == SDIS_FRONT); + ASSERT(args_back->side == SDIS_BACK); + + rwalk = args_front->rwalk; + rng = args_front->rng; + ASSERT(args_back->rng == rng); + ASSERT(args_back->rwalk == rwalk); + + dX(set)(rwalk_pos_backup, rwalk->vtx.P); + reinjection_is_valid = 0; + iattempt = 0; + do { + int rwalk_pos_moved = 0; + + if(iattempt != 0) dX(set)(rwalk->vtx.P, rwalk_pos_backup); + + /* Sample a reinjection direction and reflect it around the normal. Then + * reflect them on the back side of the interface. */ + XD(sample_reinjection_dir)(rwalk, rng, dir_front_samp); + XD(reflect)(dir_front_refl, dir_front_samp, rwalk->hit.normal); + fX(minus)(dir_back_samp, dir_front_samp); + fX(minus)(dir_back_refl, dir_front_refl); + + /* Select the reinjection direction and distance for the front side */ + res = XD(select_reinjection_dir_and_check_validity) + (scn, + args_front->solid, + rwalk, + dir_front_samp, + dir_front_refl, + args_front->distance, + step_front->direction, + &step_front->distance, + 1, /* Can move */ + NULL, + &reinjection_is_valid, + &step_front->hit); + if(res != RES_OK) goto error; + if(!reinjection_is_valid) continue; + + /* Select the reinjection direction and distance for the back side */ + res = XD(select_reinjection_dir_and_check_validity) + (scn, + args_back->solid, + rwalk, + dir_back_samp, + dir_back_refl, + args_back->distance, + step_back->direction, + &step_back->distance, + 1, /* Can move */ + &rwalk_pos_moved, + &reinjection_is_valid, + &step_back->hit); + if(res != RES_OK) goto error; + if(!reinjection_is_valid) continue; + + /* If random walk was moved by the select_reinjection_dir on back side, one + * has to rerun the select_reinjection_dir on front side at the new pos */ + if(rwalk_pos_moved) { + res = XD(select_reinjection_dir_and_check_validity) + (scn, + args_front->solid, + rwalk, + dir_front_samp, + dir_front_refl, + args_front->distance, + step_front->direction, + &step_front->distance, + 0, /* Can't move */ + NULL, + &reinjection_is_valid, + &step_front->hit); + if(res != RES_OK) goto error; + if(!reinjection_is_valid) continue; + } + } while(!reinjection_is_valid && ++iattempt < MAX_ATTEMPTS); + + /* Could not find a valid reinjection */ + if(iattempt >= MAX_ATTEMPTS) { + dX(set)(rwalk->vtx.P, rwalk_pos_backup); + log_warn(scn->dev, + "%s: could not find a valid solid/solid reinjection at {%g, %g, %g}.\n", + FUNC_NAME, SPLIT3(rwalk->vtx.P)); + res = RES_BAD_OP_IRRECOVERABLE; + goto error; + } + + /* Post-conditions */ + ASSERT(XD(check_reinjection_step)(step_front)); + ASSERT(XD(check_reinjection_step)(step_back)); + +exit: + return res; +error: + goto exit; +} + +res_T +XD(solid_reinjection) + (struct sdis_medium* solid, + struct XD(solid_reinjection_args)* args) +{ + double power; + double lambda; + double reinject_dst_m; /* Reinjection distance in meters */ + res_T res = RES_OK; + ASSERT(solid && XD(check_solid_reinjection_args)(args)); + + reinject_dst_m = args->reinjection->distance * args->fp_to_meter; + + /* Fetch solid properties */ + lambda = solid_get_thermal_conductivity(solid, &args->rwalk->vtx); + power = solid_get_volumic_power(solid, &args->rwalk->vtx); + + /* Handle the volumic power */ + if(power != SDIS_VOLUMIC_POWER_NONE) { + const double reinject_dst_m_sqr = reinject_dst_m * reinject_dst_m; + const double power_term = reinject_dst_m_sqr / (2.0 * DIM * lambda); + + args->T->value += power * power_term; + + /* Update the green */ + if(args->rwalk_ctx->green_path) { + res = green_path_add_power_term + (args->rwalk_ctx->green_path, solid, &args->rwalk->vtx, power_term); + if(res != RES_OK) goto error; + } + } + + /* Time rewind */ + res = XD(time_rewind) + (solid, args->rng, reinject_dst_m, args->rwalk_ctx, args->rwalk, args->T); + if(res != RES_OK) goto error; + + /* Test if a limit condition was reached */ + if(args->T->done) goto exit; + + /* Move the random walk to the reinjection position */ + XD(move_pos) + (args->rwalk->vtx.P, + args->reinjection->direction, + args->reinjection->distance); + + /* The random walk is in the solid */ + if(args->reinjection->hit.distance != args->reinjection->distance) { + args->T->func = XD(conductive_path); + args->rwalk->mdm = solid; + args->rwalk->hit = SXD_HIT_NULL; + args->rwalk->hit_side = SDIS_SIDE_NULL__; + + /* The random walk is at a boundary */ + } else { + args->T->func = XD(boundary_path); + args->rwalk->mdm = NULL; + args->rwalk->hit = args->reinjection->hit; + if(fX(dot)(args->reinjection->hit.normal, args->reinjection->direction) < 0) { + args->rwalk->hit_side = SDIS_FRONT; + } else { + args->rwalk->hit_side = SDIS_BACK; + } + } + + /* Register the new vertex against the heat path */ + res = register_heat_vertex + (args->rwalk_ctx->heat_path, + &args->rwalk->vtx, + args->T->value, + SDIS_HEAT_VERTEX_CONDUCTION); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; } #include "sdis_Xd_end.h" diff --git a/src/sdis_heat_path_boundary_Xd_fixed_flux.h b/src/sdis_heat_path_boundary_Xd_fixed_flux.h @@ -38,126 +38,78 @@ XD(solid_boundary_with_flux_path) struct ssp_rng* rng, struct XD(temperature)* T) { - struct XD(rwalk) rwalk_saved; + /* Input/output arguments of the function used to sample a reinjection */ + struct XD(sample_reinjection_step_args) samp_reinject_step_args = + XD(SAMPLE_REINJECTION_STEP_ARGS_NULL); + struct XD(reinjection_step) reinject_step = XD(REINJECTION_STEP_NULL); + + /* Reinjection arguments */ + struct XD(solid_reinjection_args) solid_reinject_args = + XD(SOLID_REINJECTION_ARGS_NULL); + + /* Data attached to the boundary */ struct sdis_interface* interf = NULL; - struct sdis_medium* mdm = NULL; - double lambda; - double delta; - double delta_boundary; - double delta_in_meter; - double power; - double tmp; - struct sXd(hit) hit; - float dir0[DIM]; - float dir1[DIM]; - float reinject_dst; - /* In 2D it is useless to try to resample a reinjection direction since there - * is only one possible direction */ - const int MAX_ATTEMPTS = DIM == 2 ? 1 : 10; - int iattempt = 0; - int reinjection_is_valid = 0; + struct sdis_medium* solid = NULL; + + /* Miscellaneous terms */ + double lambda; /* Solid conductivity */ + double delta_boundary; /* Orthogonal reinjection dst at the boundary */ + double delta; /* Orthogonal fitted reinjection dst at the boundary */ + double delta_m; /* Delta in meters */ + double flux_term; + enum sdis_side solid_side = SDIS_SIDE_NULL__; res_T res = RES_OK; + ASSERT(frag && phi != SDIS_FLUX_NONE); ASSERT(XD(check_rwalk_fragment_consistency)(rwalk, frag)); (void)ctx; - /* Fetch current interface */ + /* Retrieve the solid split by the interface */ interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); + solid = interface_get_medium(interf, frag->side); + solid_side = frag->side; ASSERT(phi == interface_side_get_flux(interf, frag)); + ASSERT(solid->type == SDIS_SOLID); - /* Fetch incoming solid */ - mdm = interface_get_medium(interf, frag->side); - ASSERT(mdm->type == SDIS_SOLID); - - /* Fetch medium properties */ - lambda = solid_get_thermal_conductivity(mdm, &rwalk->vtx); - delta = solid_get_delta(mdm, &rwalk->vtx); + /* Fetch the solid properties */ + lambda = solid_get_thermal_conductivity(solid, &rwalk->vtx); + delta = solid_get_delta(solid, &rwalk->vtx); - /* Compute the reinjection distance. It MUST ensure that the orthogonal - * distance from the boundary to the point to chalenge is equal to delta. */ + /* Note that the reinjection distance is *FIXED*. It MUST ensure that the + * orthogonal distance from the boundary to the reinjection point is at most + * equal to delta. */ delta_boundary = delta * sqrt(DIM); - rwalk_saved = *rwalk; - reinjection_is_valid = 0; - iattempt = 0; - do { - if(iattempt != 0) *rwalk = rwalk_saved; - /* Sample a reinjection direction */ - XD(sample_reinjection_dir)(rwalk, rng, dir0); - - /* Reflect the sampled direction around the normal */ - XD(reflect)(dir1, dir0, rwalk->hit.normal); - - if(frag->side == SDIS_BACK) { - fX(minus)(dir0, dir0); - fX(minus)(dir1, dir1); - } - - /* Select the reinjection direction and distance */ - res = XD(select_reinjection_dir_and_check_validity)(scn, mdm, rwalk, dir0, - dir1, delta_boundary, dir0, &reinject_dst, 1, NULL, - &reinjection_is_valid, &hit); - if(res != RES_OK) goto error; - - } while(!reinjection_is_valid && ++iattempt < MAX_ATTEMPTS); - - /* Could not find a valid reinjecton */ - if(iattempt >= MAX_ATTEMPTS) { - *rwalk = rwalk_saved; - log_warn(scn->dev, - "%s: could not find a valid solid/fluid with flux reinjection " - "at {%g, %g, %g}.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); - res = RES_BAD_OP_IRRECOVERABLE; - goto error; - } + /* Sample a reinjection step */ + samp_reinject_step_args.rng = rng; + samp_reinject_step_args.solid = solid; + samp_reinject_step_args.rwalk = rwalk; + samp_reinject_step_args.distance = delta_boundary; + samp_reinject_step_args.side = solid_side; + res = XD(sample_reinjection_step_solid_fluid) + (scn, &samp_reinject_step_args, &reinject_step); + if(res != RES_OK) goto error; - /* Define the orthogonal dst from the reinjection pos to the interface */ - delta = reinject_dst / sqrt(DIM); + /* Define the orthogonal dst from the boundary to the reinjection position */ + delta = reinject_step.distance / sqrt(DIM); + delta_m = delta * scn->fp_to_meter; /* Handle the flux */ - delta_in_meter = delta * scn->fp_to_meter; - tmp = delta_in_meter / lambda; - T->value += phi * tmp; + flux_term = delta_m / lambda; + T->value += phi * flux_term; if(ctx->green_path) { - res = green_path_add_flux_term(ctx->green_path, interf, frag, tmp); + res = green_path_add_flux_term(ctx->green_path, interf, frag, flux_term); if(res != RES_OK) goto error; } - /* Handle the volumic power */ - power = solid_get_volumic_power(mdm, &rwalk->vtx); - if(power != SDIS_VOLUMIC_POWER_NONE) { - delta_in_meter = reinject_dst * scn->fp_to_meter; - tmp = delta_in_meter * delta_in_meter / (2.0 * DIM * lambda); - T->value += power * tmp; - if(ctx->green_path) { - res = green_path_add_power_term(ctx->green_path, mdm, &rwalk->vtx, tmp); - if(res != RES_OK) goto error; - } - } - - /* Time rewind */ - res = XD(time_rewind)(mdm, rng, reinject_dst * scn->fp_to_meter, ctx, rwalk, T); - if(res != RES_OK) goto error; - if(T->done) goto exit; /* Limit condition was reached */ - - /* Reinject. If the reinjection move the point too close of a boundary, - * assume that the zone is isotherm and move to the boundary. */ - XD(move_pos)(rwalk->vtx.P, dir0, reinject_dst); - if(hit.distance == reinject_dst) { - T->func = XD(boundary_path); - rwalk->mdm = NULL; - rwalk->hit = hit; - rwalk->hit_side = fX(dot)(hit.normal, dir0) < 0 ? SDIS_FRONT : SDIS_BACK; - } else { - T->func = XD(conductive_path); - rwalk->mdm = mdm; - rwalk->hit = SXD_HIT_NULL; - rwalk->hit_side = SDIS_SIDE_NULL__; - } - - /* Register the new vertex against the heat path */ - res = register_heat_vertex - (ctx->heat_path, &rwalk->vtx, T->value, SDIS_HEAT_VERTEX_CONDUCTION); + /* Perform the reinjection into the solid */ + solid_reinject_args.reinjection = &reinject_step; + solid_reinject_args.rwalk_ctx = ctx; + solid_reinject_args.rwalk = rwalk; + solid_reinject_args.rng = rng; + solid_reinject_args.T = T; + solid_reinject_args.fp_to_meter = scn->fp_to_meter; + res = XD(solid_reinjection)(solid, &solid_reinject_args); if(res != RES_OK) goto error; exit: diff --git a/src/sdis_heat_path_boundary_Xd_solid_fluid.h b/src/sdis_heat_path_boundary_Xd_solid_fluid.h @@ -36,157 +36,117 @@ XD(solid_fluid_boundary_path) struct ssp_rng* rng, struct XD(temperature)* T) { + /* Input/output arguments of the function used to sample a reinjection */ + struct XD(sample_reinjection_step_args) samp_reinject_step_args = + XD(SAMPLE_REINJECTION_STEP_ARGS_NULL); + struct XD(reinjection_step) reinject_step = + XD(REINJECTION_STEP_NULL); + + /* Fragment on the fluid side of the boundary */ + struct sdis_interface_fragment frag_fluid; + + /* Data attached to the boundary */ struct sdis_interface* interf = NULL; - struct sdis_medium* mdm_front = NULL; - struct sdis_medium* mdm_back = NULL; struct sdis_medium* solid = NULL; struct sdis_medium* fluid = NULL; - struct XD(rwalk) rwalk_saved; - struct sXd(hit) hit = SXD_HIT_NULL; - struct sdis_interface_fragment frag_fluid; - double hc; - double hr; + + double h_cond; /* Conductive coefficient */ + double h_conv; /* Convective coefficient */ + double h_radi; /* Radiative coefficient */ + double h; /* Sum of h_<conv|cond|radi> */ + double p_conv; /* Convective proba */ + double p_radi; /* Radiative proba */ + double epsilon; /* Interface emissivity */ - double lambda; - double fluid_proba; - double radia_proba; - double delta; - double delta_boundary; + double lambda; /* Solid conductivity */ + double delta_boundary; /* Orthogonal reinjection dst at the boundary */ + double delta; /* Orthogonal fitted reinjection dst at the boundary */ + double r; - double tmp; - float dir0[DIM], dir1[DIM]; - float reinject_dst; - /* In 2D it is useless to try to resample a reinjection direction since there - * is only one possible direction */ - const int MAX_ATTEMPTS = DIM == 2 ? 1 : 10; - int iattempt; - int reinjection_is_valid = 0; + enum sdis_side solid_side = SDIS_SIDE_NULL__; + enum sdis_side fluid_side = SDIS_SIDE_NULL__; res_T res = RES_OK; + ASSERT(scn && rwalk && rng && T && ctx); ASSERT(XD(check_rwalk_fragment_consistency)(rwalk, frag)); - /* Retrieve the solid and the fluid split by the boundary */ + /* Retrieve the solid and the fluid split by the boundary */ interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); - mdm_front = interface_get_medium(interf, SDIS_FRONT); - mdm_back = interface_get_medium(interf, SDIS_BACK); - ASSERT(mdm_front->type != mdm_back->type); + solid = interface_get_medium(interf, SDIS_FRONT); + fluid = interface_get_medium(interf, SDIS_BACK); + solid_side = SDIS_FRONT; + fluid_side = SDIS_BACK; + if(solid->type != SDIS_SOLID) { + SWAP(struct sdis_medium*, solid, fluid); + SWAP(enum sdis_side, solid_side, fluid_side); + } + /* Setup a fragment for the fluid side */ frag_fluid = *frag; - if(mdm_front->type == SDIS_SOLID) { - solid = mdm_front; - fluid = mdm_back; - frag_fluid.side = SDIS_BACK; - } else { - solid = mdm_back; - fluid = mdm_front; - frag_fluid.side = SDIS_FRONT; - } + frag_fluid.side = fluid_side; /* Fetch the solid properties */ lambda = solid_get_thermal_conductivity(solid, &rwalk->vtx); delta = solid_get_delta(solid, &rwalk->vtx); - /* Note that the reinjection distance is *FIXED*. It MUST ensure that the - * orthogonal distance from the boundary to the point to chalenge is equal to - * delta. */ - delta_boundary = sqrt(DIM) * delta; - - rwalk_saved = *rwalk; - reinjection_is_valid = 0; - iattempt = 0; - do { - if(iattempt != 0) *rwalk = rwalk_saved; - - /* Sample a reinjection direction */ - XD(sample_reinjection_dir)(rwalk, rng, dir0); - - /* Reflect the sampled direction around the normal */ - XD(reflect)(dir1, dir0, rwalk->hit.normal); - - if(solid == mdm_back) { - fX(minus)(dir0, dir0); - fX(minus)(dir1, dir1); - } - - /* Select the solid reinjection direction and distance */ - res = XD(select_reinjection_dir_and_check_validity)(scn, solid, rwalk, - dir0, dir1, delta_boundary, dir0, &reinject_dst, 1, NULL, - &reinjection_is_valid, &hit); - if(res != RES_OK) goto error; - - } while(!reinjection_is_valid && ++iattempt < MAX_ATTEMPTS); - - /* Could not find a valid reinjecton */ - if(iattempt >= MAX_ATTEMPTS) { - *rwalk = rwalk_saved; - log_warn(scn->dev, - "%s: could not find a valid solid/fluid reinjection at {%g, %g %g}.\n", - FUNC_NAME, SPLIT3(rwalk->vtx.P)); - res = RES_BAD_OP_IRRECOVERABLE; - goto error; - } - - /* Define the orthogonal dst from the reinjection pos to the interface */ - delta = reinject_dst / sqrt(DIM); - - /* Fetch the boundary properties */ + /* Fetch the interface properties on the fluid side */ epsilon = interface_side_get_emissivity(interf, &frag_fluid); - hc = interface_get_convection_coef(interf, frag); - /* Compute the radiative coefficient */ - hr = 4.0 * BOLTZMANN_CONSTANT * ctx->Tref3 * epsilon; + /* Note that the reinjection distance is *FIXED*. It MUST ensure that the + * orthogonal distance from the boundary to the reinjection point is at most + * equal to delta. */ + delta_boundary = sqrt(DIM) * delta; - /* Compute the probas to switch in solid, fluid or radiative random walk */ - tmp = lambda / (delta * scn->fp_to_meter); - fluid_proba = hc / (tmp + hr + hc); - radia_proba = hr / (tmp + hr + hc); - /*solid_proba = tmp / (tmp + hr + hc);*/ + /* Sample a reinjection step */ + samp_reinject_step_args.rng = rng; + samp_reinject_step_args.solid = solid; + samp_reinject_step_args.rwalk = rwalk; + samp_reinject_step_args.distance = delta_boundary; + samp_reinject_step_args.side = solid_side; + res = XD(sample_reinjection_step_solid_fluid) + (scn, &samp_reinject_step_args, &reinject_step); + if(res != RES_OK) goto error; + + /* Define the orthogonal dst from the boundary to the reinjection position */ + delta = reinject_step.distance / sqrt(DIM); + + /* Compute the convective, conductive and radiative coefficients */ + h_conv = interface_get_convection_coef(interf, frag); + h_cond = lambda / (delta * scn->fp_to_meter); + h_radi = 4.0 * BOLTZMANN_CONSTANT * ctx->Tref3 * epsilon; + h = h_conv + h_cond + h_radi; + + /* Compute the probas */ + p_conv = h_conv / h; + p_radi = h_radi / h; r = ssp_rng_canonical(rng); - if(r < radia_proba) { /* Switch in radiative random walk */ + + /* Switch in radiative path */ + if(r < p_radi) { T->func = XD(radiative_path); rwalk->mdm = fluid; - rwalk->hit_side = rwalk->mdm == mdm_front ? SDIS_FRONT : SDIS_BACK; - } else if(r < fluid_proba + radia_proba) { /* Switch to convective random walk */ + rwalk->hit_side = fluid_side; + + /* Switch to convective path */ + } else if(r < p_radi + p_conv) { T->func = XD(convective_path); rwalk->mdm = fluid; - rwalk->hit_side = rwalk->mdm == mdm_front ? SDIS_FRONT : SDIS_BACK; - } else { /* Solid random walk */ - /* Handle the volumic power */ - const double power = solid_get_volumic_power(solid, &rwalk->vtx); - if(power != SDIS_VOLUMIC_POWER_NONE) { - const double delta_in_meter = reinject_dst * scn->fp_to_meter; - tmp = delta_in_meter * delta_in_meter / (2.0 * DIM * lambda); - T->value += power * tmp; - - if(ctx->green_path) { - res = green_path_add_power_term(ctx->green_path, solid, &rwalk->vtx, tmp); - if(res != RES_OK) goto error; - } - } - - /* Time rewind */ - res = XD(time_rewind)(solid, rng, reinject_dst * scn->fp_to_meter, ctx, rwalk, T); - if(res != RES_OK) goto error; - if(T->done) goto exit; /* Limit condition was reached */ - - /* Perform solid reinjection */ - XD(move_pos)(rwalk->vtx.P, dir0, reinject_dst); - if(hit.distance == reinject_dst) { - T->func = XD(boundary_path); - rwalk->mdm = NULL; - rwalk->hit = hit; - rwalk->hit_side = fX(dot)(hit.normal, dir0) < 0 ? SDIS_FRONT : SDIS_BACK; - } else { - T->func = XD(conductive_path); - rwalk->mdm = solid; - rwalk->hit = SXD_HIT_NULL; - rwalk->hit_side = SDIS_SIDE_NULL__; - } - - /* Register the new vertex against the heat path */ - res = register_heat_vertex - (ctx->heat_path, &rwalk->vtx, T->value, SDIS_HEAT_VERTEX_CONDUCTION); + rwalk->hit_side = fluid_side; + + /* Switch in conductive path */ + } else { + struct XD(solid_reinjection_args) solid_reinject_args = + XD(SOLID_REINJECTION_ARGS_NULL); + + /* Perform the reinjection into the solid */ + solid_reinject_args.reinjection = &reinject_step; + solid_reinject_args.rwalk_ctx = ctx; + solid_reinject_args.rwalk = rwalk; + solid_reinject_args.rng = rng; + solid_reinject_args.T = T; + solid_reinject_args.fp_to_meter = scn->fp_to_meter; + res = XD(solid_reinjection)(solid, &solid_reinject_args); if(res != RES_OK) goto error; } diff --git a/src/sdis_heat_path_boundary_Xd_solid_solid.h b/src/sdis_heat_path_boundary_Xd_solid_solid.h @@ -37,105 +37,77 @@ XD(solid_solid_boundary_path) struct ssp_rng* rng, struct XD(temperature)* T) { - struct sXd(hit) hit0, hit1; - struct sXd(hit)* hit; - struct XD(rwalk) rwalk_saved; + /* Input/output arguments of the function used to sample a reinjection */ + struct XD(sample_reinjection_step_args) samp_reinject_step_frt_args = + XD(SAMPLE_REINJECTION_STEP_ARGS_NULL); + struct XD(sample_reinjection_step_args) samp_reinject_step_bck_args = + XD(SAMPLE_REINJECTION_STEP_ARGS_NULL); + struct XD(reinjection_step) reinject_step_frt = XD(REINJECTION_STEP_NULL); + struct XD(reinjection_step) reinject_step_bck = XD(REINJECTION_STEP_NULL); + struct XD(reinjection_step)* reinject_step = NULL; + + /* Reinjection arguments */ + struct XD(solid_reinjection_args) solid_reinject_args = + XD(SOLID_REINJECTION_ARGS_NULL); + + /* Data attached to the boundary */ struct sdis_interface* interf = NULL; - struct sdis_medium* solid_front = NULL; - struct sdis_medium* solid_back = NULL; - struct sdis_medium* mdm; - double lambda_front, lambda_back; - double delta_front, delta_back; - double delta_boundary_front, delta_boundary_back; + struct sdis_medium* solid_frt = NULL; + struct sdis_medium* solid_bck = NULL; + struct sdis_medium* solid = NULL; + + double lambda_frt; + double lambda_bck; + double delta_boundary_frt; + double delta_boundary_bck; + double proba; - double tmp; double r; - double power; double tcr; - float dir0[DIM], dir1[DIM], dir2[DIM], dir3[DIM]; - float dir_front[DIM], dir_back[DIM]; - float* dir; - float reinject_dst_front = 0, reinject_dst_back = 0; - float reinject_dst; - /* In 2D it is useless to try to resample a reinjection direction since there - * is only one possible direction */ - const int MAX_ATTEMPTS = DIM == 2 ? 1 : 10; - int iattempt; - int move; - int reinjection_is_valid; + res_T res = RES_OK; ASSERT(scn && ctx && frag && rwalk && rng && T); ASSERT(XD(check_rwalk_fragment_consistency)(rwalk, frag)); (void)frag, (void)ctx; - /* Retrieve the current boundary media */ + /* Retrieve the two solids split by the boundary */ interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); - solid_front = interface_get_medium(interf, SDIS_FRONT); - solid_back = interface_get_medium(interf, SDIS_BACK); - ASSERT(solid_front->type == SDIS_SOLID); - ASSERT(solid_back->type == SDIS_SOLID); + solid_frt = interface_get_medium(interf, SDIS_FRONT); + solid_bck = interface_get_medium(interf, SDIS_BACK); + ASSERT(solid_frt->type == SDIS_SOLID); + ASSERT(solid_bck->type == SDIS_SOLID); /* Retrieve the thermal contact resistance */ tcr = interface_get_thermal_contact_resistance(interf, frag); /* Fetch the properties of the media */ - lambda_front = solid_get_thermal_conductivity(solid_front, &rwalk->vtx); - lambda_back = solid_get_thermal_conductivity(solid_back, &rwalk->vtx); - - /* Note that reinjection distance is *FIXED*. It MUST ensure that the orthogonal - * distance from the boundary to the point to challenge is equal to delta. */ - delta_front = solid_get_delta(solid_front, &rwalk->vtx); - delta_back = solid_get_delta(solid_back, &rwalk->vtx); - delta_boundary_front = delta_front*sqrt(DIM); - delta_boundary_back = delta_back *sqrt(DIM); - - rwalk_saved = *rwalk; - reinjection_is_valid = 0; - iattempt = 0; - do { - if(iattempt != 0) *rwalk = rwalk_saved; - - /* Sample a reinjection direction and reflect it around the normal. Then - * reflect them on the back side of the interface. */ - XD(sample_reinjection_dir)(rwalk, rng, dir0); - XD(reflect)(dir2, dir0, rwalk->hit.normal); - fX(minus)(dir1, dir0); - fX(minus)(dir3, dir2); - - /* Select the reinjection direction and distance for the front side */ - res = XD(select_reinjection_dir_and_check_validity)(scn, solid_front, rwalk, - dir0, dir2, delta_boundary_front, dir_front, &reinject_dst_front, 1, &move, - &reinjection_is_valid, &hit0); - if(res != RES_OK) goto error; - if(!reinjection_is_valid) continue; - - /* Select the reinjection direction and distance for the back side */ - res = XD(select_reinjection_dir_and_check_validity)(scn, solid_back, rwalk, - dir1, dir3, delta_boundary_back, dir_back, &reinject_dst_back, 1, &move, - &reinjection_is_valid, &hit1); - if(res != RES_OK) goto error; - if(!reinjection_is_valid) continue; - - /* If random walk was moved by the select_reinjection_dir on back side, one - * has to rerun the select_reinjection_dir on front side at the new pos */ - if(move) { - res = XD(select_reinjection_dir_and_check_validity)(scn, solid_front, - rwalk, dir0, dir2, delta_boundary_front, dir_front, &reinject_dst_front, - 0, NULL, &reinjection_is_valid, &hit0); - if(res != RES_OK) goto error; - if(!reinjection_is_valid) continue; - } - } while(!reinjection_is_valid && ++iattempt < MAX_ATTEMPTS); - - /* Could not find a valid reinjection */ - if(iattempt >= MAX_ATTEMPTS) { - *rwalk = rwalk_saved; - log_warn(scn->dev, - "%s: could not find a valid solid/solid reinjection at {%g, %g, %g}.\n", - FUNC_NAME, SPLIT3(rwalk->vtx.P)); - res = RES_BAD_OP_IRRECOVERABLE; - goto error; - } + lambda_frt = solid_get_thermal_conductivity(solid_frt, &rwalk->vtx); + lambda_bck = solid_get_thermal_conductivity(solid_bck, &rwalk->vtx); + + /* Note that the reinjection distance is *FIXED*. It MUST ensure that the + * orthogonal distance from the boundary to the reinjection point is at most + * equal to delta. */ + delta_boundary_frt = solid_get_delta(solid_frt, &rwalk->vtx) * sqrt(DIM); + delta_boundary_bck = solid_get_delta(solid_bck, &rwalk->vtx) * sqrt(DIM); + + /* Sample a front/back reinjection steps */ + samp_reinject_step_frt_args.rng = rng; + samp_reinject_step_bck_args.rng = rng; + samp_reinject_step_frt_args.solid = solid_frt; + samp_reinject_step_bck_args.solid = solid_bck; + samp_reinject_step_frt_args.rwalk = rwalk; + samp_reinject_step_bck_args.rwalk = rwalk; + samp_reinject_step_frt_args.distance = delta_boundary_frt; + samp_reinject_step_bck_args.distance = delta_boundary_bck; + samp_reinject_step_frt_args.side = SDIS_FRONT; + samp_reinject_step_bck_args.side = SDIS_BACK; + res = XD(sample_reinjection_step_solid_solid) + (scn, + &samp_reinject_step_frt_args, + &samp_reinject_step_bck_args, + &reinject_step_frt, + &reinject_step_bck); + if(res != RES_OK) goto error; r = ssp_rng_canonical(rng); if(tcr == 0) { /* No thermal contact resistance */ @@ -149,80 +121,49 @@ XD(solid_solid_boundary_path) * Anyway, one can avoid to compute the adjusted delta by directly using the * adjusted reinjection distance since the resulting proba is strictly the * same; sqrt(DIM) can be simplified. */ - proba = (lambda_front/reinject_dst_front) - / (lambda_front/reinject_dst_front + lambda_back/reinject_dst_back); + const double tmp_frt = lambda_frt / reinject_step_frt.distance; + const double tmp_bck = lambda_bck / reinject_step_bck.distance; + proba = tmp_frt / (tmp_frt + tmp_bck); } else { - const double df = reinject_dst_front/sqrt(DIM); - const double db = reinject_dst_back/sqrt(DIM); - const double tmp_front = lambda_front/df; - const double tmp_back = lambda_back/db; - const double tmp_r = tcr*tmp_front*tmp_back; + const double delta_frt = reinject_step_frt.distance/sqrt(DIM); + const double delta_bck = reinject_step_bck.distance/sqrt(DIM); + const double tmp_frt = lambda_frt/delta_frt; + const double tmp_bck = lambda_bck/delta_bck; + const double tmp_tcr = tcr*tmp_frt*tmp_bck; switch(rwalk->hit_side) { case SDIS_BACK: /* When coming from the BACK side, the probability to be reinjected on * the FRONT side depends on the thermal contact resistance: it * decreases when the TCR increases (and tends to 0 when TCR -> +inf) */ - proba = (tmp_front) / (tmp_front + tmp_back + tmp_r); + proba = tmp_frt / (tmp_frt + tmp_bck + tmp_tcr); break; case SDIS_FRONT: /* Same thing when coming from the FRONT side: the probability of * reinjection on the FRONT side depends on the thermal contact * resistance: it increases when the TCR increases (and tends to 1 when * the TCR -> +inf) */ - proba = (tmp_front + tmp_r) / (tmp_front + tmp_back + tmp_r); + proba = (tmp_frt + tmp_tcr) / (tmp_frt + tmp_bck + tmp_tcr); break; default: FATAL("Unreachable code.\n"); break; } } if(r < proba) { /* Reinject in front */ - dir = dir_front; - hit = &hit0; - mdm = solid_front; - reinject_dst = reinject_dst_front; + reinject_step = &reinject_step_frt; + solid = solid_frt; } else { /* Reinject in back */ - dir = dir_back; - hit = &hit1; - mdm = solid_back; - reinject_dst = reinject_dst_back; - } - - /* Handle the volumic power */ - power = solid_get_volumic_power(mdm, &rwalk->vtx); - if(power != SDIS_VOLUMIC_POWER_NONE) { - const double delta_in_meter = reinject_dst * scn->fp_to_meter; - const double lambda = solid_get_thermal_conductivity(mdm, &rwalk->vtx); - tmp = delta_in_meter * delta_in_meter / (2.0 * DIM * lambda); - T->value += power * tmp; - - if(ctx->green_path) { - res = green_path_add_power_term(ctx->green_path, mdm, &rwalk->vtx, tmp); - if(res != RES_OK) goto error; - } - } - - /* Time rewind */ - res = XD(time_rewind)(mdm, rng, reinject_dst * scn->fp_to_meter, ctx, rwalk, T); - if(res != RES_OK) goto error; - if(T->done) goto exit; /* Limit condition was reached */ - - /* Perform reinjection. */ - XD(move_pos)(rwalk->vtx.P, dir, (float)reinject_dst); - if(hit->distance == reinject_dst) { - T->func = XD(boundary_path); - rwalk->mdm = NULL; - rwalk->hit = *hit; - rwalk->hit_side = fX(dot)(hit->normal, dir) < 0 ? SDIS_FRONT : SDIS_BACK; - } else { - T->func = XD(conductive_path); - rwalk->mdm = mdm; - rwalk->hit = SXD_HIT_NULL; - rwalk->hit_side = SDIS_SIDE_NULL__; + reinject_step = &reinject_step_bck; + solid = solid_bck; } - /* Register the new vertex against the heat path */ - res = register_heat_vertex - (ctx->heat_path, &rwalk->vtx, T->value, SDIS_HEAT_VERTEX_CONDUCTION); + /* Perform the reinjection into the solid */ + solid_reinject_args.reinjection = reinject_step; + solid_reinject_args.rng = rng; + solid_reinject_args.rwalk = rwalk; + solid_reinject_args.rwalk_ctx = ctx; + solid_reinject_args.T = T; + solid_reinject_args.fp_to_meter = scn->fp_to_meter; + res = XD(solid_reinjection)(solid, &solid_reinject_args); if(res != RES_OK) goto error; exit: diff --git a/src/sdis_heat_path_boundary_c.h b/src/sdis_heat_path_boundary_c.h @@ -16,91 +16,131 @@ #ifndef SDIS_HEAT_PATH_BOUNDARY_C_H #define SDIS_HEAT_PATH_BOUNDARY_C_H +#include <star/s2d.h> +#include <star/s3d.h> #include <rsys/rsys.h> /* Forward declarations */ struct rwalk_2d; struct rwalk_3d; -struct s2d_hit; -struct s3d_hit; struct sdis_scene; struct sdis_medium; /******************************************************************************* - * Helper functions + * Sample a reinjection step ******************************************************************************/ +struct sample_reinjection_step_args_2d { + struct ssp_rng* rng; /* Random number generator to use */ + const struct sdis_medium* solid; /* Solid in which to reinject */ + struct rwalk_2d* rwalk; /* Current state of the random walk */ + double distance; /* Maximum Reinjection distance */ + enum sdis_side side; /* Side of the boundary to re-inject */ +}; + +struct sample_reinjection_step_args_3d { + struct ssp_rng* rng; /* Random number generator to use */ + const struct sdis_medium* solid; /* Medium in which to reinject */ + struct rwalk_3d* rwalk; /* Current random walk state */ + double distance; /* Maximum Reinjection distance */ + enum sdis_side side; /* Side of the boundary to re-inject */ +}; + +struct reinjection_step_2d { + struct s2d_hit hit; /* Intersection along the reinjection direction */ + float direction[2]; /* Reinjection direction */ + float distance; /* Reinjection distance */ +}; + +struct reinjection_step_3d { + struct s3d_hit hit; /* Intersection along the reinjection direction */ + float direction[3]; /* Reinjection direction */ + float distance; /* Reinjection distance */ +}; + +#define SAMPLE_REINJECTION_STEP_ARGS_NULL___2d \ + {NULL, NULL, NULL, -1, SDIS_SIDE_NULL__} +#define SAMPLE_REINJECTION_STEP_ARGS_NULL___3d \ + {NULL, NULL, NULL, -1, SDIS_SIDE_NULL__} +static const struct sample_reinjection_step_args_2d +SAMPLE_REINJECTION_STEP_ARGS_NULL_2d = SAMPLE_REINJECTION_STEP_ARGS_NULL___2d; +static const struct sample_reinjection_step_args_3d +SAMPLE_REINJECTION_STEP_ARGS_NULL_3d = SAMPLE_REINJECTION_STEP_ARGS_NULL___3d; + +#define REINJECTION_STEP_NULL___2d {S2D_HIT_NULL__, {0,0}, 0} +#define REINJECTION_STEP_NULL___3d {S3D_HIT_NULL__, {0,0,0}, 0} +static const struct reinjection_step_2d +REINJECTION_STEP_NULL_2d = REINJECTION_STEP_NULL___2d; +static const struct reinjection_step_3d +REINJECTION_STEP_NULL_3d = REINJECTION_STEP_NULL___3d; + extern LOCAL_SYM res_T -select_reinjection_dir_2d +sample_reinjection_step_solid_fluid_2d (const struct sdis_scene* scn, - const struct sdis_medium* mdm, /* Medium into which the reinjection occurs */ - struct rwalk_2d* rwalk, /* Current random walk state */ - const float dir0[2], /* Challenged direction */ - const float dir1[2], /* Challanged direction */ - const double delta, /* Max reinjection distance */ - float reinject_dir[2], /* Selected direction */ - float* reinject_dst, /* Effective reinjection distance */ - int can_move, /* Define of the random wal pos can be moved or not */ - int* move_pos, /* Define if the current random walk was moved. May be NULL */ - struct s2d_hit* reinject_hit); /* Hit along the reinjection dir */ + const struct sample_reinjection_step_args_2d* args, + struct reinjection_step_2d* step); extern LOCAL_SYM res_T -select_reinjection_dir_3d +sample_reinjection_step_solid_fluid_3d (const struct sdis_scene* scn, - const struct sdis_medium* mdm, /* Medium into which the reinjection occurs */ - struct rwalk_3d* rwalk, /* Current random walk state */ - const float dir0[3], /* Challenged direction */ - const float dir1[3], /* Challanged direction */ - const double delta, /* Max reinjection distance */ - float reinject_dir[3], /* Selected direction */ - float* reinject_dst, /* Effective reinjection distance */ - int can_move, /* Define of the random wal pos can be moved or not */ - int* move_pos, /* Define if the current random walk was moved. May be NULL */ - struct s3d_hit* reinject_hit); /* Hit along the reinjection dir */ + const struct sample_reinjection_step_args_3d* args, + struct reinjection_step_3d *step); extern LOCAL_SYM res_T -select_reinjection_dir_and_check_validity_2d +sample_reinjection_step_solid_solid_2d (const struct sdis_scene* scn, - const struct sdis_medium* mdm, /* Medium into which the reinjection occurs */ - struct rwalk_2d* rwalk, /* Current random walk state */ - const float dir0[2], /* Challenged direction */ - const float dir1[2], /* Challanged direction */ - const double delta, /* Max reinjection distance */ - float out_reinject_dir[2], /* Selected direction */ - float* out_reinject_dst, /* Effective reinjection distance */ - int can_move, /* Define of the random wal pos can be moved or not */ - int* move_pos, /* Define if the current random walk was moved. May be NULL */ - int* is_valid, /* Define if the reinjection defines a valid pos */ - struct s2d_hit* out_reinject_hit); /* Hit along the reinjection dir */ + const struct sample_reinjection_step_args_2d* args_front, + const struct sample_reinjection_step_args_2d* args_back, + struct reinjection_step_2d* step_front, + struct reinjection_step_2d* step_back); extern LOCAL_SYM res_T -select_reinjection_dir_and_check_validity_3d +sample_reinjection_step_solid_solid_3d (const struct sdis_scene* scn, - const struct sdis_medium* mdm, /* Medium into which the reinjection occurs */ - struct rwalk_3d* rwalk, /* Current random walk state */ - const float dir0[3], /* Challenged direction */ - const float dir1[3], /* Challanged direction */ - const double delta, /* Max reinjection distance */ - float out_reinject_dir[3], /* Selected direction */ - float* out_reinject_dst, /* Effective reinjection distance */ - int can_move, /* Define of the random wal pos can be moved or not */ - int* move_pos, /* Define if the current random walk was moved. May be NULL */ - int* is_valid, /* Define if the reinjection defines a valid pos */ - struct s3d_hit* out_reinject_hit); /* Hit along the reinjection dir */ - -/* Check that the interface fragment is consistent with the current state of - * the random walk */ -extern LOCAL_SYM int -check_rwalk_fragment_consistency_2d - (const struct rwalk_2d* rwalk, - const struct sdis_interface_fragment* frag); - -extern LOCAL_SYM int -check_rwalk_fragment_consistency_3d - (const struct rwalk_3d* rwalk, - const struct sdis_interface_fragment* frag); + const struct sample_reinjection_step_args_3d* args_front, + const struct sample_reinjection_step_args_3d* args_back, + struct reinjection_step_3d* step_front, + struct reinjection_step_3d* step_back); + +/******************************************************************************* + * Reinject the random walk into a solid + ******************************************************************************/ +struct solid_reinjection_args_2d { + const struct reinjection_step_2d* reinjection; /* Reinjection to do */ + const struct rwalk_context* rwalk_ctx; + struct rwalk_2d* rwalk; /* Current state of the random walk */ + struct ssp_rng* rng; /* Random number generator */ + struct temperature_2d* T; + double fp_to_meter; +}; + +struct solid_reinjection_args_3d { + const struct reinjection_step_3d* reinjection; /* Reinjection to do */ + const struct rwalk_context* rwalk_ctx; + struct rwalk_3d* rwalk; /* Current state of the random walk */ + struct ssp_rng* rng; /* Random number generator */ + struct temperature_3d* T; + double fp_to_meter; +}; + +#define SOLID_REINJECTION_ARGS_NULL___2d {NULL,NULL,NULL,NULL,NULL,0} +#define SOLID_REINJECTION_ARGS_NULL___3d {NULL,NULL,NULL,NULL,NULL,0} +static const struct solid_reinjection_args_2d SOLID_REINJECTION_ARGS_NULL_2d = + SOLID_REINJECTION_ARGS_NULL___2d; +static const struct solid_reinjection_args_3d SOLID_REINJECTION_ARGS_NULL_3d = + SOLID_REINJECTION_ARGS_NULL___3d; + +extern LOCAL_SYM res_T +solid_reinjection_2d + (struct sdis_medium* solid, + struct solid_reinjection_args_2d* args); + +extern LOCAL_SYM res_T +solid_reinjection_3d + (struct sdis_medium* solid, + struct solid_reinjection_args_3d* args); /******************************************************************************* - * Boundary sub-paths + * Boundary sub-paths ******************************************************************************/ extern LOCAL_SYM res_T solid_boundary_with_flux_path_2d diff --git a/src/sdis_interface_c.h b/src/sdis_interface_c.h @@ -167,5 +167,21 @@ interface_side_get_specular_fraction ? shader->specular_fraction(frag, interf->data) : 0; } +static INLINE double +interface_side_get_reference_temperature + (const struct sdis_interface* interf, + const struct sdis_interface_fragment* frag) +{ + const struct sdis_interface_side_shader* shader; + ASSERT(interf && frag); + switch(frag->side) { + case SDIS_FRONT: shader = &interf->shader.front; break; + case SDIS_BACK: shader = &interf->shader.back; break; + default: FATAL("Unreachable code\n"); break; + } + return shader->reference_temperature + ? shader->reference_temperature(frag, interf->data) : -1; +} + #endif /* SDIS_INTERFACE_C_H */ diff --git a/src/sdis_solve.c b/src/sdis_solve.c @@ -384,7 +384,7 @@ sdis_solve_camera } /* Create the proxy RNG */ - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; diff --git a/src/sdis_solve_boundary_Xd.h b/src/sdis_solve_boundary_Xd.h @@ -187,7 +187,7 @@ XD(solve_boundary) scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } else { - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } @@ -524,7 +524,7 @@ XD(solve_boundary_flux) scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } else { - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } diff --git a/src/sdis_solve_medium_Xd.h b/src/sdis_solve_medium_Xd.h @@ -252,7 +252,7 @@ XD(solve_medium) scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } else { - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } @@ -520,7 +520,7 @@ XD(compute_power) scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } else { - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } diff --git a/src/sdis_solve_probe_Xd.h b/src/sdis_solve_probe_Xd.h @@ -83,7 +83,7 @@ XD(solve_probe) scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } else { - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } diff --git a/src/sdis_solve_probe_boundary_Xd.h b/src/sdis_solve_probe_boundary_Xd.h @@ -123,7 +123,7 @@ XD(solve_probe_boundary) scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } else { - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } @@ -427,7 +427,7 @@ XD(solve_probe_boundary_flux) scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } else { - res = ssp_rng_proxy_create(scn->dev->allocator, &ssp_rng_mt19937_64, + res = ssp_rng_proxy_create(scn->dev->allocator, SSP_RNG_MT19937_64, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; } diff --git a/src/test_sdis_conducto_radiative.c b/src/test_sdis_conducto_radiative.c @@ -407,7 +407,7 @@ main(int argc, char** argv) /* Run the simulations */ p_intface = (struct interfac*)sdis_data_get(sdis_interface_get_data(interfaces[4])); - OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng)); + OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng)); FOR_EACH(isimul, 0, nsimuls) { struct sdis_mc T = SDIS_MC_NULL; struct sdis_mc time = SDIS_MC_NULL; diff --git a/src/test_sdis_conducto_radiative_2d.c b/src/test_sdis_conducto_radiative_2d.c @@ -394,7 +394,7 @@ main(int argc, char** argv) Ts1 = T1 - tmp; /* Run the simulations */ - OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng)); + OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng)); FOR_EACH(isimul, 0, nsimuls) { struct sdis_mc T = SDIS_MC_NULL; struct sdis_mc time = SDIS_MC_NULL; diff --git a/src/test_sdis_contact_resistance.c b/src/test_sdis_contact_resistance.c @@ -425,7 +425,7 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_R)); /* Solve */ - OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng)); + OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng)); printf(">> Box scene\n"); solve(box_scn, interf_props, rng); printf("\n>> Square scene\n"); diff --git a/src/test_sdis_contact_resistance_2.c b/src/test_sdis_contact_resistance_2.c @@ -519,7 +519,7 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_R)); /* Solve */ - OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng)); + OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng)); printf(">> Box scene\n"); solve_probe(box_scn, interf_props, rng); solve(box_scn, interf_props, rng); diff --git a/src/test_sdis_flux.c b/src/test_sdis_flux.c @@ -449,7 +449,7 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_phi)); /* Solve */ - OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng)); + OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng)); printf(">> Box scene\n"); solve(box_scn, rng, interf_props); printf(">> Square Scene\n"); diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c @@ -284,7 +284,7 @@ main(int argc, char** argv) (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); - OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 0, &dev)); + OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 1, &dev)); /* Create the fluid medium */ OK(sdis_data_create diff --git a/src/test_sdis_unstationary_atm.c b/src/test_sdis_unstationary_atm.c @@ -856,7 +856,7 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_TA)); /* Solve */ - OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng)); + OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng)); printf(">> Box scene\n"); solve_tfluid(box_scn); solve_tbound1(box_scn, rng); diff --git a/src/test_sdis_utils.h b/src/test_sdis_utils.h @@ -165,35 +165,36 @@ dummy_interface_getter } static const struct sdis_solid_shader DUMMY_SOLID_SHADER = { - dummy_medium_getter, - dummy_medium_getter, - dummy_medium_getter, - dummy_medium_getter, - dummy_medium_getter, - dummy_medium_getter, - 0 + dummy_medium_getter, /* Calorific capacity */ + dummy_medium_getter, /* Thermal conductivity */ + dummy_medium_getter, /* Volumic mass */ + dummy_medium_getter, /* Delta */ + dummy_medium_getter, /* Volumic power */ + dummy_medium_getter, /* Temperature */ + 0 /* Initial time */ }; static const struct sdis_fluid_shader DUMMY_FLUID_SHADER = { - dummy_medium_getter, - dummy_medium_getter, - dummy_medium_getter, - 0 + dummy_medium_getter, /* Calorific capacity */ + dummy_medium_getter, /* Volumic mass */ + dummy_medium_getter, /* Temperature */ + 0 /* Initial time */ }; #define DUMMY_INTERFACE_SIDE_SHADER__ { \ - dummy_interface_getter, \ - dummy_interface_getter, \ - dummy_interface_getter, \ - dummy_interface_getter \ + dummy_interface_getter, /* Temperature */ \ + dummy_interface_getter, /* Flux */ \ + dummy_interface_getter, /* Emissivity */ \ + dummy_interface_getter, /* Specular fraction */ \ + dummy_interface_getter /* Reference temperature */ \ } static const struct sdis_interface_shader DUMMY_INTERFACE_SHADER = { - dummy_interface_getter, - 0, - dummy_interface_getter, - DUMMY_INTERFACE_SIDE_SHADER__, - DUMMY_INTERFACE_SIDE_SHADER__ + dummy_interface_getter, /* Convection coef */ + 0, /* Upper bound of the convection coef */ + dummy_interface_getter, /* Thermal contact resistance */ + DUMMY_INTERFACE_SIDE_SHADER__, /* Front side */ + DUMMY_INTERFACE_SIDE_SHADER__ /* Back side */ }; /******************************************************************************* diff --git a/src/test_sdis_volumic_power.c b/src/test_sdis_volumic_power.c @@ -487,7 +487,7 @@ main(int argc, char** argv) OK(sdis_interface_ref_put(interf_T0)); /* Solve */ - OK(ssp_rng_create(&allocator, &ssp_rng_kiss, &rng)); + OK(ssp_rng_create(&allocator, SSP_RNG_KISS, &rng)); printf(">> Box scene\n"); solve(box_scn, rng, solid_props); printf(">> Square scene\n");