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:
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));