stardis-solver

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

commit a416c8f3dcdb207500148d87f28335d8f75f4ca3
parent b80e9f194fd95ae330570ed440cc621120c78337
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 30 May 2024 16:15:42 +0200

Extensive update of genericity management

The rwalk data structure is no longer dimensionally generic. It now
contains the 2 hits, one in 2D and one in 3D. Generic functions update
the right hits according to dimension; the XD() macro is used to select
the right hit to update. As a result, the temperature data structure no
longer needs to be dimensionally generic.

The same update has been made for the internal data structure used to
sample the re-injection steps: we replace its dimensional genericity
with 2 sets of variables updated according to the dimension processed.

Managing genericity in this way is simpler: the data type is the same
and can be declared in ordinary headers, i.e. there's no need to
duplicate them manually or include them via pre-processor directives
that generate them.

Diffstat:
Msrc/sdis_Xd_begin.h | 41-----------------------------------------
Msrc/sdis_heat_path.h | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/sdis_heat_path_boundary_Xd.h | 14+++++++-------
Msrc/sdis_heat_path_boundary_Xd_c.h | 122++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/sdis_heat_path_boundary_Xd_handle_external_net_flux.h | 12++++++------
Msrc/sdis_heat_path_boundary_Xd_solid_fluid_picard1.h | 37++++++++++++++++++-------------------
Msrc/sdis_heat_path_boundary_Xd_solid_fluid_picardN.h | 35+++++++++++++++++------------------
Msrc/sdis_heat_path_boundary_Xd_solid_solid.h | 26+++++++++++++-------------
Msrc/sdis_heat_path_boundary_c.h | 159+++++++++++++++++++++++++++++++------------------------------------------------
Msrc/sdis_heat_path_conductive.c | 8++++----
Msrc/sdis_heat_path_conductive_c.h | 22++++++++++------------
Msrc/sdis_heat_path_conductive_delta_sphere_Xd.h | 14+++++++-------
Msrc/sdis_heat_path_conductive_wos_Xd.h | 156++++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/sdis_heat_path_convective_Xd.h | 66+++++++++++++++++++++++++++++++++++-------------------------------
Msrc/sdis_heat_path_radiative_Xd.h | 32++++++++++++++++----------------
Msrc/sdis_misc.c | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/sdis_misc.h | 15+++------------
Dsrc/sdis_misc_Xd.h | 90-------------------------------------------------------------------------------
Msrc/sdis_realisation.c | 6+++---
Msrc/sdis_realisation.h | 12+++++++-----
Msrc/sdis_realisation_Xd.h | 52++++++++++++++++++++++++++--------------------------
21 files changed, 507 insertions(+), 571 deletions(-)

