stardis-solver

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

commit 202dc45b33773e7111ea6e7ad3ccc6f3b185b10e
parent 5a95ad5edb12d556f0c561d0a2c0d3d48759203d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 14 Dec 2021 11:37:55 +0100

Update the heat path API

When using a picard order greater than 1, a heat path can have branches,
that is, its geometry can be composed of several bands of segments
whereas previously a path was a single and continuous list of segments.
In this commit, the list of strips of the registered paths are now
exposed via the heat path API.

Diffstat:
Msrc/sdis.h | 22+++++++++++++++-------
Msrc/sdis_heat_path.c | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/test_sdis_solve_probe.c | 30+++++++++++++++++++-----------
Msrc/test_sdis_utils.c | 136++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
4 files changed, 241 insertions(+), 86 deletions(-)

diff --git a/src/sdis.h b/src/sdis.h @@ -1193,24 +1193,32 @@ sdis_green_path_for_each_flux_term * Heat path API ******************************************************************************/ SDIS_API res_T -sdis_heat_path_get_vertices_count +sdis_heat_path_get_status (const struct sdis_heat_path* path, - size_t* nvertices); + enum sdis_heat_path_flag* status); SDIS_API res_T -sdis_heat_path_get_status +sdis_heat_path_get_line_strips_count (const struct sdis_heat_path* path, - enum sdis_heat_path_flag* status); + size_t* nstrips); + +SDIS_API res_T +sdis_heat_path_line_strip_get_vertices_count + (const struct sdis_heat_path* path, + const size_t istrip, + size_t* nvertices); SDIS_API res_T -sdis_heat_path_get_vertex +sdis_heat_path_line_strip_get_vertex (const struct sdis_heat_path* path, - const size_t ivertex, + const size_t istrip, + const size_t ivert, struct sdis_heat_vertex* vertex); SDIS_API res_T -sdis_heat_path_for_each_vertex +sdis_heat_path_line_strip_for_each_vertex (const struct sdis_heat_path* path, + const size_t istrip, sdis_process_heat_vertex_T func, void* context); diff --git a/src/sdis_heat_path.c b/src/sdis_heat_path.c @@ -34,17 +34,27 @@ #include "sdis_heat_path_conductive_Xd.h" /******************************************************************************* - * Exported functions + * Local functions ******************************************************************************/ -res_T -sdis_heat_path_get_vertices_count - (const struct sdis_heat_path* path, size_t* nvertices) +/* Return the offset into the list of vertices toward the first vertex of the + * line strip */ +static INLINE size_t +line_strip_vertex_offset(const struct sdis_heat_path* path, const size_t istrip) { - if(!path || !nvertices) return RES_BAD_ARG; - *nvertices = darray_heat_vertex_size_get(&path->vertices); - return RES_OK; + ASSERT(path); +#ifndef NDEBUG + { + size_t nstrips; + SDIS(heat_path_get_line_strips_count(path, &nstrips)); + ASSERT(istrip < nstrips); + } +#endif + return istrip == 0 ? 0 : darray_size_t_cdata_get(&path->breaks)[istrip-1] + 1; } +/******************************************************************************* + * Exported functions + ******************************************************************************/ res_T sdis_heat_path_get_status (const struct sdis_heat_path* path, enum sdis_heat_path_flag* status) @@ -55,28 +65,112 @@ sdis_heat_path_get_status } res_T -sdis_heat_path_get_vertex +sdis_heat_path_get_line_strips_count (const struct sdis_heat_path* path, - const size_t ivertex, + size_t* nstrips) +{ + if(!path || !nstrips) return RES_BAD_ARG; + /* #strips == #breaks + 1 */ + *nstrips = darray_size_t_size_get(&path->breaks) + 1; + return RES_OK; +} + +res_T +sdis_heat_path_line_strip_get_vertices_count + (const struct sdis_heat_path* path, + const size_t istrip, + size_t* out_nvertices) +{ + size_t nstrips = 0; + size_t ivert_begin = 0; + size_t ivert_end = 0; + res_T res = RES_OK; + + if(!path || !out_nvertices) { + res = RES_BAD_ARG; + goto error; + } + + res = sdis_heat_path_get_line_strips_count(path, &nstrips); + if(res != RES_OK) goto error; + + /* Check the indices of the strip */ + if(istrip >= nstrips) { + res = RES_BAD_ARG; + goto error; + } + + if(istrip == 0) { /* First strip */ + ivert_begin = 0; + } else { + ivert_begin = line_strip_vertex_offset(path, istrip); + } + + if(istrip == nstrips-1) { /* Last strip */ + ivert_end = darray_heat_vertex_size_get(&path->vertices) - ivert_begin; + } else { + ivert_end = line_strip_vertex_offset(path, istrip+1) - ivert_begin; + } + + ASSERT(ivert_begin <= ivert_end); + *out_nvertices = ivert_end - ivert_begin; + +exit: + return res; +error: + goto exit; +} + +res_T +sdis_heat_path_line_strip_get_vertex + (const struct sdis_heat_path* path, + const size_t istrip, + const size_t ivert, struct sdis_heat_vertex* vertex) { - if(!path || !vertex - || ivertex >= darray_heat_vertex_size_get(&path->vertices)) { - return RES_BAD_ARG; + size_t nverts = 0; + size_t ivert_adjusted = 0; + res_T res = RES_OK; + + if(!path || !vertex) { + res = RES_BAD_ARG; + goto error; } - *vertex = darray_heat_vertex_cdata_get(&path->vertices)[ivertex]; - return RES_OK; + /* By retrieving the number of vertices, we also check the validity of + * istrip: the function will return an error if istrip is invalid */ + res = sdis_heat_path_line_strip_get_vertices_count(path, istrip, &nverts); + if(res != RES_OK) goto error; + + if(ivert >= nverts) { + res = RES_BAD_ARG; + goto error; + } + + /* Compute the index into the overall list of vertices */ + ivert_adjusted = ivert + line_strip_vertex_offset(path, istrip); + ASSERT(ivert_adjusted < darray_heat_vertex_size_get(&path->vertices)); + + /* Fetch the vertex */ + *vertex = darray_heat_vertex_cdata_get(&path->vertices)[ivert_adjusted]; + +exit: + return res; +error: + goto exit; } res_T -sdis_heat_path_for_each_vertex +sdis_heat_path_line_strip_for_each_vertex (const struct sdis_heat_path* path, + const size_t istrip, sdis_process_heat_vertex_T func, void* context) { - const struct sdis_heat_vertex* vertices; - size_t i, n; + const struct sdis_heat_vertex* vertices = NULL; + size_t ivert = 0; + size_t offset = 0; + size_t nverts = 0; res_T res = RES_OK; if(!path || !func) { @@ -84,10 +178,14 @@ sdis_heat_path_for_each_vertex goto error; } - SDIS(heat_path_get_vertices_count(path, &n)); + res = sdis_heat_path_line_strip_get_vertices_count(path, istrip, &nverts); + if(res != RES_OK) goto error; + + offset = line_strip_vertex_offset(path, istrip); + vertices = darray_heat_vertex_cdata_get(&path->vertices); - FOR_EACH(i, 0, n) { - res = func(vertices+i, context); + FOR_EACH(ivert, 0, nverts) { + res = func(vertices+ivert+offset, context); if(res != RES_OK) goto error; } @@ -96,4 +194,3 @@ exit: error: goto exit; } - diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c @@ -208,10 +208,10 @@ process_heat_path(const struct sdis_heat_path* path, 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_line_strips_count(NULL, &n)); + BA(sdis_heat_path_get_line_strips_count(path, NULL)); + OK(sdis_heat_path_get_line_strips_count(path, &n)); + CHK(n == 1); BA(sdis_heat_path_get_status(NULL, &status)); BA(sdis_heat_path_get_status(path, NULL)); @@ -224,20 +224,28 @@ process_heat_path(const struct sdis_heat_path* path, void* context) 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)); + BA(sdis_heat_path_line_strip_get_vertices_count(NULL, 0, &n)); + BA(sdis_heat_path_line_strip_get_vertices_count(path, 1, &n)); + BA(sdis_heat_path_line_strip_get_vertices_count(path, 0, NULL)); + OK(sdis_heat_path_line_strip_get_vertices_count(path, 0, &n)); + CHK(n != 0); + + BA(sdis_heat_path_line_strip_get_vertex(NULL, 0, 0, &vert)); + BA(sdis_heat_path_line_strip_get_vertex(path, 1, 1, &vert)); + BA(sdis_heat_path_line_strip_get_vertex(path, 0, n, &vert)); + BA(sdis_heat_path_line_strip_get_vertex(path, 0, 0, NULL)); FOR_EACH(i, 0, n) { - OK(sdis_heat_path_get_vertex(path, i, &vert)); + OK(sdis_heat_path_line_strip_get_vertex(path, 0, 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)); + BA(sdis_heat_path_line_strip_for_each_vertex(NULL, 0, dump_vertex_pos, context)); + BA(sdis_heat_path_line_strip_for_each_vertex(path, 1, dump_vertex_pos, context)); + BA(sdis_heat_path_line_strip_for_each_vertex(path, 0, NULL, context)); + OK(sdis_heat_path_line_strip_for_each_vertex(path, 0, dump_vertex_pos, context)); FOR_EACH(i, 0, n-1) { fprintf(ctx->stream, "l %lu %lu\n", diff --git a/src/test_sdis_utils.c b/src/test_sdis_utils.c @@ -178,31 +178,54 @@ solve_green_path(struct sdis_green_path* path, void* ctx) return RES_OK; } +static size_t +heat_path_get_vertices_count(const struct sdis_heat_path* path) +{ + size_t istrip = 0; + size_t nstrips = 0; + size_t nvertices = 0; + CHK(path); + + OK(sdis_heat_path_get_line_strips_count(path, &nstrips)); + FOR_EACH(istrip, 0, nstrips) { + size_t n; + OK(sdis_heat_path_line_strip_get_vertices_count(path, istrip, &n)); + nvertices += n; + } + return nvertices; +} + static void -dump_heat_path_position(FILE* stream, const struct sdis_heat_path* path) +dump_heat_path_positions(FILE* stream, const struct sdis_heat_path* path) { - size_t nverts; - size_t ivert; + size_t istrip, nstrips; + size_t ivert, nverts; CHK(stream && path); - OK(sdis_heat_path_get_vertices_count(path, &nverts)); - FOR_EACH(ivert, 0, nverts) { - struct sdis_heat_vertex vtx; - OK(sdis_heat_path_get_vertex(path, ivert, &vtx)); - fprintf(stream, "%g %g %g\n", SPLIT3(vtx.P)); + OK(sdis_heat_path_get_line_strips_count(path, &nstrips)); + FOR_EACH(istrip, 0, nstrips) { + OK(sdis_heat_path_line_strip_get_vertices_count(path, istrip, &nverts)); + FOR_EACH(ivert, 0, nverts) { + struct sdis_heat_vertex vtx; + OK(sdis_heat_path_line_strip_get_vertex(path, istrip, ivert, &vtx)); + fprintf(stream, "%g %g %g\n", SPLIT3(vtx.P)); + } } } static void -dump_heat_path_segments - (FILE* stream, const struct sdis_heat_path* path, const size_t offset) +dump_heat_path_line_strip + (FILE* stream, + const struct sdis_heat_path* path, + const size_t istrip, + const size_t offset) { - size_t nverts, ivert; + size_t ivert, nverts; CHK(stream); - OK(sdis_heat_path_get_vertices_count(path, &nverts)); + OK(sdis_heat_path_line_strip_get_vertices_count(path, istrip, &nverts)); fprintf(stream, "%lu", (unsigned long)nverts); FOR_EACH(ivert, 0, nverts) { fprintf(stream, " %lu", (unsigned long)(ivert + offset)); @@ -216,29 +239,33 @@ dump_heat_path_vertex_attribs const struct sdis_heat_path* path, const enum heat_vertex_attrib attr) { - size_t nverts, ivert; + size_t ivert, nverts; + size_t istrip, nstrips; CHK(stream && path); - OK(sdis_heat_path_get_vertices_count(path, &nverts)); - FOR_EACH(ivert, 0, nverts) { - struct sdis_heat_vertex vtx; - OK(sdis_heat_path_get_vertex(path, ivert, &vtx)); - switch(attr) { - case HEAT_VERTEX_WEIGHT: - fprintf(stream, "%g\n", vtx.weight); - break; - case HEAT_VERTEX_TIME: - fprintf(stream, "%g\n", IS_INF(vtx.time) ? FLT_MAX : vtx.time); - break; - case HEAT_VERTEX_TYPE: - switch(vtx.type) { - case SDIS_HEAT_VERTEX_CONDUCTION: fprintf(stream, "0.0\n"); break; - case SDIS_HEAT_VERTEX_CONVECTION: fprintf(stream, "0.5\n"); break; - case SDIS_HEAT_VERTEX_RADIATIVE: fprintf(stream, "1.0\n"); break; - default: FATAL("Unreachable code.\n"); break; - } - break; - default: FATAL("Unreachable code.\n"); break; + OK(sdis_heat_path_get_line_strips_count(path, &nstrips)); + FOR_EACH(istrip, 0, nstrips) { + OK(sdis_heat_path_line_strip_get_vertices_count(path, istrip, &nverts)); + FOR_EACH(ivert, 0, nverts) { + struct sdis_heat_vertex vtx; + OK(sdis_heat_path_line_strip_get_vertex(path, istrip, ivert, &vtx)); + switch(attr) { + case HEAT_VERTEX_WEIGHT: + fprintf(stream, "%g\n", vtx.weight); + break; + case HEAT_VERTEX_TIME: + fprintf(stream, "%g\n", IS_INF(vtx.time) ? FLT_MAX : vtx.time); + break; + case HEAT_VERTEX_TYPE: + switch(vtx.type) { + case SDIS_HEAT_VERTEX_CONDUCTION: fprintf(stream, "0.0\n"); break; + case SDIS_HEAT_VERTEX_CONVECTION: fprintf(stream, "0.5\n"); break; + case SDIS_HEAT_VERTEX_RADIATIVE: fprintf(stream, "1.0\n"); break; + default: FATAL("Unreachable code.\n"); break; + } + break; + default: FATAL("Unreachable code.\n"); break; + } } } } @@ -306,9 +333,9 @@ dump_heat_paths(FILE* stream, const struct sdis_estimator* estimator) const struct sdis_heat_path* path; size_t ipath; size_t npaths; + size_t nstrips_overall; size_t nvertices; size_t offset; - size_t n; CHK(stream && estimator); OK(sdis_estimator_get_paths_count(estimator, &npaths)); @@ -320,30 +347,40 @@ dump_heat_paths(FILE* stream, const struct sdis_estimator* estimator) fprintf(stream, "ASCII\n"); fprintf(stream, "DATASET POLYDATA\n"); - /* Compute the overall number of vertices */ + /* Compute the overall number of vertices and the overall number of strips */ nvertices = 0; + nstrips_overall = 0; FOR_EACH(ipath, 0, npaths) { + size_t n; OK(sdis_estimator_get_path(estimator, ipath, &path)); - OK(sdis_heat_path_get_vertices_count(path, &n)); - nvertices += n; + nvertices += heat_path_get_vertices_count(path); + OK(sdis_heat_path_get_line_strips_count(path, &n)); + nstrips_overall += n; } /* Write path positions */ fprintf(stream, "POINTS %lu double\n", (unsigned long)nvertices); FOR_EACH(ipath, 0, npaths) { OK(sdis_estimator_get_path(estimator, ipath, &path)); - dump_heat_path_position(stream, path); + dump_heat_path_positions(stream, path); } /* Write the segment of the paths */ fprintf(stream, "LINES %lu %lu\n", - (unsigned long)npaths, (unsigned long)(npaths + nvertices)); + (unsigned long)(nstrips_overall), + (unsigned long)(nstrips_overall + nvertices)); offset = 0; FOR_EACH(ipath, 0, npaths) { + size_t path_istrip; + size_t path_nstrips; OK(sdis_estimator_get_path(estimator, ipath, &path)); - dump_heat_path_segments(stream, path, offset); - OK(sdis_heat_path_get_vertices_count(path, &n)); - offset += n; + OK(sdis_heat_path_get_line_strips_count(path, &path_nstrips)); + FOR_EACH(path_istrip, 0, path_nstrips) { + size_t n; + dump_heat_path_line_strip(stream, path, path_istrip, offset); + OK(sdis_heat_path_line_strip_get_vertices_count(path, path_istrip, &n)); + offset += n; + } } fprintf(stream, "POINT_DATA %lu\n", (unsigned long)nvertices); @@ -377,17 +414,22 @@ dump_heat_paths(FILE* stream, const struct sdis_estimator* estimator) } /* Write path type */ - fprintf(stream, "CELL_DATA %lu\n", (unsigned long)npaths); + fprintf(stream, "CELL_DATA %lu\n", (unsigned long)nstrips_overall); fprintf(stream, "SCALARS Path_Type float 1\n"); fprintf(stream, "LOOKUP_TABLE path_type\n"); FOR_EACH(ipath, 0, npaths) { + size_t path_istrip; + size_t path_nstrips; enum sdis_heat_path_flag status = SDIS_HEAT_PATH_NONE; OK(sdis_estimator_get_path(estimator, ipath, &path)); OK(sdis_heat_path_get_status(path, &status)); - switch(status) { - case SDIS_HEAT_PATH_SUCCESS: fprintf(stream, "0.0\n"); break; - case SDIS_HEAT_PATH_FAILURE: fprintf(stream, "1.0\n"); break; - default: FATAL("Unreachable code.\n"); break; + OK(sdis_heat_path_get_line_strips_count(path, &path_nstrips)); + FOR_EACH(path_istrip, 0, path_nstrips) { + switch(status) { + case SDIS_HEAT_PATH_SUCCESS: fprintf(stream, "0.0\n"); break; + case SDIS_HEAT_PATH_FAILURE: fprintf(stream, "1.0\n"); break; + default: FATAL("Unreachable code.\n"); break; + } } } fprintf(stream, "LOOKUP_TABLE path_type 2\n");