stardis-solver

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

commit e825330be6d4ac04900d775cd2eeddec51e44636
parent 7f389490ab19caf4e600e49715880095a5b2d23d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 13 Feb 2019 11:38:41 +0100

Add the sdis_green_function_solve function

Update the internal green implementation to match the solve requirements.
A limit vertex is now registered as a sdis_rwalk_vertex or a
sdis_interface_fragment. Furthermore, the flux terms are now defined per
side of each interface.

Diffstat:
Msrc/sdis.h | 6++++++
Msrc/sdis_green.c | 367++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/sdis_green.h | 17++++++++---------
Msrc/sdis_heat_path_boundary_Xd.h | 14++++++--------
Msrc/sdis_heat_path_conductive_Xd.h | 8+++-----
Msrc/sdis_heat_path_convective_Xd.h | 12++----------
Msrc/sdis_heat_path_radiative_Xd.h | 7++++---
Msrc/sdis_medium_c.h | 23+++++++++++++++++++----
Msrc/sdis_misc.h | 10++++++++++
Msrc/sdis_solve_Xd.h | 14--------------
10 files changed, 339 insertions(+), 139 deletions(-)

diff --git a/src/sdis.h b/src/sdis.h @@ -587,6 +587,12 @@ SDIS_API res_T sdis_green_function_ref_put (struct sdis_green_function* green); +SDIS_API res_T +sdis_green_function_solve + (struct sdis_green_function* green, + const double time_range[2], /* Observation time */ + struct sdis_estimator** estimator); + /******************************************************************************* * Miscellaneous functions ******************************************************************************/ diff --git a/src/sdis_green.c b/src/sdis_green.c @@ -14,10 +14,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "sdis_device_c.h" +#include "sdis_estimator_c.h" #include "sdis_green.h" #include "sdis_medium_c.h" +#include "sdis_misc.h" #include "sdis_interface_c.h" +#include <star/ssp.h> + #include <rsys/dynamic_array.h> #include <rsys/hash_table.h> #include <rsys/mem_allocator.h> @@ -28,39 +32,58 @@ #include <limits.h> -struct green_vertex { - double pos[3]; /* Position */ - double delta_time; /* Time "spent" into the system */ - unsigned id; /* Id of the medium/interface onto wich the vertex lies */ +enum limit_type { LIMIT_FRAGMENT, LIMIT_VERTEX }; + +struct power_term { + double term; /* Power term computed during green estimation */ + unsigned id; /* Identifier of the medium of the term */ }; -#define GREEN_VERTEX_NULL__ {{INF,INF,INF}, INF, UINT_MAX} -static const struct green_vertex GREEN_VERTEX_NULL = GREEN_VERTEX_NULL__; +#define POWER_TERM_NULL__ {INF, UINT_MAX} +static const struct power_term POWER_TERM_NULL = POWER_TERM_NULL__; + +static INLINE void +power_term_init(struct mem_allocator* allocator, struct power_term* term) +{ + ASSERT(term); (void)allocator; + *term = POWER_TERM_NULL; +} -struct green_term { - double term; /* Term computed during green estimation */ - unsigned id; /* Identifier of the medium/interface of the term */ +/* Generate the dynamic array of power terms */ +#define DARRAY_NAME power_term +#define DARRAY_DATA struct power_term +#define DARRAY_FUNCTOR_INIT power_term_init +#include <rsys/dynamic_array.h> + +struct flux_term { + double term; + unsigned id; /* Id of the interface of the flux term */ + enum sdis_side side; }; -#define GREEN_TERM_NULL__ {INF, UINT_MAX} -static const struct green_term GREEN_TERM_NULL = GREEN_TERM_NULL__; +#define FLUX_TERM_NULL__ {INF, UINT_MAX, SDIS_SIDE_NULL__} +static const struct flux_term FLUX_TERM_NULL = FLUX_TERM_NULL__; static INLINE void -green_term_init(struct mem_allocator* allocator, struct green_term* term) +flux_term_init(struct mem_allocator* allocator, struct flux_term* term) { ASSERT(term); (void)allocator; - *term = GREEN_TERM_NULL; + *term = FLUX_TERM_NULL; } -/* Generate the dynamic array of green vertices */ -#define DARRAY_NAME green_term -#define DARRAY_DATA struct green_term -#define DARRAY_FUNCTOR_INIT green_term_init +/* Generate the dynamic array of flux terms */ +#define DARRAY_NAME flux_term +#define DARRAY_DATA struct flux_term +#define DARRAY_FUNCTOR_INIT flux_term_init #include <rsys/dynamic_array.h> struct green_path { - struct darray_green_term flux_terms; /* List of flux terms */ - struct darray_green_term power_terms; /* List of volumic power terms */ - struct green_vertex limit_vertex; /* End vertex of the path */ - int end_on_interface; /* Define if the limit vertex lies on an interface */ + struct darray_flux_term flux_terms; /* List of flux terms */ + struct darray_power_term power_terms; /* List of volumic power terms */ + union { + struct sdis_rwalk_vertex vertex; + struct sdis_interface_fragment fragment; + } limit; + unsigned limit_id; /* Identifier of the limit medium/interface */ + enum limit_type limit_type; /* Indices of the last accessed medium/interface. Used to speed up the access * to the medium/interface. */ @@ -72,10 +95,11 @@ static INLINE void green_path_init(struct mem_allocator* allocator, struct green_path* path) { ASSERT(path); - darray_green_term_init(allocator, &path->flux_terms); - darray_green_term_init(allocator, &path->power_terms); - path->limit_vertex = GREEN_VERTEX_NULL; - path->end_on_interface = 0; + darray_flux_term_init(allocator, &path->flux_terms); + darray_power_term_init(allocator, &path->power_terms); + path->limit.vertex = SDIS_RWALK_VERTEX_NULL; + path->limit_id = UINT_MAX; + path->limit_type = LIMIT_VERTEX; path->ilast_medium = UINT16_MAX; path->ilast_interf = UINT16_MAX; } @@ -84,8 +108,8 @@ static INLINE void green_path_release(struct green_path* path) { ASSERT(path); - darray_green_term_release(&path->flux_terms); - darray_green_term_release(&path->power_terms); + darray_flux_term_release(&path->flux_terms); + darray_power_term_release(&path->power_terms); } static INLINE res_T @@ -93,13 +117,14 @@ green_path_copy(struct green_path* dst, const struct green_path* src) { res_T res = RES_OK; ASSERT(dst && src); - dst->limit_vertex = src->limit_vertex; - dst->end_on_interface = src->end_on_interface; + dst->limit = src->limit; + dst->limit_id = src->limit_id; + dst->limit_type = src->limit_type; dst->ilast_medium = src->ilast_medium; dst->ilast_interf = src->ilast_interf; - res = darray_green_term_copy(&dst->flux_terms, &src->flux_terms); + res = darray_flux_term_copy(&dst->flux_terms, &src->flux_terms); if(res != RES_OK) return res; - res = darray_green_term_copy(&dst->power_terms, &src->power_terms); + res = darray_power_term_copy(&dst->power_terms, &src->power_terms); if(res != RES_OK) return res; return RES_OK; } @@ -109,14 +134,14 @@ green_path_copy_and_clear(struct green_path* dst, struct green_path* src) { res_T res = RES_OK; ASSERT(dst && src); - - dst->limit_vertex = src->limit_vertex; - dst->end_on_interface = src->end_on_interface; + dst->limit = src->limit; + dst->limit_id = src->limit_id; + dst->limit_type = src->limit_type; dst->ilast_medium = src->ilast_medium; dst->ilast_interf = src->ilast_interf; - res = darray_green_term_copy_and_clear(&dst->flux_terms, &src->flux_terms); + res = darray_flux_term_copy_and_clear(&dst->flux_terms, &src->flux_terms); if(res != RES_OK) return res; - res = darray_green_term_copy_and_clear(&dst->power_terms, &src->power_terms); + res = darray_power_term_copy_and_clear(&dst->power_terms, &src->power_terms); if(res != RES_OK) return res; return RES_OK; @@ -127,13 +152,14 @@ green_path_copy_and_release(struct green_path* dst, struct green_path* src) { res_T res = RES_OK; ASSERT(dst && src); - dst->limit_vertex = src->limit_vertex; - dst->end_on_interface = src->end_on_interface; + dst->limit = src->limit; + dst->limit_id = src->limit_id; + dst->limit_type = src->limit_type; dst->ilast_medium = src->ilast_medium; dst->ilast_interf = src->ilast_interf; - res = darray_green_term_copy_and_release(&dst->flux_terms, &src->flux_terms); + res = darray_flux_term_copy_and_release(&dst->flux_terms, &src->flux_terms); if(res != RES_OK) return res; - res = darray_green_term_copy_and_release(&dst->power_terms, &src->power_terms); + res = darray_power_term_copy_and_release(&dst->power_terms, &src->power_terms); if(res != RES_OK) return res; return RES_OK; } @@ -217,6 +243,114 @@ error: goto exit; } +static FINLINE const struct sdis_medium* +green_function_fetch_medium + (struct sdis_green_function* green, const unsigned medium_id) +{ + struct sdis_medium* const* pmdm = NULL; + ASSERT(green); + pmdm = htable_medium_find(&green->media, &medium_id); + ASSERT(pmdm); + return *pmdm; +} + +static FINLINE const struct sdis_interface* +green_function_fetch_interf + (struct sdis_green_function* green, const unsigned interf_id) +{ + struct sdis_interface* const* pinterf = NULL; + ASSERT(green); + pinterf = htable_interf_find(&green->interfaces, &interf_id); + ASSERT(pinterf); + return *pinterf; +} + +static res_T +green_function_solve_path + (struct sdis_green_function* green, + const double time, /* Sampled time */ + const size_t ipath, + double* weight) +{ + const struct power_term* power_terms = NULL; + const struct flux_term* flux_terms = NULL; + const struct green_path* path = NULL; + const struct sdis_medium* medium = NULL; + const struct sdis_interface* interf = NULL; + struct sdis_rwalk_vertex vtx = SDIS_RWALK_VERTEX_NULL; + struct sdis_interface_fragment frag = SDIS_INTERFACE_FRAGMENT_NULL; + double power; + double flux; + double temperature; + double time_curr; + size_t i, n; + res_T res = RES_OK; + ASSERT(green && ipath < darray_green_path_size_get(&green->paths) && weight); + + path = darray_green_path_cdata_get(&green->paths) + ipath; + + /* Compute medium power terms */ + power = 0; + n = darray_power_term_size_get(&path->power_terms); + power_terms = darray_power_term_cdata_get(&path->power_terms); + FOR_EACH(i, 0, n) { + vtx.time = INF; + medium = green_function_fetch_medium(green, power_terms[i].id); + power += power_terms[i].term * solid_get_volumic_power(medium, &vtx); + } + + /* Compute interface fluxes */ + flux = 0; + n = darray_flux_term_size_get(&path->flux_terms); + flux_terms = darray_flux_term_cdata_get(&path->flux_terms); + FOR_EACH(i, 0, n) { + frag.time = INF; + frag.side = flux_terms[i].side; + interf = green_function_fetch_interf(green, flux_terms[i].id); + flux += flux_terms[i].term * interface_side_get_flux(interf, &frag); + } + + /* Setup time. TODO handle t0 of the media */ + switch(path->limit_type) { + case LIMIT_FRAGMENT: time_curr = time + path->limit.fragment.time; break; + case LIMIT_VERTEX: time_curr = time + path->limit.vertex.time; break; + default: FATAL("Unreachable code.\n"); break; + } + if(time_curr <= 0) { + log_err(green->dev, + "%s: invalid observation time \"%g\": the initial condition is reached " + "while instationary system are not supported by the green function.\n", + FUNC_NAME, time); + res = RES_BAD_ARG; + goto error; + } + + /* Compute limit condition */ + switch(path->limit_type) { + case LIMIT_FRAGMENT: + frag = path->limit.fragment; + frag.time = time_curr; + interf = green_function_fetch_interf(green, path->limit_id); + temperature = interface_side_get_temperature(interf, &frag); + break; + case LIMIT_VERTEX: + vtx = path->limit.vertex; + vtx.time = time_curr; + medium = green_function_fetch_medium(green, path->limit_id); + temperature = medium_get_temerature(medium, &vtx); + break; + default: FATAL("Unreachable code.\n"); break; + } + + /* Compute the path weight */ + *weight = power + flux + temperature; + +exit: + return res; +error: + goto exit; +} + static void green_function_clear(struct sdis_green_function* green) { @@ -283,6 +417,62 @@ sdis_green_function_ref_put(struct sdis_green_function* green) return RES_OK; } +res_T +sdis_green_function_solve + (struct sdis_green_function* green, + const double time_range[2], + struct sdis_estimator** out_estimator) +{ + struct sdis_estimator* estimator = NULL; + struct ssp_rng* rng = NULL; + size_t npaths; + size_t ipath; + double accum = 0; + double accum2 = 0; + res_T res = RES_OK; + + if(!green || !time_range || time_range[0] < 0 + || time_range[1] < time_range[0] || !out_estimator) { + res = RES_BAD_ARG; + goto error; + } + + res = ssp_rng_create(green->dev->allocator, &ssp_rng_mt19937_64, &rng); + if(res != RES_OK) goto error; + + npaths = darray_green_path_size_get(&green->paths); + + /* Create the estimator */ + res = estimator_create + (green->dev, SDIS_ESTIMATOR_TEMPERATURE, npaths, npaths, &estimator); + if(res != RES_OK) goto error; + + /* Solve the green function */ + FOR_EACH(ipath, 0, npaths) { /* TODO add multi-threading */ + const double time = sample_time(rng, time_range); + double w; + + res = green_function_solve_path(green, time, ipath, &w); + if(res != RES_OK) goto error; + accum += w; + accum2 += w*w; + } + + /* Setup the estimated temperature */ + estimator_setup_temperature(estimator, accum, accum2); + +exit: + if(rng) SSP(rng_ref_put(rng)); + if(out_estimator) *out_estimator = estimator; + return res; +error: + if(estimator) { + SDIS(estimator_ref_put(estimator)); + estimator = NULL; + } + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -396,42 +586,34 @@ green_function_create_path } res_T -green_path_set_medium_limit_vertex +green_path_set_limit_interface_fragment (struct green_path_handle* handle, - struct sdis_medium* mdm, - const double pos[3], - const double delta_time) + struct sdis_interface* interf, + const struct sdis_interface_fragment* frag) { res_T res = RES_OK; - ASSERT(handle && mdm && pos); - res = ensure_medium_registration(handle->green, mdm); + ASSERT(handle && interf && frag); + res = ensure_interface_registration(handle->green, interf); if(res != RES_OK) return res; - handle->path->limit_vertex.pos[0] = pos[0]; - handle->path->limit_vertex.pos[1] = pos[1]; - handle->path->limit_vertex.pos[2] = pos[2]; - handle->path->limit_vertex.delta_time = delta_time; - handle->path->limit_vertex.id = medium_get_id(mdm); - handle->path->end_on_interface = 0; + handle->path->limit.fragment = *frag; + handle->path->limit_id = interface_get_id(interf); + handle->path->limit_type = LIMIT_FRAGMENT; return RES_OK; } res_T -green_path_set_interface_limit_vertex +green_path_set_limit_vertex (struct green_path_handle* handle, - struct sdis_interface* interf, - const double pos[3], - const double delta_time) + struct sdis_medium* mdm, + const struct sdis_rwalk_vertex* vert) { res_T res = RES_OK; - ASSERT(handle && interf && pos); - res = ensure_interface_registration(handle->green, interf); + ASSERT(handle && mdm && vert); + res = ensure_medium_registration(handle->green, mdm); if(res != RES_OK) return res; - handle->path->limit_vertex.pos[0] = pos[0]; - handle->path->limit_vertex.pos[1] = pos[1]; - handle->path->limit_vertex.pos[2] = pos[2]; - handle->path->limit_vertex.delta_time = delta_time; - handle->path->limit_vertex.id = interface_get_id(interf); - handle->path->end_on_interface = 1; + handle->path->limit.vertex = *vert; + handle->path->limit_id = medium_get_id(mdm); + handle->path->limit_type = LIMIT_VERTEX; return RES_OK; } @@ -439,22 +621,27 @@ res_T green_path_add_power_term (struct green_path_handle* handle, struct sdis_medium* mdm, - const double term) + const struct sdis_rwalk_vertex* vtx, + const double val) { struct green_path* path; - struct green_term* terms; + struct power_term* terms; size_t nterms; size_t iterm; unsigned id; res_T res = RES_OK; - ASSERT(handle && mdm && term >= 0); + ASSERT(handle && mdm && vtx && val >= 0); + + /* Unused position and time: the current implementation of the green function + * assumes that the power is constant in space and time per medium. */ + (void)vtx; res = ensure_medium_registration(handle->green, mdm); if(res != RES_OK) goto error; path = handle->path; - terms = darray_green_term_data_get(&path->power_terms); - nterms = darray_green_term_size_get(&path->power_terms); + terms = darray_power_term_data_get(&path->power_terms); + nterms = darray_power_term_size_get(&path->power_terms); id = medium_get_id(mdm); iterm = SIZE_MAX; @@ -468,12 +655,12 @@ green_path_add_power_term /* Add the power term to the path wrt the submitted medium */ if(iterm < nterms) { - terms[iterm].term += term; + terms[iterm].term += val; } else { - struct green_term gterm = GREEN_TERM_NULL; - gterm.term = term; - gterm.id = id; - res = darray_green_term_push_back(&handle->path->power_terms, &gterm); + struct power_term term = POWER_TERM_NULL; + term.term = val; + term.id = id; + res = darray_power_term_push_back(&handle->path->power_terms, &term); if(res != RES_OK) goto error; } @@ -491,41 +678,49 @@ res_T green_path_add_flux_term (struct green_path_handle* handle, struct sdis_interface* interf, - const double term) + const struct sdis_interface_fragment* frag, + const double val) { struct green_path* path; - struct green_term* terms; + struct flux_term* terms; size_t nterms; size_t iterm; unsigned id; res_T res = RES_OK; - ASSERT(handle && interf && term >= 0); + ASSERT(handle && interf && frag && val >= 0); res = ensure_interface_registration(handle->green, interf); if(res != RES_OK) goto error; path = handle->path; - terms = darray_green_term_data_get(&path->flux_terms); - nterms = darray_green_term_size_get(&path->flux_terms); + terms = darray_flux_term_data_get(&path->flux_terms); + nterms = darray_flux_term_size_get(&path->flux_terms); id = interface_get_id(interf); iterm = SIZE_MAX; /* Early find */ - if(path->ilast_interf < nterms && terms[path->ilast_interf].id == id) { + if(path->ilast_interf < nterms + && terms[path->ilast_interf].id == id + && terms[path->ilast_interf].side == frag->side) { iterm = path->ilast_interf; } else { /* Linear search of the submitted interface */ - FOR_EACH(iterm, 0, nterms) if(terms[iterm].id == id) break; + FOR_EACH(iterm, 0, nterms) { + if(terms[iterm].id == id && terms[iterm].side == frag->side) { + break; + } + } } /* Add the flux term to the path wrt the submitted interface */ if(iterm < nterms) { - terms[iterm].term += term; + terms[iterm].term += val; } else { - struct green_term gterm = GREEN_TERM_NULL; - gterm.term = term; - gterm.id = id; - res = darray_green_term_push_back(&handle->path->flux_terms, &gterm); + struct flux_term term = FLUX_TERM_NULL; + term.term = val; + term.id = id; + term.side = frag->side; + res = darray_flux_term_push_back(&handle->path->flux_terms, &term); if(res != RES_OK) goto error; } diff --git a/src/sdis_green.h b/src/sdis_green.h @@ -47,31 +47,30 @@ green_function_create_path struct green_path_handle* handle); extern LOCAL_SYM res_T -green_path_set_medium_limit_vertex +green_path_set_limit_interface_fragment (struct green_path_handle* path, - struct sdis_medium* mdm, - const double pos[3], - const double delta_time); + struct sdis_interface* interf, + const struct sdis_interface_fragment* fragment); extern LOCAL_SYM res_T -green_path_set_interface_limit_vertex +green_path_set_limit_vertex (struct green_path_handle* path, - struct sdis_interface* interf, - const double pos[3], - const double delta_time); + struct sdis_medium* mdm, + const struct sdis_rwalk_vertex* vertex); extern LOCAL_SYM res_T green_path_add_power_term (struct green_path_handle* path, struct sdis_medium* mdm, + const struct sdis_rwalk_vertex* vertex, const double term); extern LOCAL_SYM res_T green_path_add_flux_term (struct green_path_handle* path, struct sdis_interface* interf, + const struct sdis_interface_fragment* fragment, const double term); - #endif /* SDIS_GREEN_H */ diff --git a/src/sdis_heat_path_boundary_Xd.h b/src/sdis_heat_path_boundary_Xd.h @@ -233,7 +233,7 @@ XD(solid_solid_boundary_path) T->value += power * tmp; if(ctx->green_path) { - res = green_path_add_power_term(ctx->green_path, mdm, tmp); + res = green_path_add_power_term(ctx->green_path, mdm, &rwalk->vtx, tmp); if(res != RES_OK) goto error; } } @@ -393,7 +393,7 @@ XD(solid_fluid_boundary_path) T->value += power * tmp; if(ctx->green_path) { - res = green_path_add_power_term(ctx->green_path, solid, tmp); + res = green_path_add_power_term(ctx->green_path, solid, &rwalk->vtx, tmp); if(res != RES_OK) goto error; } } @@ -513,7 +513,7 @@ XD(solid_boundary_with_flux_path) tmp = delta_in_meter / lambda; T->value += phi * tmp; if(ctx->green_path) { - res = green_path_add_flux_term(ctx->green_path, interf, tmp); + res = green_path_add_flux_term(ctx->green_path, interf, frag, tmp); if(res != RES_OK) goto error; } @@ -524,7 +524,7 @@ XD(solid_boundary_with_flux_path) 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, tmp); + res = green_path_add_power_term(ctx->green_path, mdm, &rwalk->vtx, tmp); if(res != RES_OK) goto error; } } @@ -586,10 +586,8 @@ XD(boundary_path) T->done = 1; if(ctx->green_path) { - double pos[3] = {0,0,0}; - dX(set)(pos, rwalk->vtx.P); - res = green_path_set_interface_limit_vertex - (ctx->green_path, interf, pos, rwalk->vtx.time); + res = green_path_set_limit_interface_fragment + (ctx->green_path, interf, &frag); if(res != RES_OK) goto error; } goto exit; diff --git a/src/sdis_heat_path_conductive_Xd.h b/src/sdis_heat_path_conductive_Xd.h @@ -72,10 +72,7 @@ XD(conductive_path) T->done = 1; if(ctx->green_path) { - double pos[3] = {0,0,0}; - dX(set)(pos, rwalk->vtx.P); - res = green_path_set_medium_limit_vertex - (ctx->green_path, rwalk->mdm, pos, rwalk->vtx.time); + res = green_path_set_limit_vertex(ctx->green_path, rwalk->mdm, &rwalk->vtx); if(res != RES_OK) goto error; } goto exit; @@ -164,7 +161,8 @@ XD(conductive_path) /* Register the power term against the green function */ if(ctx->green_path && power != SDIS_VOLUMIC_POWER_NONE) { - res = green_path_add_power_term(ctx->green_path, mdm, power_factor); + res = green_path_add_power_term + (ctx->green_path, mdm, &rwalk->vtx, power_factor); if(res != RES_OK) goto error; } diff --git a/src/sdis_heat_path_convective_Xd.h b/src/sdis_heat_path_convective_Xd.h @@ -59,16 +59,8 @@ XD(convective_path) T->done = 1; if(ctx->green_path) { - double pos[3] = {0,0,0}; - dX(set)(pos, rwalk->vtx.P); - res = green_path_set_medium_limit_vertex - (ctx->green_path, rwalk->mdm, pos, rwalk->vtx.time); - if(res != RES_OK) { - log_err(scn->dev, - "%s: could not register the limit vertex of a sampled path " - "against the green function.\n", FUNC_NAME); - goto error; - } + res = green_path_set_limit_vertex(ctx->green_path, rwalk->mdm, &rwalk->vtx); + if(res != RES_OK) goto error; } goto exit; } diff --git a/src/sdis_heat_path_radiative_Xd.h b/src/sdis_heat_path_radiative_Xd.h @@ -77,9 +77,10 @@ XD(trace_radiative_path) T->done = 1; if(ctx->green_path) { - const double inf_pos[3] = {INF,INF,INF}; - res = green_path_set_medium_limit_vertex - (ctx->green_path, rwalk->mdm, inf_pos, rwalk->vtx.time); + struct sdis_rwalk_vertex vtx; + d3_splat(vtx.P, INF); + vtx.time = rwalk->vtx.time; + res = green_path_set_limit_vertex(ctx->green_path, rwalk->mdm, &vtx); if(res != RES_OK) goto error; } break; diff --git a/src/sdis_medium_c.h b/src/sdis_medium_c.h @@ -70,8 +70,7 @@ fluid_get_temperature } static INLINE double - fluid_get_t0 -(const struct sdis_medium* mdm) +fluid_get_t0(const struct sdis_medium* mdm) { ASSERT(mdm && mdm->type == SDIS_FLUID); ASSERT(0 <= mdm->shader.fluid.t0 && mdm->shader.fluid.t0 < INF); @@ -133,13 +132,29 @@ solid_get_temperature } static INLINE double - solid_get_t0 -(const struct sdis_medium* mdm) +solid_get_t0(const struct sdis_medium* mdm) { ASSERT(mdm && mdm->type == SDIS_SOLID); ASSERT(0 <= mdm->shader.solid.t0 && mdm->shader.solid.t0 < INF); return mdm->shader.solid.t0; } +/******************************************************************************* + * Generic functions + ******************************************************************************/ +static FINLINE double +medium_get_temerature + (const struct sdis_medium* mdm, const struct sdis_rwalk_vertex* vtx) +{ + double temp; + ASSERT(mdm); + switch(mdm->type) { + case SDIS_FLUID: temp = fluid_get_temperature(mdm, vtx); break; + case SDIS_SOLID: temp = solid_get_temperature(mdm, vtx); break; + default: FATAL("Unreachable code.\n"); break; + } + return temp; +} + #endif /* SDIS_MEDIUM_C_H */ diff --git a/src/sdis_misc.h b/src/sdis_misc.h @@ -18,6 +18,7 @@ #include <rsys/float2.h> #include <rsys/float3.h> +#include <star/ssp.h> /* Empirical scale factor to apply to the upper bound of the ray range in order * to handle numerical imprecisions */ @@ -77,4 +78,13 @@ move_pos_3d(double pos[3], const float dir[3], const float delta) return pos; } +static INLINE double +sample_time(struct ssp_rng* rng, const double time_range[2]) +{ + ASSERT(time_range && time_range[0] >= 0 && time_range[1] >= time_range[0]); + ASSERT(rng); + if(time_range[0] == time_range[1]) return time_range[0]; + return ssp_rng_uniform_double(rng, time_range[0], time_range[1]); +} + #endif /* SDIS_MISC_H */ diff --git a/src/sdis_solve_Xd.h b/src/sdis_solve_Xd.h @@ -34,20 +34,6 @@ static const struct XD(boundary_context) XD(BOUNDARY_CONTEXT_NULL) = { NULL, NULL }; -#ifndef SDIS_SOLVE_XD_H -#define SDIS_SOLVE_XD_H - -static INLINE double -sample_time(struct ssp_rng* rng, const double time_range[2]) -{ - ASSERT(time_range && time_range[0] >= 0 && time_range[1] >= time_range[0]); - ASSERT(rng); - if(time_range[0] == time_range[1]) return time_range[0]; - return ssp_rng_uniform_double(rng, time_range[0], time_range[1]); -} - -#endif /* SDIS_SOLVE_XD_H */ - /******************************************************************************* * Helper functions ******************************************************************************/