stardis-solver

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

commit 724387f01fd1145b77d18c9e912a415a9364d038
parent 770227f1326854bb4f4d0c07348ac022921a3998
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 25 Feb 2019 16:02:28 +0100

Add and test the sdis_heat_path API

Diffstat:
Msrc/sdis.h | 57++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/sdis_Xd_begin.h | 4++--
Msrc/sdis_estimator.c | 41+++++++++++++++++++++++++++++++++++++++--
Msrc/sdis_estimator_c.h | 2+-
Msrc/sdis_heat_path.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/sdis_heat_path.h | 16++++++++--------
Msrc/sdis_misc.h | 2+-
Msrc/sdis_realisation.h | 4++--
Msrc/sdis_realisation_Xd.h | 2+-
Msrc/sdis_solve_Xd.h | 6+++---
Msrc/test_sdis_conducto_radiative.c | 4++++
Msrc/test_sdis_solve_probe.c | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
12 files changed, 275 insertions(+), 24 deletions(-)

diff --git a/src/sdis.h b/src/sdis.h @@ -66,6 +66,9 @@ struct sdis_interface; struct sdis_medium; struct sdis_scene; +/* Forward declaration of non ref counted types */ +struct sdis_heat_path; + enum sdis_side { SDIS_FRONT, SDIS_BACK, @@ -103,9 +106,9 @@ enum sdis_heat_vertex_type { }; enum sdis_heat_path_flag { - SDIS_HEAT_PATH_OK = BIT(0), + SDIS_HEAT_PATH_SUCCEED = BIT(0), SDIS_HEAT_PATH_FAILED = BIT(1), - SDIS_HEAT_PATH_ALL = SDIS_HEAT_PATH_OK | SDIS_HEAT_PATH_FAILED, + SDIS_HEAT_PATH_ALL = SDIS_HEAT_PATH_SUCCEED | SDIS_HEAT_PATH_FAILED, SDIS_HEAT_PATH_NONE = 0 }; @@ -294,7 +297,7 @@ struct sdis_point { #define SDIS_POINT_NULL__ { {{NULL, SDIS_RWALK_VERTEX_NULL__}}, SDIS_POINT_NONE} static const struct sdis_point SDIS_POINT_NULL = SDIS_POINT_NULL__; -/* Functor used to process the paths registered agains the green function */ +/* Functor used to process the paths registered against the green function */ typedef res_T (*sdis_process_green_path_T) (struct sdis_green_path* path, @@ -317,6 +320,18 @@ typedef res_T const double flux_term, void* context); +/* Functor used to process a heat path registered against the estimator */ +typedef res_T +(*sdis_process_heat_path_T) + (const struct sdis_heat_path* path, + void* context); + +/* Functor used to process the vertices of a heat path */ +typedef res_T +(*sdis_process_heat_vertex_T) + (const struct sdis_heat_vertex* vertex, + void* context); + BEGIN_DECLS /******************************************************************************* @@ -712,6 +727,17 @@ sdis_estimator_get_total_flux (const struct sdis_estimator* estimator, struct sdis_mc* flux); +SDIS_API res_T +sdis_estimator_get_paths_count + (const struct sdis_estimator* estimator, + size_t* npaths); + +SDIS_API res_T +sdis_estimator_for_each_path + (const struct sdis_estimator* estimator, + sdis_process_heat_path_T func, + void* context); + /******************************************************************************* * The green function saves the estimation of the propagator ******************************************************************************/ @@ -778,6 +804,31 @@ sdis_green_path_for_each_flux_term void* context); /******************************************************************************* + * Heat path API + ******************************************************************************/ +SDIS_API res_T +sdis_heat_path_get_vertices_count + (const struct sdis_heat_path* path, + size_t* nvertices); + +SDIS_API res_T +sdis_heat_path_get_status + (const struct sdis_heat_path* path, + enum sdis_heat_path_flag* status); + +SDIS_API res_T +sdis_heat_path_get_vertex + (const struct sdis_heat_path* path, + const size_t ivertex, + struct sdis_heat_vertex* vertex); + +SDIS_API res_T +sdis_heat_path_for_each_vertex + (const struct sdis_heat_path* path, + sdis_process_heat_vertex_T func, + void* context); + +/******************************************************************************* * Solvers ******************************************************************************/ SDIS_API res_T diff --git a/src/sdis_Xd_begin.h b/src/sdis_Xd_begin.h @@ -20,11 +20,11 @@ /* Forward declaration */ struct green_path_handle; -struct heat_path; +struct sdis_heat_path; struct rwalk_context { struct green_path_handle* green_path; - struct heat_path* heat_path; + struct sdis_heat_path* heat_path; double Tarad; /* Ambient radiative temperature */ double Tref3; /* Reference temperature ^ 3 */ }; diff --git a/src/sdis_estimator.c b/src/sdis_estimator.c @@ -124,6 +124,43 @@ sdis_estimator_get_total_flux return RES_OK; } +res_T +sdis_estimator_get_paths_count + (const struct sdis_estimator* estimator, size_t* npaths) +{ + if(!estimator || !npaths) return RES_BAD_ARG; + *npaths = darray_heat_path_size_get(&estimator->paths); + return RES_OK; +} + +res_T +sdis_estimator_for_each_path + (const struct sdis_estimator* estimator, + sdis_process_heat_path_T func, + void* context) +{ + const struct sdis_heat_path* paths = NULL; + size_t i, n; + res_T res = RES_OK; + + if(!estimator || !func) { + res = RES_BAD_ARG; + goto error; + } + + SDIS(estimator_get_paths_count(estimator, &n)); + paths = darray_heat_path_cdata_get(&estimator->paths); + FOR_EACH(i, 0, n) { + res = func(paths+i, context); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -175,9 +212,9 @@ error: res_T estimator_add_and_release_heat_path - (struct sdis_estimator* estimator, struct heat_path* path) + (struct sdis_estimator* estimator, struct sdis_heat_path* path) { - struct heat_path* dst = NULL; + struct sdis_heat_path* dst = NULL; size_t i; res_T res = RES_OK; ASSERT(estimator && path); diff --git a/src/sdis_estimator_c.h b/src/sdis_estimator_c.h @@ -62,7 +62,7 @@ estimator_create extern LOCAL_SYM res_T estimator_add_and_release_heat_path (struct sdis_estimator* estimator, - struct heat_path* path); + struct sdis_heat_path* path); /* Must be invoked before any others "estimator_setup" functions */ static INLINE void diff --git a/src/sdis_heat_path.c b/src/sdis_heat_path.c @@ -39,3 +39,67 @@ #define SDIS_XD_DIMENSION 3 #include "sdis_heat_path_boundary_Xd.h" +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +sdis_heat_path_get_vertices_count + (const struct sdis_heat_path* path, size_t* nvertices) +{ + if(!path || !nvertices) return RES_BAD_ARG; + *nvertices = darray_heat_vertex_size_get(&path->vertices); + return RES_OK; +} + +res_T +sdis_heat_path_get_status + (const struct sdis_heat_path* path, enum sdis_heat_path_flag* status) +{ + if(!path || !status) return RES_BAD_ARG; + *status = path->status; + return RES_OK; +} + +res_T +sdis_heat_path_get_vertex + (const struct sdis_heat_path* path, + const size_t ivertex, + struct sdis_heat_vertex* vertex) +{ + if(!path || !vertex + || ivertex >= darray_heat_vertex_size_get(&path->vertices)) { + return RES_BAD_ARG; + } + + *vertex = darray_heat_vertex_cdata_get(&path->vertices)[ivertex]; + return RES_OK; +} + +res_T +sdis_heat_path_for_each_vertex + (const struct sdis_heat_path* path, + sdis_process_heat_vertex_T func, + void* context) +{ + const struct sdis_heat_vertex* vertices; + size_t i, n; + res_T res = RES_OK; + + if(!path || !func) { + res = RES_BAD_ARG; + goto error; + } + + SDIS(heat_path_get_vertices_count(path, &n)); + vertices = darray_heat_vertex_cdata_get(&path->vertices); + FOR_EACH(i, 0, n) { + res = func(vertices+i, context); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + diff --git a/src/sdis_heat_path.h b/src/sdis_heat_path.h @@ -38,13 +38,13 @@ struct temperature_3d; /******************************************************************************* * Heat path data structure ******************************************************************************/ -struct heat_path { +struct sdis_heat_path { struct darray_heat_vertex vertices; enum sdis_heat_path_flag status; }; static INLINE void -heat_path_init(struct mem_allocator* allocator, struct heat_path* path) +heat_path_init(struct mem_allocator* allocator, struct sdis_heat_path* path) { ASSERT(path); path->status = SDIS_HEAT_PATH_NONE; @@ -52,14 +52,14 @@ heat_path_init(struct mem_allocator* allocator, struct heat_path* path) } static INLINE void -heat_path_release(struct heat_path* path) +heat_path_release(struct sdis_heat_path* path) { ASSERT(path); darray_heat_vertex_release(&path->vertices); } static INLINE res_T -heat_path_copy(struct heat_path* dst, const struct heat_path* src) +heat_path_copy(struct sdis_heat_path* dst, const struct sdis_heat_path* src) { ASSERT(dst && src); dst->status = src->status; @@ -67,7 +67,7 @@ heat_path_copy(struct heat_path* dst, const struct heat_path* src) } static INLINE res_T -heat_path_copy_and_release(struct heat_path* dst, struct heat_path* src) +heat_path_copy_and_release(struct sdis_heat_path* dst, struct sdis_heat_path* src) { ASSERT(dst && src); dst->status = src->status; @@ -75,7 +75,7 @@ heat_path_copy_and_release(struct heat_path* dst, struct heat_path* src) } static INLINE res_T -heat_path_copy_and_clear(struct heat_path* dst, struct heat_path* src) +heat_path_copy_and_clear(struct sdis_heat_path* dst, struct sdis_heat_path* src) { ASSERT(dst && src); dst->status = src->status; @@ -83,7 +83,7 @@ heat_path_copy_and_clear(struct heat_path* dst, struct heat_path* src) } static INLINE res_T -heat_path_add_vertex(struct heat_path* path, const struct sdis_heat_vertex* vtx) +heat_path_add_vertex(struct sdis_heat_path* path, const struct sdis_heat_vertex* vtx) { ASSERT(path && vtx); return darray_heat_vertex_push_back(&path->vertices, vtx); @@ -91,7 +91,7 @@ heat_path_add_vertex(struct heat_path* path, const struct sdis_heat_vertex* vtx) /* Generate the dynamic array of heat paths */ #define DARRAY_NAME heat_path -#define DARRAY_DATA struct heat_path +#define DARRAY_DATA struct sdis_heat_path #define DARRAY_FUNCTOR_INIT heat_path_init #define DARRAY_FUNCTOR_RELEASE heat_path_release #define DARRAY_FUNCTOR_COPY heat_path_copy diff --git a/src/sdis_misc.h b/src/sdis_misc.h @@ -89,7 +89,7 @@ sample_time(struct ssp_rng* rng, const double time_range[2]) static INLINE res_T register_heat_vertex - (struct heat_path* path, + (struct sdis_heat_path* path, const struct sdis_rwalk_vertex* vtx, const double weight, const enum sdis_heat_vertex_type type) diff --git a/src/sdis_realisation.h b/src/sdis_realisation.h @@ -46,7 +46,7 @@ probe_realisation_2d const double ambient_radiative_temperature, const double reference_temperature, struct green_path_handle* green_path, - struct heat_path* heat_path, + struct sdis_heat_path* heat_path, double* weight); extern LOCAL_SYM res_T @@ -60,7 +60,7 @@ probe_realisation_3d const double ambient_radiative_temperature, const double reference_temperature, struct green_path_handle* green_path, - struct heat_path* heat_path, + struct sdis_heat_path* heat_path, double* weight); /******************************************************************************* diff --git a/src/sdis_realisation_Xd.h b/src/sdis_realisation_Xd.h @@ -97,7 +97,7 @@ XD(probe_realisation) const double ambient_radiative_temperature, const double reference_temperature, struct green_path_handle* green_path, - struct heat_path* heat_path, + struct sdis_heat_path* heat_path, double* weight) { struct rwalk_context ctx = RWALK_CONTEXT_NULL; diff --git a/src/sdis_solve_Xd.h b/src/sdis_solve_Xd.h @@ -243,8 +243,8 @@ XD(solve_probe) struct ssp_rng* rng = rngs[ithread]; struct green_path_handle* pgreen_path = NULL; struct green_path_handle green_path = GREEN_PATH_HANDLE_NULL; - struct heat_path* pheat_path = NULL; - struct heat_path heat_path; + struct sdis_heat_path* pheat_path = NULL; + struct sdis_heat_path heat_path; if(ATOMIC_GET(&res) != RES_OK) continue; /* An error occurred */ @@ -276,7 +276,7 @@ XD(solve_probe) if(pheat_path) { pheat_path->status = res_local == RES_OK - ? SDIS_HEAT_PATH_OK + ? SDIS_HEAT_PATH_SUCCEED : SDIS_HEAT_PATH_FAILED; /* Check if the path must be saved regarding the register_paths mask */ diff --git a/src/test_sdis_conducto_radiative.c b/src/test_sdis_conducto_radiative.c @@ -422,6 +422,10 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator)); OK(sdis_estimator_ref_put(estimator2)); OK(sdis_green_function_ref_put(green)); + + OK(sdis_solve_probe(scn, 100, pos, time_range, 1, -1, Tref, + SDIS_HEAT_PATH_ALL, &estimator)); + OK(sdis_estimator_ref_put(estimator)); } /* Release memory */ diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c @@ -167,6 +167,80 @@ interface_get_specular_fraction } /******************************************************************************* + * Helper functions + ******************************************************************************/ +struct dump_path_context { + FILE* stream; + size_t offset; + size_t nfailures; + size_t nsuccesses; +}; +static const struct dump_path_context DUMP_PATH_CONTEXT_NULL = {NULL, 0, 0, 0}; + +static res_T +dump_vertex_pos(const struct sdis_heat_vertex* vert, void* context) +{ + struct dump_path_context* ctx = context; + CHK(vert && context); + fprintf(ctx->stream, "v %g %g %g\n", SPLIT3(vert->P)); + return RES_OK; +} + +static res_T +process_heat_path(const struct sdis_heat_path* path, void* context) +{ + struct dump_path_context* ctx = context; + struct sdis_heat_vertex vert = SDIS_HEAT_VERTEX_NULL; + enum sdis_heat_path_flag status = SDIS_HEAT_PATH_NONE; + size_t i; + size_t n; + (void)context; + + CHK(path && context); + + BA(sdis_heat_path_get_vertices_count(NULL, &n)); + BA(sdis_heat_path_get_vertices_count(path, NULL)); + OK(sdis_heat_path_get_vertices_count(path, &n)); + CHK(n != 0); + + BA(sdis_heat_path_get_status(NULL, &status)); + BA(sdis_heat_path_get_status(path, NULL)); + OK(sdis_heat_path_get_status(path, &status)); + CHK(status == SDIS_HEAT_PATH_SUCCEED || status == SDIS_HEAT_PATH_FAILED); + + switch(status) { + case SDIS_HEAT_PATH_FAILED: ++ctx->nfailures; break; + case SDIS_HEAT_PATH_SUCCEED: ++ctx->nsuccesses; break; + default: FATAL("Unreachable code.\n"); break; + } + + BA(sdis_heat_path_get_vertex(NULL, 0, &vert)); + BA(sdis_heat_path_get_vertex(path, n, &vert)); + BA(sdis_heat_path_get_vertex(path, 0, NULL)); + + FOR_EACH(i, 0, n) { + OK(sdis_heat_path_get_vertex(path, i, &vert)); + CHK(vert.type == SDIS_HEAT_VERTEX_CONVECTION + || vert.type == SDIS_HEAT_VERTEX_CONDUCTION + || vert.type == SDIS_HEAT_VERTEX_RADIATIVE); + } + + BA(sdis_heat_path_for_each_vertex(NULL, dump_vertex_pos, context)); + BA(sdis_heat_path_for_each_vertex(path, NULL, context)); + OK(sdis_heat_path_for_each_vertex(path, dump_vertex_pos, context)); + + FOR_EACH(i, 0, n-1) { + fprintf(ctx->stream, "l %lu %lu\n", + (unsigned long)(i+1 + ctx->offset), + (unsigned long)(i+2 + ctx->offset)); + } + + ctx->offset += n; + + return RES_OK; +} + +/******************************************************************************* * Test ******************************************************************************/ int @@ -187,6 +261,7 @@ main(int argc, char** argv) struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL; + struct dump_path_context dump_ctx = DUMP_PATH_CONTEXT_NULL; struct context ctx; struct fluid* fluid_param; struct solid* solid_param; @@ -196,12 +271,14 @@ main(int argc, char** argv) double time_range[2]; double ref; const size_t N = 1000; + const size_t N_dump = 10; size_t nreals; size_t nfails; + size_t n; (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); - OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 1, &dev)); + OK(sdis_device_create(NULL, &allocator, SDIS_NTHREADS_DEFAULT, 0, &dev)); /* Create the fluid medium */ OK(sdis_data_create @@ -348,6 +425,24 @@ main(int argc, char** argv) OK(sdis_estimator_ref_put(estimator)); OK(sdis_estimator_ref_put(estimator2)); + OK(sdis_solve_probe(scn, N, pos, time_range, 1.0, 0, 0, 0, &estimator)); + BA(sdis_estimator_get_paths_count(NULL, &n)); + BA(sdis_estimator_get_paths_count(estimator, NULL)); + OK(sdis_estimator_get_paths_count(estimator, &n)); + CHK(n == 0); + OK(sdis_estimator_ref_put(estimator)); + + OK(sdis_solve_probe(scn, N_dump, pos, time_range, 1.0, 0, 0, + SDIS_HEAT_PATH_ALL, &estimator)); + OK(sdis_estimator_get_paths_count(estimator, &n)); + CHK(n == N_dump); + + dump_ctx.stream = stderr; + BA(sdis_estimator_for_each_path(NULL, process_heat_path, &dump_ctx)); + BA(sdis_estimator_for_each_path(estimator, NULL, &dump_ctx)); + OK(sdis_estimator_for_each_path(estimator, process_heat_path, &dump_ctx)); + + OK(sdis_estimator_ref_put(estimator)); OK(sdis_scene_ref_put(scn)); OK(sdis_device_ref_put(dev));