diff --git a/src/sdis_Xd_begin.h b/src/sdis_Xd_begin.h @@ -76,44 +76,3 @@ /* Macro making generic its submitted name to SDIS_XD_DIMENSION */ #define XD(Name) CONCAT(CONCAT(CONCAT(Name, _), DIM), d) - -/* Generate the generic data structures and constants */ -#if (SDIS_XD_DIMENSION == 2 && !defined(SDIS_2D_H)) \ -|| (SDIS_XD_DIMENSION == 3 && !defined(SDIS_3D_H)) - #if SDIS_XD_DIMENSION == 2 - #define SDIS_2D_H - #else - #define SDIS_3D_H - #endif - -struct rwalk_context; - -/* Current state of the random walk */ -struct XD(rwalk) { - struct sdis_rwalk_vertex vtx; /* Position and time of the Random walk */ - struct sdis_medium* mdm; /* Medium in which the random walk lies */ - struct sXd(hit) hit; /* Hit of the random walk */ - - /* Direction along which the random walk reached the radiative environment */ - double dir[3]; - - double elapsed_time; - enum sdis_side hit_side; -}; -static const struct XD(rwalk) XD(RWALK_NULL) = { - SDIS_RWALK_VERTEX_NULL__, NULL, SXD_HIT_NULL__, {0,0,0}, 0, SDIS_SIDE_NULL__ -}; - -struct XD(temperature) { - res_T (*func)/* Next function to invoke in order to compute the temperature */ - (struct sdis_scene* scn, - struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, - struct ssp_rng* rng, - struct XD(temperature)* temp); - double value; /* Current value of the temperature */ - int done; -}; -static const struct XD(temperature) XD(TEMPERATURE_NULL) = { NULL, 0, 0 }; - -#endif /* SDIX_<2|3>D_H */ diff --git a/src/sdis_heat_path.h b/src/sdis_heat_path.h @@ -24,12 +24,8 @@ /* Forward declarations */ struct green_path_handle; -struct rwalk_2d; -struct rwalk_3d; struct sdis_scene; struct ssp_rng; -struct temperature_2d; -struct temperature_3d; /******************************************************************************* * Context of a random walk, i.e. its data concerning the current system and the @@ -87,6 +83,46 @@ get_picard_order(const struct rwalk_context* ctx) } /******************************************************************************* + * 2D/3D random walk and associated temperature, i.e. current state of the + * sampled path + ******************************************************************************/ +struct rwalk { + struct sdis_rwalk_vertex vtx; /* Position and time of the Random walk */ + struct sdis_medium* mdm; /* Medium in which the random walk lies */ + struct s2d_hit hit_2d; + struct s3d_hit hit_3d; + + /* Direction along which the random walk reached the radiative environment */ + double dir[3]; + + double elapsed_time; + enum sdis_side hit_side; +}; +#define RWALK_NULL__ { \ + SDIS_RWALK_VERTEX_NULL__, \ + NULL, \ + S2D_HIT_NULL__, \ + S3D_HIT_NULL__, \ + {0,0,0}, \ + 0, \ + SDIS_SIDE_NULL__ \ +} +static const struct rwalk RWALK_NULL = RWALK_NULL__; + +struct temperature { + res_T (*func)/* Next function to invoke in order to compute the temperature */ + (struct sdis_scene* scn, + struct rwalk_context* ctx, + struct rwalk* rwalk, + struct ssp_rng* rng, + struct temperature* temp); + double value; /* Current value of the temperature */ + int done; +}; +#define TEMPERATURE_NULL__ {NULL,0,0} +static const struct temperature TEMPERATURE_NULL = TEMPERATURE_NULL__; + +/******************************************************************************* * Heat path data structure used to record the geometry of sampled paths ******************************************************************************/ /* Generate the dynamic array of heat vertices */ @@ -261,34 +297,34 @@ trace_radiative_path_2d (struct sdis_scene* scn, const float ray_dir[3], struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* temperature); + struct temperature* temperature); extern LOCAL_SYM res_T trace_radiative_path_3d (struct sdis_scene* scn, const float ray_dir[3], struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* temperature); + struct temperature* temperature); extern LOCAL_SYM res_T radiative_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* temperature); + struct temperature* temperature); extern LOCAL_SYM res_T radiative_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* temperature); + struct temperature* temperature); /******************************************************************************* * Convective path @@ -297,17 +333,17 @@ extern LOCAL_SYM res_T convective_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* temperature); + struct temperature* temperature); extern LOCAL_SYM res_T convective_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* temperature); + struct temperature* temperature); /******************************************************************************* * Conductive path @@ -316,17 +352,17 @@ extern LOCAL_SYM res_T conductive_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* temperature); + struct temperature* temperature); extern LOCAL_SYM res_T conductive_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* temperature); + struct temperature* temperature); /******************************************************************************* * Boundary sub-path @@ -335,16 +371,16 @@ extern LOCAL_SYM res_T boundary_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* temperature); + struct temperature* temperature); extern LOCAL_SYM res_T boundary_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* temperature); + struct temperature* temperature); #endif /* SDIS_HEAT_PATH_H */ diff --git a/src/sdis_heat_path_boundary_Xd.h b/src/sdis_heat_path_boundary_Xd.h @@ -31,9 +31,9 @@ res_T XD(boundary_path) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { struct sdis_interface_fragment frag = SDIS_INTERFACE_FRAGMENT_NULL; struct sdis_interface* interf = NULL; @@ -43,14 +43,15 @@ XD(boundary_path) res_T res = RES_OK; ASSERT(scn && ctx && rwalk && rng && T); ASSERT(rwalk->mdm == NULL); - ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!SXD_HIT_NONE(&rwalk->XD(hit))); - XD(setup_interface_fragment)(&frag, &rwalk->vtx, &rwalk->hit, rwalk->hit_side); + XD(setup_interface_fragment) + (&frag, &rwalk->vtx, &rwalk->XD(hit), rwalk->hit_side); - fX(normalize)(rwalk->hit.normal, rwalk->hit.normal); + fX(normalize)(rwalk->XD(hit).normal, rwalk->XD(hit).normal); /* Retrieve the current interface */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); + interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id); /* Check if the boundary temperature is known */ tmp = interface_side_get_temperature(interf, &frag); @@ -89,4 +90,3 @@ error: } #include "sdis_Xd_end.h" - diff --git a/src/sdis_heat_path_boundary_Xd_c.h b/src/sdis_heat_path_boundary_Xd_c.h @@ -27,7 +27,7 @@ struct XD(find_reinjection_ray_args) { const struct sdis_medium* solid; /* Medium into which the reinjection occurs */ - const struct XD(rwalk)* rwalk; /* Current random walk state */ + const struct rwalk* rwalk; /* Current random walk state */ float dir0[DIM]; /* Challenged ray direction */ float dir1[DIM]; /* Challenged ray direction */ double distance; /* Maximum reinjection distance */ @@ -69,7 +69,7 @@ XD(check_find_reinjection_ray_args) static INLINE int XD(check_sample_reinjection_step_args) - (const struct XD(sample_reinjection_step_args)* args) + (const struct sample_reinjection_step_args* args) { return args && args->rng @@ -81,7 +81,7 @@ XD(check_sample_reinjection_step_args) } static INLINE int -XD(check_reinjection_step)(const struct XD(reinjection_step)* step) +XD(check_reinjection_step)(const struct reinjection_step* step) { return step && fX(is_normalized)(step->direction) @@ -89,7 +89,7 @@ XD(check_reinjection_step)(const struct XD(reinjection_step)* step) } static INLINE int -XD(check_solid_reinjection_args)(const struct XD(solid_reinjection_args)* args) +XD(check_solid_reinjection_args)(const struct solid_reinjection_args* args) { return args && XD(check_reinjection_step)(args->reinjection) @@ -104,14 +104,14 @@ XD(check_solid_reinjection_args)(const struct XD(solid_reinjection_args)* args) * the random walk */ static INLINE int XD(check_rwalk_fragment_consistency) - (const struct XD(rwalk)* rwalk, + (const struct 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(normalize)(N, dX_set_fX(N, rwalk->XD(hit).normal)); + if( SXD_HIT_NONE(&rwalk->XD(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)) @@ -119,16 +119,16 @@ XD(check_rwalk_fragment_consistency) return 0; } #if (SDIS_XD_DIMENSION == 2) - uv[0] = rwalk->hit.u; + uv[0] = rwalk->XD(hit).u; #else - d2_set_f2(uv, rwalk->hit.uv); + d2_set_f2(uv, rwalk->XD(hit).uv); #endif return d2_eq_eps(uv, frag->uv, 1.e-6); } static void XD(sample_reinjection_dir) - (const struct XD(rwalk)* rwalk, + (const struct rwalk* rwalk, struct ssp_rng* rng, float dir[DIM]) { @@ -145,15 +145,15 @@ XD(sample_reinjection_dir) * discard the sqrt(2)/2 constant. */ const uint64_t r = ssp_rng_uniform_uint64(rng, 0, 1); ASSERT(rwalk && rng && dir); - ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!SXD_HIT_NONE(&rwalk->XD(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]; + dir[0] = rwalk->XD(hit).normal[0] - rwalk->XD(hit).normal[1]; + dir[1] = rwalk->XD(hit).normal[0] + rwalk->XD(hit).normal[1]; } else { - dir[0] = rwalk->hit.normal[0] + rwalk->hit.normal[1]; - dir[1] =-rwalk->hit.normal[0] + rwalk->hit.normal[1]; + dir[0] = rwalk->XD(hit).normal[0] + rwalk->XD(hit).normal[1]; + dir[1] =-rwalk->XD(hit).normal[0] + rwalk->XD(hit).normal[1]; } f2_normalize(dir, dir); #else @@ -162,17 +162,17 @@ XD(sample_reinjection_dir) * radius of its base is 1. */ float frame[9]; ASSERT(rwalk && rng && dir); - ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!SXD_HIT_NONE(&rwalk->XD(hit))); ASSERT(!rwalk->mdm); - ASSERT(fX(is_normalized)(rwalk->hit.normal)); + ASSERT(fX(is_normalized)(rwalk->XD(hit).normal)); ssp_ran_circle_uniform_float(rng, dir, NULL); dir[2] = (float)(1.0/sqrt(2)); - f33_basis(frame, rwalk->hit.normal); + f33_basis(frame, rwalk->XD(hit).normal); f33_mulf3(dir, frame, dir); f3_normalize(dir, dir); - ASSERT(eq_epsf(f3_dot(dir, rwalk->hit.normal), (float)(1.0/sqrt(3)), 1.e-4f)); + ASSERT(eq_epsf(f3_dot(dir, rwalk->XD(hit).normal), (float)(1.0/sqrt(3)), 1.e-4f)); #endif } @@ -180,7 +180,7 @@ XD(sample_reinjection_dir) #if DIM == 2 static void XD(move_away_primitive_boundaries) - (const struct XD(rwalk)* rwalk, + (const struct rwalk* rwalk, const double delta, double position[DIM]) /* Position to move */ { @@ -189,9 +189,9 @@ XD(move_away_primitive_boundaries) float dir[DIM]; float len; const float st = 0.5f; - ASSERT(rwalk && !SXD_HIT_NONE(&rwalk->hit) && delta > 0); + ASSERT(rwalk && !SXD_HIT_NONE(&rwalk->XD(hit)) && delta > 0); - SXD(primitive_get_attrib(&rwalk->hit.prim, SXD_POSITION, st, &attr)); + SXD(primitive_get_attrib(&rwalk->XD(hit).prim, SXD_POSITION, st, &attr)); fX_set_dX(pos, position); fX(sub)(dir, attr.value, pos); @@ -205,7 +205,7 @@ XD(move_away_primitive_boundaries) * numerical issues leading to inconsistent random walks. */ static void XD(move_away_primitive_boundaries) - (const struct XD(rwalk)* rwalk, + (const struct rwalk* rwalk, const double delta, double position[DIM]) { @@ -222,14 +222,14 @@ XD(move_away_primitive_boundaries) int imin = 0; int imid = 0; int i; - ASSERT(rwalk && delta > 0 && !S3D_HIT_NONE(&rwalk->hit)); + ASSERT(rwalk && delta > 0 && !S3D_HIT_NONE(&rwalk->XD(hit))); fX_set_dX(P, position); /* Fetch triangle vertices */ - S3D(triangle_get_vertex_attrib(&rwalk->hit.prim, 0, S3D_POSITION, &v0)); - S3D(triangle_get_vertex_attrib(&rwalk->hit.prim, 1, S3D_POSITION, &v1)); - S3D(triangle_get_vertex_attrib(&rwalk->hit.prim, 2, S3D_POSITION, &v2)); + S3D(triangle_get_vertex_attrib(&rwalk->XD(hit).prim, 0, S3D_POSITION, &v0)); + S3D(triangle_get_vertex_attrib(&rwalk->XD(hit).prim, 1, S3D_POSITION, &v1)); + S3D(triangle_get_vertex_attrib(&rwalk->XD(hit).prim, 2, S3D_POSITION, &v2)); /* Compute the edge vector */ f3_sub(E[0], v1.value, v0.value); @@ -351,7 +351,7 @@ XD(find_reinjection_ray) do { fX_set_dX(org, ray->org); - filter_data.XD(hit) = args->rwalk->hit; + filter_data.XD(hit) = args->rwalk->XD(hit); filter_data.epsilon = args->distance * 0.01; SXD(scene_view_trace_ray (scn->sXd(view), org, args->dir0, range, &filter_data, &hit0)); @@ -557,9 +557,9 @@ static res_T XD(handle_volumic_power) (struct sdis_medium* solid, struct rwalk_context* rwalk_ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, const double reinject_dst_m, - struct XD(temperature)* T) + struct temperature* T) { double power; double lambda; @@ -614,8 +614,8 @@ error: res_T XD(sample_reinjection_step_solid_fluid) (struct sdis_scene* scn, - const struct XD(sample_reinjection_step_args)* args, - struct XD(reinjection_step)* step) + const struct sample_reinjection_step_args* args, + struct reinjection_step* step) { /* Input/output data of the function finding a valid reinjection ray */ struct XD(find_reinjection_ray_args) find_reinject_ray_args = @@ -641,7 +641,7 @@ XD(sample_reinjection_step_solid_fluid) ASSERT(XD(check_sample_reinjection_step_args)(args)); /* Initialise the reinjection step */ - *step = XD(REINJECTION_STEP_NULL); + *step = REINJECTION_STEP_NULL; /* Check whether the solid enclosure is part of the system, or whether it is * only there to describe boundary conditions. In the latter case, the @@ -650,11 +650,11 @@ XD(sample_reinjection_step_solid_fluid) * that if the trajectory passes through the solid enclosure, it will stop, * i.e. the temperature of the solid should be fixed. If it doesn't, it's an * error */ - scene_get_enclosure_ids(scn, args->rwalk->hit.prim.prim_id, enc_ids); + scene_get_enclosure_ids(scn, args->rwalk->XD(hit).prim.prim_id, enc_ids); solid_enclosure = scene_get_enclosure(scn, enc_ids[args->side]); if(solid_enclosure->medium_id == ENCLOSURE_ID_MULTI_MEDIA) { - step->hit = SXD_HIT_NULL; - fX(normalize)(step->direction, args->rwalk->hit.normal); + step->XD(hit) = SXD_HIT_NULL; + fX(normalize)(step->direction, args->rwalk->XD(hit).normal); if(args->side == SDIS_BACK) fX(minus)(step->direction, step->direction); step->distance = (float)args->distance; goto exit; /* That's all folks! */ @@ -666,7 +666,7 @@ XD(sample_reinjection_step_solid_fluid) XD(sample_reinjection_dir)(args->rwalk, args->rng, dir0); /* Reflect the sampled direction around the normal */ - XD(reflect)(dir1, dir0, args->rwalk->hit.normal); + XD(reflect)(dir1, dir0, args->rwalk->XD(hit).normal); /* Flip the sampled directions if one wants to reinject to back side */ if(args->side == SDIS_BACK) { @@ -698,7 +698,7 @@ XD(sample_reinjection_step_solid_fluid) } /* Setup the reinjection step */ - step->hit = ray.hit; + step->XD(hit) = ray.hit; step->distance = ray.dst; fX(set)(step->direction, ray.dir); @@ -720,10 +720,10 @@ error: res_T XD(sample_reinjection_step_solid_solid) (struct sdis_scene* scn, - const struct XD(sample_reinjection_step_args)* args_frt, - const struct XD(sample_reinjection_step_args)* args_bck, - struct XD(reinjection_step)* step_frt, - struct XD(reinjection_step)* step_bck) + const struct sample_reinjection_step_args* args_frt, + const struct sample_reinjection_step_args* args_bck, + struct reinjection_step* step_frt, + struct reinjection_step* step_bck) { /* Input/output data of the function finding a valid reinjection ray */ struct XD(find_reinjection_ray_args) find_reinject_ray_frt_args = @@ -737,7 +737,7 @@ XD(sample_reinjection_step_solid_solid) double rwalk_pos_backup[DIM]; /* Variables shared by the two side */ - struct XD(rwalk)* rwalk = NULL; + struct rwalk* rwalk = NULL; struct ssp_rng* rng = NULL; /* In 2D it is useless to try to resample a reinjection direction since there @@ -764,7 +764,7 @@ XD(sample_reinjection_step_solid_solid) ASSERT(XD(check_sample_reinjection_step_args)(args_bck)); ASSERT(args_frt->side == SDIS_FRONT); ASSERT(args_bck->side == SDIS_BACK); - ASSERT(SXD_PRIMITIVE_EQ(&args_frt->rwalk->hit.prim, &args_bck->rwalk->hit.prim)); + ASSERT(SXD_PRIMITIVE_EQ(&args_frt->rwalk->XD(hit).prim, &args_bck->rwalk->XD(hit).prim)); rng = args_frt->rng; rwalk = args_frt->rwalk; @@ -772,8 +772,8 @@ XD(sample_reinjection_step_solid_solid) ASSERT(args_bck->rwalk == rwalk); /* Initialise the reinjection steps */ - *step_frt = XD(REINJECTION_STEP_NULL); - *step_bck = XD(REINJECTION_STEP_NULL); + *step_frt = REINJECTION_STEP_NULL; + *step_bck = REINJECTION_STEP_NULL; /* Check whether the solid enclosure is part of the system, or whether it is * only there to describe boundary conditions. In the latter case, the @@ -782,18 +782,18 @@ XD(sample_reinjection_step_solid_solid) * that if the trajectory passes through the solid enclosure, it will stop, * i.e. the temperature of the solid should be fixed. If it doesn't, it's an * error */ - scene_get_enclosure_ids(scn, args_frt->rwalk->hit.prim.prim_id, enc_ids); + scene_get_enclosure_ids(scn, args_frt->rwalk->XD(hit).prim.prim_id, enc_ids); enclosure_frt = scene_get_enclosure(scn, enc_ids[SDIS_FRONT]); enclosure_bck = scene_get_enclosure(scn, enc_ids[SDIS_BACK]); if(enclosure_frt->medium_id == ENCLOSURE_ID_MULTI_MEDIA) { - step_frt->hit = SXD_HIT_NULL; - fX(normalize)(step_frt->direction, args_frt->rwalk->hit.normal); + step_frt->XD(hit) = SXD_HIT_NULL; + fX(normalize)(step_frt->direction, args_frt->rwalk->XD(hit).normal); step_frt->distance = (float)args_frt->distance; multiple_media_frt = 1; } if(enclosure_bck->medium_id == ENCLOSURE_ID_MULTI_MEDIA) { - step_bck->hit = SXD_HIT_NULL; - fX(normalize)(step_bck->direction, args_bck->rwalk->hit.normal); + step_bck->XD(hit) = SXD_HIT_NULL; + fX(normalize)(step_bck->direction, args_bck->rwalk->XD(hit).normal); fX(minus)(step_bck->direction, step_bck->direction); step_bck->distance = (float)args_bck->distance; multiple_media_bck = 1; @@ -811,7 +811,7 @@ XD(sample_reinjection_step_solid_solid) /* 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_frt_samp); - XD(reflect)(dir_frt_refl, dir_frt_samp, rwalk->hit.normal); + XD(reflect)(dir_frt_refl, dir_frt_samp, rwalk->XD(hit).normal); fX(minus)(dir_bck_samp, dir_frt_samp); fX(minus)(dir_bck_refl, dir_frt_refl); @@ -881,13 +881,13 @@ XD(sample_reinjection_step_solid_solid) /* Setup the front and back reinjection steps */ if(!multiple_media_frt) { - step_frt->hit = ray_frt.hit; + step_frt->XD(hit) = ray_frt.hit; step_frt->distance = ray_frt.dst; fX(set)(step_frt->direction, ray_frt.dir); ASSERT(XD(check_reinjection_step)(step_frt)); /* Post-condition */ } if(!multiple_media_bck) { - step_bck->hit = ray_bck.hit; + step_bck->XD(hit) = ray_bck.hit; step_bck->distance = ray_bck.dst; fX(set)(step_bck->direction, ray_bck.dir); ASSERT(XD(check_reinjection_step)(step_bck)); /* Post-condition */ @@ -902,7 +902,7 @@ error: res_T XD(solid_reinjection) (struct sdis_medium* solid, - struct XD(solid_reinjection_args)* args) + struct solid_reinjection_args* args) { struct solid_props props = SOLID_PROPS_NULL; double reinject_dst_m; /* Reinjection distance in meters */ @@ -923,7 +923,7 @@ XD(solid_reinjection) /* Time rewind */ args->rwalk->mdm = solid; /* Medium into which the time is rewind */ mu = (2*DIM*props.lambda)/(props.rho*props.cp*reinject_dst_m*reinject_dst_m); - res = XD(time_rewind) + res = time_rewind (mu, props.t0, args->rng, args->rwalk, args->rwalk_ctx, args->T); if(res != RES_OK) goto error; @@ -937,18 +937,18 @@ XD(solid_reinjection) args->reinjection->distance); /* The random walk is in the solid */ - if(args->reinjection->hit.distance != args->reinjection->distance) { + if(args->reinjection->XD(hit).distance != args->reinjection->distance) { args->T->func = XD(conductive_path); args->rwalk->mdm = solid; - args->rwalk->hit = SXD_HIT_NULL; + args->rwalk->XD(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->XD(hit) = args->reinjection->XD(hit); + if(fX(dot)(args->reinjection->XD(hit).normal, args->reinjection->direction) < 0) { args->rwalk->hit_side = SDIS_FRONT; } else { args->rwalk->hit_side = SDIS_BACK; @@ -974,7 +974,7 @@ res_T XD(handle_net_flux) (const struct sdis_scene* scn, const struct handle_net_flux_args* args, - struct XD(temperature)* T) + struct temperature* T) { double flux_term; double phi; diff --git a/src/sdis_heat_path_boundary_Xd_handle_external_net_flux.h b/src/sdis_heat_path_boundary_Xd_handle_external_net_flux.h @@ -173,7 +173,7 @@ static INLINE res_T XD(check_handle_external_net_flux_args) (const struct sdis_scene* scn, const char* func_name, - const struct XD(handle_external_net_flux_args)* args) + const struct handle_external_net_flux_args* args) { int net_flux = 0; res_T res = RES_OK; @@ -181,7 +181,7 @@ XD(check_handle_external_net_flux_args) /* Handle bugs */ ASSERT(scn && func_name && args); ASSERT(args->interf && args->frag); - ASSERT(!SXD_HIT_NONE(args->hit)); + ASSERT(!SXD_HIT_NONE(args->XD(hit))); ASSERT(args->h_cond >= 0 && args->h_conv >= 0 && args->h_radi >= 0); ASSERT(args->h_cond + args->h_conv + args->h_radi > 0); @@ -453,8 +453,8 @@ res_T XD(handle_external_net_flux) (const struct sdis_scene* scn, struct ssp_rng* rng, - const struct XD(handle_external_net_flux_args)* args, - struct XD(temperature)* T) + const struct handle_external_net_flux_args* args, + struct temperature* T) { /* Terms to be registered in the green function */ struct sdis_green_external_flux_terms green = @@ -516,13 +516,13 @@ XD(handle_external_net_flux) * interface side */ cos_theta = d3_dot(N, src_sample.dir); if(cos_theta > 0) { - Ld = XD(direct_contribution)(scn, &src_sample, frag.P, args->hit); + Ld = XD(direct_contribution)(scn, &src_sample, frag.P, args->XD(hit)); incident_flux_direct = cos_theta * Ld / src_sample.pdf; /* [W/m^2] */ } /* Calculate the incident diffuse flux [W/m^2] */ res = XD(compute_incident_diffuse_flux) - (scn, rng, frag.P, N, frag.time, args->hit, &incident_flux_diffuse); + (scn, rng, frag.P, N, frag.time, args->XD(hit), &incident_flux_diffuse); if(res != RES_OK) goto error; /* Calculate the incident flux without the part scattered by the environment. diff --git a/src/sdis_heat_path_boundary_Xd_solid_fluid_picard1.h b/src/sdis_heat_path_boundary_Xd_solid_fluid_picard1.h @@ -31,8 +31,8 @@ static INLINE res_T XD(rwalk_get_Tref) (const struct sdis_scene* scn, - const struct XD(rwalk)* rwalk, - const struct XD(temperature)* T, + const struct rwalk* rwalk, + const struct temperature* T, double* out_Tref) { double Tref = SDIS_TEMPERATURE_NONE; @@ -52,16 +52,16 @@ XD(rwalk_get_Tref) } else { struct sdis_interface_fragment frag; struct sdis_interface* interf = NULL; - ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!SXD_HIT_NONE(&rwalk->XD(hit))); /* Fetch the interface where the random walk ends */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); + interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id); ASSERT(rwalk->hit_side!=SDIS_FRONT || interf->medium_front->type==SDIS_FLUID); ASSERT(rwalk->hit_side!=SDIS_BACK || interf->medium_back->type==SDIS_FLUID); /* Fragment on the fluid side of the boundary onto which the rwalk ends */ XD(setup_interface_fragment) - (&frag, &rwalk->vtx, &rwalk->hit, rwalk->hit_side); + (&frag, &rwalk->vtx, &rwalk->XD(hit), rwalk->hit_side); Tref = interface_side_get_reference_temperature(interf, &frag); } @@ -85,26 +85,25 @@ XD(solid_fluid_boundary_picard1_path) (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { /* Input argument used to handle the net flux */ struct handle_net_flux_args handle_net_flux_args = HANDLE_NET_FLUX_ARGS_NULL; /* Input argument used to handle the external net flux */ - struct XD(handle_external_net_flux_args) handle_external_net_flux_args = - XD(HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL); + struct handle_external_net_flux_args handle_external_net_flux_args = + HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL; /* 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); + struct sample_reinjection_step_args samp_reinject_step_args = + SAMPLE_REINJECTION_STEP_ARGS_NULL; + struct reinjection_step reinject_step = REINJECTION_STEP_NULL; /* Temperature and random walk state of the sampled radiative path */ - struct XD(temperature) T_s; - struct XD(rwalk) rwalk_s; + struct temperature T_s; + struct rwalk rwalk_s; /* Fragment on the fluid side of the boundary */ struct sdis_interface_fragment frag_fluid; @@ -139,7 +138,7 @@ XD(solid_fluid_boundary_picard1_path) ASSERT(XD(check_rwalk_fragment_consistency)(rwalk, frag)); /* Retrieve the solid and the fluid split by the boundary */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); + interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id); solid = interface_get_medium(interf, SDIS_FRONT); fluid = interface_get_medium(interf, SDIS_BACK); solid_side = SDIS_FRONT; @@ -222,7 +221,7 @@ XD(solid_fluid_boundary_picard1_path) /* Handle the external net flux if any */ handle_external_net_flux_args.interf = interf; handle_external_net_flux_args.frag = frag; - handle_external_net_flux_args.hit = &rwalk->hit; + handle_external_net_flux_args.XD(hit) = &rwalk->XD(hit); handle_external_net_flux_args.green_path = ctx->green_path; handle_external_net_flux_args.picard_order = get_picard_order(ctx); handle_external_net_flux_args.h_cond = h_cond; @@ -255,8 +254,8 @@ XD(solid_fluid_boundary_picard1_path) /* Switch in conductive path */ if(r < p_conv + p_cond) { - struct XD(solid_reinjection_args) solid_reinject_args = - XD(SOLID_REINJECTION_ARGS_NULL); + struct solid_reinjection_args solid_reinject_args = + SOLID_REINJECTION_ARGS_NULL; /* Perform the reinjection into the solid */ solid_reinject_args.reinjection = &reinject_step; diff --git a/src/sdis_heat_path_boundary_Xd_solid_fluid_picardN.h b/src/sdis_heat_path_boundary_Xd_solid_fluid_picardN.h @@ -66,23 +66,23 @@ error: static INLINE res_T XD(sample_path) (struct sdis_scene* scn, - const struct XD(rwalk)* rwalk_from, + const struct rwalk* rwalk_from, struct rwalk_context* ctx, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { - struct XD(rwalk) rwalk = XD(RWALK_NULL); + struct rwalk rwalk = RWALK_NULL; res_T res = RES_OK; ASSERT(rwalk_from && rng && T); /* Clean-up the output variable */ - *T = XD(TEMPERATURE_NULL); + *T = TEMPERATURE_NULL; T->func = XD(boundary_path); /* Init the random walk */ rwalk.vtx = rwalk_from->vtx; rwalk.mdm = rwalk_from->mdm; - rwalk.hit = rwalk_from->hit; + rwalk.XD(hit) = rwalk_from->XD(hit); rwalk.hit_side = rwalk_from->hit_side; /* Start the registration of a new heat path */ @@ -128,15 +128,14 @@ XD(solid_fluid_boundary_picardN_path) (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct 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); + struct sample_reinjection_step_args samp_reinject_step_args = + SAMPLE_REINJECTION_STEP_ARGS_NULL; + struct reinjection_step reinject_step = REINJECTION_STEP_NULL; /* Fragment on the fluid side of the boundary */ struct sdis_interface_fragment frag_fluid; @@ -184,7 +183,7 @@ XD(solid_fluid_boundary_picardN_path) That3 = ctx->That3; /* Retrieve the solid and the fluid split by the boundary */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); + interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id); solid = interface_get_medium(interf, SDIS_FRONT); fluid = interface_get_medium(interf, SDIS_BACK); solid_side = SDIS_FRONT; @@ -256,8 +255,8 @@ XD(solid_fluid_boundary_picardN_path) /* Null collision main loop */ for(;;) { /* Temperature and random walk state of the sampled radiative path */ - struct XD(temperature) T_s; - struct XD(rwalk) rwalk_s; + struct temperature T_s; + struct rwalk rwalk_s; double h_radi, h_radi_min, h_radi_max; /* Radiative coefficients */ double p_radi, p_radi_min, p_radi_max; /* Radiative probas */ @@ -279,8 +278,8 @@ XD(solid_fluid_boundary_picardN_path) /* Switch in conductive path */ if(r < p_conv + p_cond) { - struct XD(solid_reinjection_args) solid_reinject_args = - XD(SOLID_REINJECTION_ARGS_NULL); + struct solid_reinjection_args solid_reinject_args = + SOLID_REINJECTION_ARGS_NULL; /* Perform the reinjection into the solid */ solid_reinject_args.reinjection = &reinject_step; @@ -340,9 +339,9 @@ XD(solid_fluid_boundary_picardN_path) } (void)0 #define COMPUTE_TEMPERATURE(Result, RWalk, Temp) { \ - struct XD(temperature) T_p; \ + struct temperature T_p; \ if((Temp)->done) { /* Ambient radiative temperature */ \ - ASSERT(SXD_HIT_NONE(&(RWalk)->hit)); \ + ASSERT(SXD_HIT_NONE(&(RWalk)->XD(hit))); \ T_p = *(Temp); \ } else { \ res = XD(sample_path)(scn, RWalk, ctx, rng, &T_p); \ diff --git a/src/sdis_heat_path_boundary_Xd_solid_solid.h b/src/sdis_heat_path_boundary_Xd_solid_solid.h @@ -33,22 +33,22 @@ XD(solid_solid_boundary_path) (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { /* 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; + struct sample_reinjection_step_args samp_reinject_step_frt_args = + SAMPLE_REINJECTION_STEP_ARGS_NULL; + struct sample_reinjection_step_args samp_reinject_step_bck_args = + SAMPLE_REINJECTION_STEP_ARGS_NULL; + struct reinjection_step reinject_step_frt = REINJECTION_STEP_NULL; + struct reinjection_step reinject_step_bck = REINJECTION_STEP_NULL; + struct reinjection_step* reinject_step = NULL; /* Reinjection arguments */ - struct XD(solid_reinjection_args) solid_reinject_args = - XD(SOLID_REINJECTION_ARGS_NULL); + struct solid_reinjection_args solid_reinject_args = + SOLID_REINJECTION_ARGS_NULL; /* Data attached to the boundary */ struct sdis_interface* interf = NULL; @@ -71,7 +71,7 @@ XD(solid_solid_boundary_path) (void)frag, (void)ctx; /* Retrieve the two solids split by the boundary */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); + interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id); solid_frt = interface_get_medium(interf, SDIS_FRONT); solid_bck = interface_get_medium(interf, SDIS_BACK); ASSERT(solid_frt->type == SDIS_SOLID); @@ -102,7 +102,7 @@ XD(solid_solid_boundary_path) samp_reinject_step_frt_args.side = SDIS_FRONT; samp_reinject_step_bck_args.side = SDIS_BACK; res = XD(sample_reinjection_step_solid_solid) - (scn, + (scn, &samp_reinject_step_frt_args, &samp_reinject_step_bck_args, &reinject_step_frt, diff --git a/src/sdis_heat_path_boundary_c.h b/src/sdis_heat_path_boundary_c.h @@ -21,123 +21,90 @@ #include <rsys/rsys.h> /* Forward declarations */ -struct rwalk_2d; -struct rwalk_3d; +struct rwalk; struct sdis_scene; struct sdis_medium; /******************************************************************************* * Sample a reinjection step ******************************************************************************/ -struct sample_reinjection_step_args_2d { +struct sample_reinjection_step_args { 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 */ + struct rwalk* 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 */ -}; +#define SAMPLE_REINJECTION_STEP_ARGS_NULL__ \ + {NULL, NULL, NULL, -1, SDIS_SIDE_NULL__} +static const struct sample_reinjection_step_args +SAMPLE_REINJECTION_STEP_ARGS_NULL = SAMPLE_REINJECTION_STEP_ARGS_NULL__; -struct reinjection_step_3d { - struct s3d_hit hit; /* Intersection along the reinjection direction */ +struct reinjection_step { + struct s2d_hit hit_2d; /* 2D Intersection along the reinjection direction */ + struct s3d_hit hit_3d; /* 3D 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; +#define REINJECTION_STEP_NULL__ {S2D_HIT_NULL__, S3D_HIT_NULL__, {0,0,0}, 0} +static const struct reinjection_step REINJECTION_STEP_NULL = + REINJECTION_STEP_NULL__; extern LOCAL_SYM res_T sample_reinjection_step_solid_fluid_2d (struct sdis_scene* scn, - const struct sample_reinjection_step_args_2d* args, - struct reinjection_step_2d* step); + const struct sample_reinjection_step_args* args, + struct reinjection_step* step); extern LOCAL_SYM res_T sample_reinjection_step_solid_fluid_3d (struct sdis_scene* scn, - const struct sample_reinjection_step_args_3d* args, - struct reinjection_step_3d *step); + const struct sample_reinjection_step_args* args, + struct reinjection_step *step); extern LOCAL_SYM res_T sample_reinjection_step_solid_solid_2d (struct sdis_scene* scn, - 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); + const struct sample_reinjection_step_args* args_front, + const struct sample_reinjection_step_args* args_back, + struct reinjection_step* step_front, + struct reinjection_step* step_back); extern LOCAL_SYM res_T sample_reinjection_step_solid_solid_3d (struct sdis_scene* scn, - 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); + const struct sample_reinjection_step_args* args_front, + const struct sample_reinjection_step_args* args_back, + struct reinjection_step* step_front, + struct reinjection_step* step_back); /******************************************************************************* * Reinject the random walk into a solid ******************************************************************************/ -struct solid_reinjection_args_2d { - const struct reinjection_step_2d* reinjection; /* Reinjection to do */ - 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 */ +struct solid_reinjection_args { + const struct reinjection_step* reinjection; /* Reinjection to do */ struct rwalk_context* rwalk_ctx; - struct rwalk_3d* rwalk; /* Current state of the random walk */ + struct rwalk* rwalk; /* Current state of the random walk */ struct ssp_rng* rng; /* Random number generator */ - struct temperature_3d* T; + struct temperature* 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; +#define SOLID_REINJECTION_ARGS_NULL__ {NULL,NULL,NULL,NULL,NULL,0} +static const struct solid_reinjection_args SOLID_REINJECTION_ARGS_NULL = + SOLID_REINJECTION_ARGS_NULL__; extern LOCAL_SYM res_T solid_reinjection_2d (struct sdis_medium* solid, - struct solid_reinjection_args_2d* args); + struct solid_reinjection_args* args); extern LOCAL_SYM res_T solid_reinjection_3d (struct sdis_medium* solid, - struct solid_reinjection_args_3d* args); + struct solid_reinjection_args* args); /******************************************************************************* * Handle net flux @@ -160,21 +127,22 @@ extern LOCAL_SYM res_T handle_net_flux_2d (const struct sdis_scene* scn, const struct handle_net_flux_args* args, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T handle_net_flux_3d (const struct sdis_scene* scn, const struct handle_net_flux_args* args, - struct temperature_3d* T); + struct temperature* T); /******************************************************************************* * Handle external flux ******************************************************************************/ -struct handle_external_net_flux_args_2d { +struct handle_external_net_flux_args { struct sdis_interface* interf; const struct sdis_interface_fragment* frag; - const struct s2d_hit* hit; + const struct s2d_hit* hit_2d; + const struct s3d_hit* hit_3d; struct green_path_handle* green_path; /* Store the propagator */ struct sdis_heat_path* heat_path; /* Save paths */ @@ -199,26 +167,23 @@ struct handle_external_net_flux_args_3d { double h_radi; /* Radiative coefficient */ }; -#define HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL___2d {NULL,NULL,NULL,NULL,NULL,0,0,0,0} -#define HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL___3d {NULL,NULL,NULL,NULL,NULL,0,0,0,0} -static const struct handle_external_net_flux_args_2d -HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL_2d = HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL___2d; -static const struct handle_external_net_flux_args_3d -HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL_3d = HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL___3d; +#define HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL__ {NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0} +static const struct handle_external_net_flux_args +HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL = HANDLE_EXTERNAL_NET_FLUX_ARGS_NULL__; extern LOCAL_SYM res_T handle_external_net_flux_2d (const struct sdis_scene* scn, struct ssp_rng* rng, - const struct handle_external_net_flux_args_2d* args, - struct temperature_2d* T); + const struct handle_external_net_flux_args* args, + struct temperature* T); extern LOCAL_SYM res_T handle_external_net_flux_3d (const struct sdis_scene* scn, struct ssp_rng* rng, - const struct handle_external_net_flux_args_3d* args, - struct temperature_3d* T); + const struct handle_external_net_flux_args* args, + struct temperature* T); /******************************************************************************* * Miscellaneous functions @@ -246,9 +211,9 @@ solid_boundary_with_flux_path_2d struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, const double phi, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T solid_boundary_with_flux_path_3d @@ -256,62 +221,62 @@ solid_boundary_with_flux_path_3d struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, const double phi, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T); + struct temperature* T); extern LOCAL_SYM res_T solid_fluid_boundary_picard1_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T solid_fluid_boundary_picard1_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T); + struct temperature* T); extern LOCAL_SYM res_T solid_fluid_boundary_picardN_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T solid_fluid_boundary_picardN_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T); + struct temperature* T); extern LOCAL_SYM res_T solid_solid_boundary_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T solid_solid_boundary_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, const struct sdis_interface_fragment* frag, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T); + struct temperature* T); #endif /* SDIS_HEAT_PATH_BOUNDARY_C_H */ diff --git a/src/sdis_heat_path_conductive.c b/src/sdis_heat_path_conductive.c @@ -75,9 +75,9 @@ res_T conductive_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T) + struct temperature* T) { res_T res = RES_OK; ASSERT(ctx); @@ -98,9 +98,9 @@ res_T conductive_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T) + struct temperature* T) { res_T res = RES_OK; ASSERT(ctx); diff --git a/src/sdis_heat_path_conductive_c.h b/src/sdis_heat_path_conductive_c.h @@ -19,15 +19,13 @@ #include <rsys/rsys.h> /* Forward declarations */ -struct rwalk_2d; -struct rwalk_3d; +struct rwalk; struct rwalk_context; struct sdis_device; struct sdis_scene; struct solid_props; struct ssp_rng; -struct temperature_2d; -struct temperature_3d; +struct temperature; extern LOCAL_SYM res_T check_solid_constant_properties @@ -44,17 +42,17 @@ extern LOCAL_SYM res_T conductive_path_delta_sphere_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T conductive_path_delta_sphere_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T); + struct temperature* T); /******************************************************************************* * Conductive paths using the walk on sphere algorithm @@ -63,16 +61,16 @@ extern LOCAL_SYM res_T conductive_path_wos_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T conductive_path_wos_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T); + struct temperature* T); #endif /* SDIS_HEAT_PATH_CONDUCTIVE_C_H */ diff --git a/src/sdis_heat_path_conductive_delta_sphere_Xd.h b/src/sdis_heat_path_conductive_delta_sphere_Xd.h @@ -239,7 +239,7 @@ XD(handle_volumic_power) (const struct sdis_scene* scn, const struct XD(handle_volumic_power_args)* args, double* out_power_term, - struct XD(temperature)* T) + struct temperature* T) { double power_term = 0; res_T res = RES_OK; @@ -332,9 +332,9 @@ res_T XD(conductive_path_delta_sphere) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { /* Enclosure/medium in which the conductive path starts */ struct sdis_medium* mdm = NULL; @@ -450,16 +450,16 @@ XD(conductive_path_delta_sphere) /* Rewind the time */ delta_m = delta * scn->fp_to_meter; mu = (2*DIM*props.lambda)/(props.rho*props.cp*delta_m*delta_m); - res = XD(time_rewind)(mu, props.t0, rng, rwalk, ctx, T); + res = time_rewind(mu, props.t0, rng, rwalk, ctx, T); if(res != RES_OK) goto error; if(T->done) break; /* Limit condition was reached */ /* Define if the random walk hits something along dir0 */ if(hit0.distance > delta) { - rwalk->hit = SXD_HIT_NULL; + rwalk->XD(hit) = SXD_HIT_NULL; rwalk->hit_side = SDIS_SIDE_NULL__; } else { - rwalk->hit = hit0; + rwalk->XD(hit) = hit0; rwalk->hit_side = fX(dot)(hit0.normal, dir0) < 0 ? SDIS_FRONT : SDIS_BACK; } @@ -474,7 +474,7 @@ XD(conductive_path_delta_sphere) ++istep; /* Keep going while the solid random walk does not hit an interface */ - } while(SXD_HIT_NONE(&rwalk->hit)); + } while(SXD_HIT_NONE(&rwalk->XD(hit))); /* Register the power term for the green function */ if(ctx->green_path && props_ref.power != SDIS_VOLUMIC_POWER_NONE) { diff --git a/src/sdis_heat_path_conductive_wos_Xd.h b/src/sdis_heat_path_conductive_wos_Xd.h @@ -23,12 +23,81 @@ #include "sdis_Xd_begin.h" /******************************************************************************* + * Non generic helper functions + ******************************************************************************/ +#ifndef SDIS_HEAT_PATH_CONDUCTIVE_WOS_XD_H +#define SDIS_HEAT_PATH_CONDUCTIVE_WOS_XD_H + +static res_T +handle_volumic_power_wos + (struct sdis_scene* scn, + const struct solid_props* props, + const double distance, /* [m/fp_to_meter] */ + double* power_term, + struct temperature* T) +{ + double dst = distance * scn->fp_to_meter; /* [m] */ + double term = 0; + res_T res = RES_OK; + ASSERT(scn && props && distance >= 0 && power_term && T); + + if(props->power == SDIS_VOLUMIC_POWER_NONE) goto exit; + + /* No displacement => no power density */ + if(distance == 0) goto exit; + + term = dst*dst / (2*DIM*props->lambda); + T->value += props->power * term; + +exit: + *power_term = term; + return res; +} + +static res_T +update_green_path + (struct green_path_handle* green_path, + struct rwalk* rwalk, + struct sdis_medium* mdm, + const struct solid_props* props, + const double power_term, + const struct temperature* T) +{ + res_T res = RES_OK; + ASSERT(mdm && props && T); + + /* Is the green function estimated? */ + if(!green_path) goto exit; + + /* Save power term for green function if any */ + if(props->power != SDIS_VOLUMIC_POWER_NONE) { + res = green_path_add_power_term(green_path, mdm, &rwalk->vtx, power_term); + if(res != RES_OK) goto error; + } + + /* Set the green path limit to the current position if the initial condition + * has been reached */ + if(T->done) { + res = green_path_set_limit_vertex + (green_path, mdm, &rwalk->vtx, rwalk->elapsed_time); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + +#endif /* SDIS_HEAT_PATH_CONDUCTIVE_WOS_XD_H */ + +/******************************************************************************* * Helper function ******************************************************************************/ static res_T XD(check_medium_consistency) (struct sdis_scene* scn, - const struct XD(rwalk)* rwalk) + const struct rwalk* rwalk) { unsigned enc_id = ENCLOSURE_ID_NULL; struct sdis_medium* mdm = NULL; @@ -58,12 +127,12 @@ error: static res_T XD(time_travel) (struct sdis_scene* scn, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, const double alpha, /* Diffusivity, i.e. lambda/(rho*cp) */ const double t0, /* Initial time [s] */ double* distance, /* Displacement [m/fp_to_meter] */ - struct XD(temperature)* T) + struct temperature* T) { double dir[DIM] = {0}; double dst = 0; /* Distance [m] */ @@ -261,7 +330,7 @@ static res_T XD(setup_hit_wos) (struct sdis_scene* scn, const struct sXd(hit)* hit, - struct XD(rwalk)* rwalk) + struct rwalk* rwalk) { /* Geometry */ struct sXd(primitive) prim; @@ -308,7 +377,7 @@ XD(setup_hit_wos) * the interface. So we can't yet assume that the random walk has left the * current medium */ dX(set)(rwalk->vtx.P, tgt); - rwalk->hit = *hit; + rwalk->XD(hit) = *hit; rwalk->hit_side = side; exit: @@ -323,7 +392,7 @@ XD(setup_hit_rt) const double pos[DIM], const double dir[DIM], const struct sXd(hit)* hit, - struct XD(rwalk)* rwalk) + struct rwalk* rwalk) { /* Properties */ struct sdis_interface* interf = NULL; @@ -363,7 +432,7 @@ XD(setup_hit_rt) * the interface. So we can't yet assume that the random walk has left the * current medium */ dX(set)(rwalk->vtx.P, tgt); - rwalk->hit = *hit; + rwalk->XD(hit) = *hit; rwalk->hit_side = side; exit: @@ -375,7 +444,7 @@ error: static res_T XD(sample_next_position) (struct sdis_scene* scn, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, double* distance) /* Displacement distance */ { @@ -481,67 +550,6 @@ error: goto exit; } -static res_T -XD(handle_volumic_power_wos) - (struct sdis_scene* scn, - const struct solid_props* props, - const double distance, /* [m/fp_to_meter] */ - double* power_term, - struct XD(temperature)* T) -{ - double dst = distance * scn->fp_to_meter; /* [m] */ - double term = 0; - res_T res = RES_OK; - ASSERT(scn && props && distance >= 0 && power_term && T); - - if(props->power == SDIS_VOLUMIC_POWER_NONE) goto exit; - - /* No displacement => no power density */ - if(distance == 0) goto exit; - - term = dst*dst / (2*DIM*props->lambda); - T->value += props->power * term; - -exit: - *power_term = term; - return res; -} - -static res_T -XD(update_green_path) - (struct green_path_handle* green_path, - struct XD(rwalk)* rwalk, - struct sdis_medium* mdm, - const struct solid_props* props, - const double power_term, - const struct XD(temperature)* T) -{ - res_T res = RES_OK; - ASSERT(mdm && props && T); - - /* Is the green function estimated? */ - if(!green_path) goto exit; - - /* Save power term for green function if any */ - if(props->power != SDIS_VOLUMIC_POWER_NONE) { - res = green_path_add_power_term(green_path, mdm, &rwalk->vtx, power_term); - if(res != RES_OK) goto error; - } - - /* Set the green path limit to the current position if the initial condition - * has been reached */ - if(T->done) { - res = green_path_set_limit_vertex - (green_path, mdm, &rwalk->vtx, rwalk->elapsed_time); - if(res != RES_OK) goto error; - } - -exit: - return res; -error: - goto exit; -} - /******************************************************************************* * Local function ******************************************************************************/ @@ -549,9 +557,9 @@ res_T XD(conductive_path_wos) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { /* Properties */ struct sdis_medium* mdm = NULL; @@ -627,7 +635,7 @@ XD(conductive_path_wos) if(res != RES_OK) goto error; /* Add the volumic power density */ - res = XD(handle_volumic_power_wos)(scn, &props, dst, &power_term, T); + res = handle_volumic_power_wos(scn, &props, dst, &power_term, T); if(res != RES_OK) goto error; REGISTER_HEAT_VERTEX; @@ -642,7 +650,7 @@ XD(conductive_path_wos) } /* The path reaches a boundary */ - if(!SXD_HIT_NONE(&rwalk->hit)) { + if(!SXD_HIT_NONE(&rwalk->XD(hit))) { T->func = XD(boundary_path); rwalk->mdm = NULL; break; @@ -660,7 +668,7 @@ XD(conductive_path_wos) } /* Save green function data */ - res = XD(update_green_path) + res = update_green_path (ctx->green_path, rwalk, mdm, &props_ref, green_power_term, T); exit: diff --git a/src/sdis_heat_path_convective_Xd.h b/src/sdis_heat_path_convective_Xd.h @@ -69,7 +69,7 @@ static res_T XD(register_heat_vertex_in_fluid) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, const double weight) { struct sdis_rwalk_vertex vtx = SDIS_RWALK_VERTEX_NULL; @@ -84,13 +84,13 @@ XD(register_heat_vertex_in_fluid) if(!ctx->heat_path) return RES_OK; - ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!SXD_HIT_NONE(&rwalk->XD(hit))); fX_set_dX(org, rwalk->vtx.P); - fX(set)(dir, rwalk->hit.normal); + fX(set)(dir, rwalk->XD(hit).normal); if(rwalk->hit_side == SDIS_BACK) fX(minus)(dir, dir); - filter_data.XD(hit) = rwalk->hit; + filter_data.XD(hit) = rwalk->XD(hit); filter_data.epsilon = 1.e-6; SXD(scene_view_trace_ray(scn->sXd(view), org, dir, range, &filter_data, &hit)); dst = SXD_HIT_NONE(&hit) ? empirical_dst : hit.distance * 0.5f; @@ -107,8 +107,8 @@ static res_T XD(handle_known_fluid_temperature) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, - struct XD(temperature)* T) + struct rwalk* rwalk, + struct temperature* T) { double temperature; int known_temperature; @@ -143,7 +143,7 @@ error: static res_T XD(handle_convective_path_startup) (struct sdis_scene* scn, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, int* path_starts_in_fluid) { const float range[2] = {FLT_MIN, FLT_MAX}; @@ -153,7 +153,7 @@ XD(handle_convective_path_startup) ASSERT(scn && rwalk && path_starts_in_fluid); ASSERT(sdis_medium_get_type(rwalk->mdm) == SDIS_FLUID); - *path_starts_in_fluid = SXD_HIT_NONE(&rwalk->hit); + *path_starts_in_fluid = SXD_HIT_NONE(&rwalk->XD(hit)); if(*path_starts_in_fluid == 0) goto exit; /* Nothing to do */ dir[DIM-1] = 1; @@ -161,8 +161,8 @@ XD(handle_convective_path_startup) /* Init the path hit field required to define the current enclosure and * fetch the interface data */ - SXD(scene_view_trace_ray(scn->sXd(view), org, dir, range, NULL, &rwalk->hit)); - if(SXD_HIT_NONE(&rwalk->hit)) { + SXD(scene_view_trace_ray(scn->sXd(view), org, dir, range, NULL, &rwalk->XD(hit))); + if(SXD_HIT_NONE(&rwalk->XD(hit))) { log_err(scn->dev, "%s: the position %g %g %g lies in the surrounding fluid whose " "temperature must be known.\n", FUNC_NAME, SPLIT3(rwalk->vtx.P)); @@ -170,7 +170,8 @@ XD(handle_convective_path_startup) goto error; } - rwalk->hit_side = fX(dot)(rwalk->hit.normal, dir) < 0 ? SDIS_FRONT : SDIS_BACK; + rwalk->hit_side = fX(dot)(rwalk->XD(hit).normal, dir) < 0 + ? SDIS_FRONT : SDIS_BACK; exit: return res; @@ -181,7 +182,7 @@ error: static res_T XD(fetch_fluid_enclosure) (struct sdis_scene* scn, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, const struct enclosure** out_enclosure) { const struct sdis_interface* interf; @@ -191,11 +192,11 @@ XD(fetch_fluid_enclosure) res_T res = RES_OK; ASSERT(scn && rwalk && out_enclosure); ASSERT(sdis_medium_get_type(rwalk->mdm) == SDIS_FLUID); - ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!SXD_HIT_NONE(&rwalk->XD(hit))); /* Fetch the current interface and its associated enclosures */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); - scene_get_enclosure_ids(scn, rwalk->hit.prim.prim_id, enc_ids); + interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id); + scene_get_enclosure_ids(scn, rwalk->XD(hit).prim.prim_id, enc_ids); /* Find the enclosure identifier of the current medium */ ASSERT(interf->medium_front != interf->medium_back); @@ -237,14 +238,15 @@ res_T XD(convective_path) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { struct sXd(attrib) attr_P, attr_N; struct fluid_props props_ref = FLUID_PROPS_NULL; - const struct sdis_interface* interf; - const struct enclosure* enc; + const struct sdis_interface* interf = NULL; + const struct enclosure* enc = NULL; + struct sXd(hit)* rwalk_hit = NULL; double r; #if SDIS_XD_DIMENSION == 2 float st; @@ -257,6 +259,8 @@ XD(convective_path) ASSERT(scn && ctx && rwalk && rng && T); ASSERT(rwalk->mdm->type == SDIS_FLUID); + rwalk_hit = &rwalk->XD(hit); + res = XD(handle_known_fluid_temperature)(scn, ctx, rwalk, T); if(res != RES_OK) goto error; if(T->done) goto exit; /* The fluid temperature is known */ @@ -308,7 +312,7 @@ XD(convective_path) /* Sample the time using the upper bound. */ mu = enc->hc_upper_bound / (props.rho * props.cp) * enc->S_over_V; - res = XD(time_rewind)(mu, props.t0, rng, rwalk, ctx, T); + res = time_rewind(mu, props.t0, rng, rwalk, ctx, T); if(res != RES_OK) goto error; if(T->done) break; /* Limit condition was reached */ @@ -318,29 +322,29 @@ XD(convective_path) (enc->sXd(view), ssp_rng_canonical_float(rng), ssp_rng_canonical_float(rng), - &prim, &rwalk->hit.u)); - st = rwalk->hit.u; + &prim, &rwalk_hit->u)); + st = rwalk_hit->u; #else SXD(scene_view_sample (enc->sXd(view), ssp_rng_canonical_float(rng), ssp_rng_canonical_float(rng), ssp_rng_canonical_float(rng), - &prim, rwalk->hit.uv)); - f2_set(st, rwalk->hit.uv); + &prim, rwalk_hit->uv)); + f2_set(st, rwalk_hit->uv); #endif /* Map the sampled primitive id from the enclosure space to the scene * space. Note that the overall scene has only one shape. As a consequence * neither the geom_id nor the inst_id needs to be updated */ - rwalk->hit.prim.prim_id = enclosure_local2global_prim_id(enc, prim.prim_id); + rwalk_hit->prim.prim_id = enclosure_local2global_prim_id(enc, prim.prim_id); - SXD(primitive_get_attrib(&rwalk->hit.prim, SXD_POSITION, st, &attr_P)); - SXD(primitive_get_attrib(&rwalk->hit.prim, SXD_GEOMETRY_NORMAL, st, &attr_N)); + SXD(primitive_get_attrib(&rwalk_hit->prim, SXD_POSITION, st, &attr_P)); + SXD(primitive_get_attrib(&rwalk_hit->prim, SXD_GEOMETRY_NORMAL, st, &attr_N)); dX_set_fX(rwalk->vtx.P, attr_P.value); - fX(set)(rwalk->hit.normal, attr_N.value); + fX(set)(rwalk_hit->normal, attr_N.value); /* Fetch the interface of the sampled point. */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); + interf = scene_get_interface(scn, rwalk_hit->prim.prim_id); if(rwalk->mdm == interf->medium_front) { rwalk->hit_side = SDIS_FRONT; } else if(rwalk->mdm == interf->medium_back) { @@ -355,7 +359,7 @@ XD(convective_path) if(res != RES_OK) goto error; /* Setup the fragment of the sampled position into the enclosure. */ - XD(setup_interface_fragment)(&frag, &rwalk->vtx, &rwalk->hit, rwalk->hit_side); + XD(setup_interface_fragment)(&frag, &rwalk->vtx, rwalk_hit, rwalk->hit_side); /* Fetch the convection coefficient of the sampled position */ hc = interface_get_convection_coef(interf, &frag); @@ -374,7 +378,7 @@ XD(convective_path) } } - rwalk->hit.distance = 0; + rwalk_hit->distance = 0; T->func = XD(boundary_path); rwalk->mdm = NULL; /* The random walk is at an interface between 2 media */ diff --git a/src/sdis_heat_path_radiative_Xd.h b/src/sdis_heat_path_radiative_Xd.h @@ -35,9 +35,9 @@ XD(trace_radiative_path) (struct sdis_scene* scn, const float ray_dir[3], struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { /* The radiative random walk is always performed in 3D. In 2D, the geometry * are assumed to be extruded to the infinity along the Z dimension. */ @@ -68,16 +68,16 @@ XD(trace_radiative_path) fX_set_dX(pos, rwalk->vtx.P); /* Trace the radiative ray */ - filter_data.XD(hit) = rwalk->hit; + filter_data.XD(hit) = rwalk->XD(hit); filter_data.epsilon = 1.e-6; #if (SDIS_XD_DIMENSION == 2) SXD(scene_view_trace_ray_3d - (scn->sXd(view), pos, dir, range, &filter_data, &rwalk->hit)); + (scn->sXd(view), pos, dir, range, &filter_data, &rwalk->XD(hit))); #else SXD(scene_view_trace_ray - (scn->sXd(view), pos, dir, range, &filter_data, &rwalk->hit)); + (scn->sXd(view), pos, dir, range, &filter_data, &rwalk->XD(hit))); #endif - if(SXD_HIT_NONE(&rwalk->hit)) { /* Fetch the ambient radiative temperature */ + if(SXD_HIT_NONE(&rwalk->XD(hit))) { /* Fetch the ambient radiative temperature */ struct sdis_radiative_ray ray = SDIS_RADIATIVE_RAY_NULL; double trad = 0; /* [K] */ @@ -127,11 +127,11 @@ XD(trace_radiative_path) } /* Define the hit side */ - rwalk->hit_side = fX(dot)(dir, rwalk->hit.normal) < 0 + rwalk->hit_side = fX(dot)(dir, rwalk->XD(hit).normal) < 0 ? SDIS_FRONT : SDIS_BACK; /* Move the random walk to the hit position */ - XD(move_pos)(rwalk->vtx.P, dir, rwalk->hit.distance); + XD(move_pos)(rwalk->vtx.P, dir, rwalk->XD(hit).distance); /* Register the random walk vertex against the heat path */ res = register_heat_vertex(ctx->heat_path, &rwalk->vtx, T->value, @@ -139,8 +139,8 @@ XD(trace_radiative_path) if(res != RES_OK) goto error; /* Fetch the new interface and setup the hit fragment */ - interf = scene_get_interface(scn, rwalk->hit.prim.prim_id); - XD(setup_interface_fragment)(&frag, &rwalk->vtx, &rwalk->hit, rwalk->hit_side); + interf = scene_get_interface(scn, rwalk->XD(hit).prim.prim_id); + XD(setup_interface_fragment)(&frag, &rwalk->vtx, &rwalk->XD(hit), rwalk->hit_side); /* Fetch the interface emissivity */ epsilon = interface_side_get_emissivity(interf, SDIS_INTERN_SOURCE_ID, &frag); @@ -162,7 +162,7 @@ XD(trace_radiative_path) /* Normalize the normal of the interface and ensure that it points toward the * current medium */ - fX(normalize)(N, rwalk->hit.normal); + fX(normalize)(N, rwalk->XD(hit).normal); if(rwalk->hit_side == SDIS_BACK){ chk_mdm = interf->medium_back; fX(minus)(N, N); @@ -175,7 +175,7 @@ XD(trace_radiative_path) * incoherent regarding media. Here a radiative path is allowed to join * 2 different fluids. */ const int outside = scene_is_outside - (scn, rwalk->hit_side, rwalk->hit.prim.prim_id); + (scn, rwalk->hit_side, rwalk->XD(hit).prim.prim_id); if(outside && chk_mdm->type == SDIS_FLUID) { rwalk->mdm = chk_mdm; } else { @@ -204,9 +204,9 @@ res_T XD(radiative_path) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { /* The radiative random walk is always performed in 3D. In 2D, the geometry * are assumed to be extruded to the infinity along the Z dimension. */ @@ -215,11 +215,11 @@ XD(radiative_path) res_T res = RES_OK; ASSERT(scn && ctx && rwalk && rng && T); - ASSERT(!SXD_HIT_NONE(&rwalk->hit)); + ASSERT(!SXD_HIT_NONE(&rwalk->XD(hit))); /* Normalize the normal of the interface and ensure that it points toward the * current medium */ - fX(normalize(N, rwalk->hit.normal)); + fX(normalize(N, rwalk->XD(hit).normal)); if(rwalk->hit_side == SDIS_BACK) { fX(minus(N, N)); } diff --git a/src/sdis_misc.c b/src/sdis_misc.c @@ -14,12 +14,77 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "sdis.h" +#include "sdis_heat_path.h" +#include "sdis_log.h" +#include "sdis_medium_c.h" +#include "sdis_misc.h" +#include "sdis_green.h" -/* Generate the generic functions */ -#define SDIS_XD_DIMENSION 2 -#include "sdis_misc_Xd.h" -#define SDIS_XD_DIMENSION 3 -#include "sdis_misc_Xd.h" +#include <star/ssp.h> + +res_T +time_rewind + (const double mu, + const double t0, + struct ssp_rng* rng, + struct rwalk* rwalk, + const struct rwalk_context* ctx, + struct temperature* T) +{ + double temperature; + double tau; + res_T res = RES_OK; + ASSERT(rwalk && rng && T); + + /* Sample the time using the upper bound. */ + tau = ssp_ran_exp(rng, mu); + + /* Increment the elapsed time */ + ASSERT(rwalk->vtx.time >= t0); + rwalk->elapsed_time += MMIN(tau, rwalk->vtx.time - t0); + + if(IS_INF(rwalk->vtx.time)) goto exit; /* Steady computation */ + + /* Time rewind */ + rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0); /* Time rewind */ + + /* The path does not reach the limit condition */ + if(rwalk->vtx.time > t0) goto exit; + + /* Fetch the initial temperature */ + temperature = medium_get_temperature(rwalk->mdm, &rwalk->vtx); + if(SDIS_TEMPERATURE_IS_UNKNOWN(temperature)) { + log_err(rwalk->mdm->dev, "the path reaches the limit condition but the " + "%s temperature remains unknown -- position=%g, %g, %g\n", + medium_type_to_string(sdis_medium_get_type(rwalk->mdm)), + SPLIT3(rwalk->vtx.P)); + res = RES_BAD_ARG; + goto error; + } + + /* Update temperature */ + T->value += temperature; + T->done = 1; + + if(ctx->heat_path) { + /* Update the registered vertex data */ + struct sdis_heat_vertex* vtx; + vtx = heat_path_get_last_vertex(ctx->heat_path); + vtx->time = rwalk->vtx.time; + vtx->weight = T->value; + } + + if(ctx->green_path) { + res = green_path_set_limit_vertex(ctx->green_path, rwalk->mdm, + &rwalk->vtx, rwalk->elapsed_time); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} res_T check_primitive_uv_2d(struct sdis_device* dev, const double param_coord[]) diff --git a/src/sdis_misc.h b/src/sdis_misc.h @@ -148,22 +148,13 @@ register_heat_vertex } extern LOCAL_SYM res_T -time_rewind_2d +time_rewind (const double mu, const double t0, /* Initial time */ struct ssp_rng* rng, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, const struct rwalk_context* ctx, - struct temperature_2d* T); - -extern LOCAL_SYM res_T -time_rewind_3d - (const double mu, - const double t0, /* Initial time */ - struct ssp_rng* rng, - struct rwalk_3d* rwalk, - const struct rwalk_context* ctx, - struct temperature_3d* T); + struct temperature* T); /* Check the validity of the parametric coordinate onto a 2D primitive. If it * is invalid, the function prints an error message and return RES_BAD_ARG. */ diff --git a/src/sdis_misc_Xd.h b/src/sdis_misc_Xd.h @@ -1,90 +0,0 @@ -/* Copyright (C) 2016-2024 |Méso|Star> (contact@meso-star.com) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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_heat_path.h" -#include "sdis_log.h" -#include "sdis_medium_c.h" -#include "sdis_misc.h" -#include "sdis_green.h" - -#include <star/ssp.h> - -#include "sdis_Xd_begin.h" - -res_T -XD(time_rewind) - (const double mu, - const double t0, - struct ssp_rng* rng, - struct XD(rwalk)* rwalk, - const struct rwalk_context* ctx, - struct XD(temperature)* T) -{ - double temperature; - double tau; - res_T res = RES_OK; - ASSERT(rwalk && rng && T); - - /* Sample the time using the upper bound. */ - tau = ssp_ran_exp(rng, mu); - - /* Increment the elapsed time */ - ASSERT(rwalk->vtx.time >= t0); - rwalk->elapsed_time += MMIN(tau, rwalk->vtx.time - t0); - - if(IS_INF(rwalk->vtx.time)) goto exit; /* Steady computation */ - - /* Time rewind */ - rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0); /* Time rewind */ - - /* The path does not reach the limit condition */ - if(rwalk->vtx.time > t0) goto exit; - - /* Fetch the initial temperature */ - temperature = medium_get_temperature(rwalk->mdm, &rwalk->vtx); - if(SDIS_TEMPERATURE_IS_UNKNOWN(temperature)) { - log_err(rwalk->mdm->dev, "the path reaches the limit condition but the " - "%s temperature remains unknown -- position=%g, %g, %g\n", - medium_type_to_string(sdis_medium_get_type(rwalk->mdm)), - SPLIT3(rwalk->vtx.P)); - res = RES_BAD_ARG; - goto error; - } - - /* Update temperature */ - T->value += temperature; - T->done = 1; - - if(ctx->heat_path) { - /* Update the registered vertex data */ - struct sdis_heat_vertex* vtx; - vtx = heat_path_get_last_vertex(ctx->heat_path); - vtx->time = rwalk->vtx.time; - vtx->weight = T->value; - } - - if(ctx->green_path) { - res = green_path_set_limit_vertex(ctx->green_path, rwalk->mdm, - &rwalk->vtx, rwalk->elapsed_time); - if(res != RES_OK) goto error; - } - -exit: - return res; -error: - goto exit; -} - -#include "sdis_Xd_end.h" diff --git a/src/sdis_realisation.c b/src/sdis_realisation.c @@ -47,15 +47,15 @@ ray_realisation_3d double* weight) { struct rwalk_context ctx = RWALK_CONTEXT_NULL; - struct rwalk_3d rwalk = RWALK_NULL_3d; - struct temperature_3d T = TEMPERATURE_NULL_3d; + struct rwalk rwalk = RWALK_NULL; + struct temperature T = TEMPERATURE_NULL; float dir[3]; res_T res = RES_OK; ASSERT(scn && weight && check_ray_realisation_args(args)); d3_set(rwalk.vtx.P, args->position); rwalk.vtx.time = args->time; - rwalk.hit = S3D_HIT_NULL; + rwalk.hit_3d = S3D_HIT_NULL; rwalk.hit_side = SDIS_SIDE_NULL__; rwalk.mdm = args->medium; diff --git a/src/sdis_realisation.h b/src/sdis_realisation.h @@ -22,11 +22,13 @@ #include <rsys/rsys.h> /* Forward declarations */ +struct bound_flux_result; struct green_path_handle; +struct rwalk; struct sdis_heat_path; struct sdis_scene; struct ssp_rng; -struct bound_flux_result; +struct temperature; enum flux_flag { FLUX_FLAG_CONVECTIVE = BIT(FLUX_CONVECTIVE), @@ -41,17 +43,17 @@ extern LOCAL_SYM res_T sample_coupled_path_2d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_2d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_2d* T); + struct temperature* T); extern LOCAL_SYM res_T sample_coupled_path_3d (struct sdis_scene* scn, struct rwalk_context* ctx, - struct rwalk_3d* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct temperature_3d* T); + struct temperature* T); /******************************************************************************* * Realisation at a given position and time IN a medium diff --git a/src/sdis_realisation_Xd.h b/src/sdis_realisation_Xd.h @@ -82,15 +82,15 @@ res_T XD(sample_coupled_path) (struct sdis_scene* scn, struct rwalk_context* ctx, - struct XD(rwalk)* rwalk, + struct rwalk* rwalk, struct ssp_rng* rng, - struct XD(temperature)* T) + struct temperature* T) { #ifndef NDEBUG /* Stack that saves the state of each recursion steps. */ struct entry { - struct XD(temperature) temperature; - struct XD(rwalk) rwalk; + struct temperature temperature; + struct rwalk rwalk; }* stack = NULL; size_t istack = 0; #endif @@ -109,8 +109,8 @@ XD(sample_coupled_path) while(!T->done) { /* Save the current random walk state */ - const struct XD(rwalk) rwalk_bkp = *rwalk; - const struct XD(temperature) T_bkp = *T; + const struct rwalk rwalk_bkp = *rwalk; + const struct temperature T_bkp = *T; size_t nfails = 0; /* #failures */ #ifndef NDEBUG @@ -172,8 +172,8 @@ XD(probe_realisation) double* weight) { struct rwalk_context ctx = RWALK_CONTEXT_NULL; - struct XD(rwalk) rwalk = XD(RWALK_NULL); - struct XD(temperature) T = XD(TEMPERATURE_NULL); + struct rwalk rwalk = RWALK_NULL; + struct temperature T = TEMPERATURE_NULL; enum sdis_heat_vertex_type type; double t0; double (*get_initial_temperature) @@ -224,7 +224,7 @@ XD(probe_realisation) goto error; } - rwalk.hit = SXD_HIT_NULL; + rwalk.XD(hit) = SXD_HIT_NULL; rwalk.mdm = args->medium; ctx.green_path = args->green_path; @@ -258,8 +258,8 @@ XD(boundary_realisation) double* weight) { struct rwalk_context ctx = RWALK_CONTEXT_NULL; - struct XD(rwalk) rwalk = XD(RWALK_NULL); - struct XD(temperature) T = XD(TEMPERATURE_NULL); + struct rwalk rwalk = RWALK_NULL; + struct temperature T = TEMPERATURE_NULL; struct sXd(attrib) attr; #if SDIS_XD_DIMENSION == 2 float st; @@ -271,7 +271,7 @@ XD(boundary_realisation) T.func = XD(boundary_path); rwalk.hit_side = args->side; - rwalk.hit.distance = 0; + rwalk.XD(hit).distance = 0; rwalk.vtx.time = args->time; rwalk.mdm = NULL; /* The random walk is at an interface between 2 media */ @@ -283,20 +283,20 @@ XD(boundary_realisation) /* Fetch the primitive */ SXD(scene_view_get_primitive - (scn->sXd(view), (unsigned int)args->iprim, &rwalk.hit.prim)); + (scn->sXd(view), (unsigned int)args->iprim, &rwalk.XD(hit).prim)); /* Retrieve the world space position of the probe onto the primitive */ - SXD(primitive_get_attrib(&rwalk.hit.prim, SXD_POSITION, st, &attr)); + SXD(primitive_get_attrib(&rwalk.XD(hit).prim, SXD_POSITION, st, &attr)); dX_set_fX(rwalk.vtx.P, attr.value); /* Retrieve the primitive normal */ - SXD(primitive_get_attrib(&rwalk.hit.prim, SXD_GEOMETRY_NORMAL, st, &attr)); - fX(set)(rwalk.hit.normal, attr.value); + SXD(primitive_get_attrib(&rwalk.XD(hit).prim, SXD_GEOMETRY_NORMAL, st, &attr)); + fX(set)(rwalk.XD(hit).normal, attr.value); #if SDIS_XD_DIMENSION==2 - rwalk.hit.u = st; + rwalk.XD(hit).u = st; #else - f2_set(rwalk.hit.uv, st); + f2_set(rwalk.XD(hit).uv, st); #endif res = register_heat_vertex(args->heat_path, &rwalk.vtx, 0/*weight*/, @@ -333,8 +333,8 @@ XD(boundary_flux_realisation) struct bound_flux_result* result) { struct rwalk_context ctx = RWALK_CONTEXT_NULL; - struct XD(rwalk) rwalk; - struct XD(temperature) T; + struct rwalk rwalk; + struct temperature T; struct sXd(attrib) attr; struct sXd(primitive) prim; struct sdis_interface* interf = NULL; @@ -387,13 +387,13 @@ XD(boundary_flux_realisation) fX(set)(N, attr.value); #define RESET_WALK(Side, Mdm) { \ - rwalk = XD(RWALK_NULL); \ + rwalk = RWALK_NULL; \ rwalk.hit_side = (Side); \ - rwalk.hit.distance = 0; \ + rwalk.XD(hit).distance = 0; \ rwalk.vtx.time = args->time; \ rwalk.mdm = (Mdm); \ - rwalk.hit.prim = prim; \ - SET_PARAM(rwalk.hit, st); \ + rwalk.XD(hit).prim = prim; \ + SET_PARAM(rwalk.XD(hit), st); \ ctx.Tmin = Tmin; \ ctx.Tmin3 = Tmin3; \ ctx.That = That; \ @@ -403,8 +403,8 @@ XD(boundary_flux_realisation) ctx.irealisation = args->irealisation; \ ctx.diff_algo = args->diff_algo; \ dX(set)(rwalk.vtx.P, P); \ - fX(set)(rwalk.hit.normal, N); \ - T = XD(TEMPERATURE_NULL); \ + fX(set)(rwalk.XD(hit).normal, N); \ + T = TEMPERATURE_NULL; \ } (void)0 /* Compute boundary temperature */