commit ac1c03a85352de91b3defb971fccd0ddb6c1861e
parent 766a73ab8e608bc0cc73e2bf46f0b546cc1b08cf
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 18 Mar 2019 15:44:31 +0100
Add option to dump paths in VTK files
Diffstat:
5 files changed, 129 insertions(+), 15 deletions(-)
diff --git a/src/args.h b/src/args.h
@@ -16,6 +16,13 @@ enum stardis_mode{
DUMP_VTK
};
+enum dump_path_type {
+ DUMP_NONE = 0,
+ DUMP_SUCCESS = BIT(0),
+ DUMP_ERROR = BIT(1),
+ DUMP_ALL = DUMP_SUCCESS | DUMP_ERROR,
+};
+
struct args{
char* medium_filename;
char* bc_filename;
@@ -29,6 +36,8 @@ struct args{
double scale_factor;
double radiative_temp[2];
char* camera;
+ enum dump_path_type dump_paths;
+ int just_help;
};
#ifdef NDEBUG
#define DEFAULT_NTHREADS SDIS_NTHREADS_DEFAULT
@@ -38,7 +47,7 @@ struct args{
#define ARGS_DEFAULT__ {\
NULL, NULL, 10000, DEFAULT_NTHREADS,\
{ { {0.0, 0.0, 0.0}, 0x7FF0000000000000 /* probe[3]=INF */}},\
- PROBE_COMPUTE, 1.0, {300.0, 300.0}, NULL}
+ PROBE_COMPUTE, 1.0, {300.0, 300.0}, NULL, DUMP_NONE, 0}
static const struct args ARGS_DEFAULT = ARGS_DEFAULT__;
static void
@@ -47,7 +56,8 @@ print_help(char* prog)
printf("stardis-app built-on stardis library version %i.%i.%i\n",
Stardis_VERSION_MAJOR,Stardis_VERSION_MINOR,Stardis_VERSION_PATCH);
printf("usage : \n%s -m MEDIUM.txt -b BOUNDARY.txt [-p X,Y,Z,TIME]\n", prog);
- printf("[-s SCALE_FACTOR] [-d] [-n NUM_OF_REALIZATIONS] [-t NUM_OF_THREADS]\n");
+ printf("[-s SCALE_FACTOR] [-d] [-D {all | error | success}]\n");
+ printf("[-n NUM_OF_REALIZATIONS] [-t NUM_OF_THREADS]\n");
printf("[-r AMBIENT_RAD_TEMP:REFERENCE_TEMP]\n");
printf("\n -h : print this help.\n");
printf("\nArguments\n");
@@ -70,6 +80,8 @@ print_help(char* prog)
printf("\n -d :\n");
printf(" dump geometry in VTK format with medium front/back id and\n");
printf(" boundary id.\n");
+ printf("\n -D { all | error | success } :\n");
+ printf(" dump paths in VTK format.\n");
printf("\n -n NUM_OF_REALIZATIONS :\n");
printf(" number of Monte-Carlo realizations.\n");
printf(" default value: 10000.\n");
@@ -104,13 +116,12 @@ parse_args(const int argc, char** argv, struct args* args)
goto error;
}
- while((opt = getopt(argc, argv, "hn:t:b:m:p:ds:r:R:")) != -1) {
+ while((opt = getopt(argc, argv, "hn:t:b:m:p:dD:s:r:R:")) != -1) {
switch(opt) {
case 'h':
print_help(argv[0]);
- res = RES_BAD_ARG;
- goto error;
- break;
+ args->just_help = 1;
+ goto exit;
case 'n': {
args->N = strtoull(optarg, NULL, 10);
@@ -154,6 +165,20 @@ parse_args(const int argc, char** argv, struct args* args)
args->mode = DUMP_VTK;
break;
+ case 'D':
+ if (0 == strcmp(optarg, "all")) {
+ args->dump_paths = DUMP_ALL;
+ } else if(0 == strcmp(optarg, "error")) {
+ args->dump_paths = DUMP_ERROR;
+ } else if(0 == strcmp(optarg, "success")) {
+ args->dump_paths = DUMP_SUCCESS;
+ } else {
+ res = RES_BAD_ARG;
+ fprintf(stderr, "Invalid argument -D %s\n", optarg);
+ goto error;
+ }
+ break;
+
case 's':
cstr_to_double(optarg, &args->scale_factor);
if (res != RES_OK
diff --git a/src/main.c b/src/main.c
@@ -15,6 +15,7 @@ int main(int argc, char** argv){
res = parse_args(argc, argv, &args);
if (res != RES_OK) goto error;
+ if (args.just_help) goto exit;
res = stardis_init(&args, &stardis);
if (res != RES_OK) goto error;
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -222,7 +222,7 @@ parse_medium_line(char* line, char** stl_filename, struct description* desc)
}
else {
res = RES_BAD_ARG;
- printf("Invalid medium type: %s\n", tk);
+ fprintf(stderr, "Invalid medium type: %s\n", tk);
}
#undef CHK_TOK
@@ -439,7 +439,7 @@ parse_boundary_line(char* line, char** stl_filename, struct description* desc)
}
}
else {
- printf("Invalid boundary type: %s", tk);
+ fprintf(stderr, "Invalid boundary type: %s", tk);
res = RES_BAD_ARG;
goto exit;
}
@@ -632,7 +632,7 @@ read_stl
res = sstl_load(sstl, *stl_filename);
if (res != RES_OK) {
- printf("Cannot read STL file: %s\n", *stl_filename);
+ fprintf(stderr, "Cannot read STL file: %s\n", *stl_filename);
goto error;
}
SSTL(get_desc(sstl, &stl_desc));
@@ -705,7 +705,7 @@ geometry_analyse
/* Register new medium description */
htable_descriptions_set(&descriptions, &desc, &desc_id);
} else {
- printf("Duplicate media description found: deduplicated.\n");
+ fprintf(stderr, "Duplicate media description found: deduplicated.\n");
desc_id = *p_desc;
}
@@ -742,7 +742,7 @@ geometry_analyse
/* Register new boundary description */
htable_descriptions_set(&descriptions, &desc, &desc_id);
} else {
- printf("Duplicate boundary description found: deduplicated.\n");
+ fprintf(stderr, "Duplicate boundary description found: deduplicated.\n");
desc_id = *p_desc;
}
@@ -842,6 +842,11 @@ stardis_init
stardis->scale_factor = args->scale_factor;
stardis->radiative_temp[0] = args->radiative_temp[0];
stardis->radiative_temp[1] = args->radiative_temp[1];
+ stardis->dump_paths = SDIS_HEAT_PATH_NONE;
+ if (args->dump_paths & DUMP_ERROR)
+ stardis->dump_paths |= SDIS_HEAT_PATH_FAILED;
+ if (args->dump_paths & DUMP_SUCCESS)
+ stardis->dump_paths |= SDIS_HEAT_PATH_SUCCEED;
if (args->mode == IR_COMPUTE){
res = parse_camera(args->camera, &stardis->camera);
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -888,9 +888,11 @@ struct stardis {
struct camera camera;
struct mem_allocator allocator;
int allocator_initialized;
+ enum sdis_heat_path_flag dump_paths;
};
#define NULL_ALLOCATOR__ {NULL}
-#define NULL_STARDIS__ {NULL_GEOMETRY__, NULL, 0, 0, {0,0,0,0}, 0, {300,300}, NULL_CAMERA__, NULL_ALLOCATOR__, 0}
+#define NULL_STARDIS__ {NULL_GEOMETRY__, NULL, 0, 0, {0,0,0,0}, 0,\
+ {300,300}, NULL_CAMERA__, NULL_ALLOCATOR__, 0, SDIS_HEAT_PATH_NONE}
static const struct stardis NULL_STARDIS = NULL_STARDIS__;
extern res_T
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -67,7 +67,7 @@ compile_expr_to_fn
*f = te_compile(math_expr, vars, t_allowed ? 4 : 3, NULL);
if (!*f) {
if (!t_allowed && te_compile(math_expr, vars, 4, NULL))
- printf("Expression use variable t and should not.\n");
+ fprintf(stderr, "Expression use variable t and should not.\n");
return RES_BAD_ARG;
}
if (is_zero) *is_zero = !((*f)->type == TE_CONSTANT && (*f)->v.value == 0);
@@ -671,6 +671,84 @@ error:
goto end;
}
+static res_T
+dump_path
+ (const struct sdis_heat_path* path,
+ void* context)
+{
+ FILE* stream = context;
+ enum sdis_heat_path_flag status = SDIS_HEAT_PATH_NONE;
+ size_t i, vcount;
+
+ /* Header */
+ fprintf(stream, "---\n");
+ fprintf(stream, "# vtk DataFile Version 2.0\n");
+ fprintf(stream, "Heat paths\n");
+ fprintf(stream, "ASCII\n");
+ fprintf(stream, "DATASET POLYDATA\n");
+ /* Write path positions */
+ sdis_heat_path_get_vertices_count(path, &vcount);
+ fprintf(stream, "POINTS %lu double\n", (unsigned long)vcount);
+ FOR_EACH(i, 0, vcount) {
+ struct sdis_heat_vertex vtx;
+ CHK(sdis_heat_path_get_vertex(path, i, &vtx) == RES_OK);
+ fprintf(stream, "%g %g %g\n", SPLIT3(vtx.P));
+ }
+ /* Write the segment of the path */
+ fprintf(stream, "LINES %lu %lu\n", 1, (unsigned long)(1 + vcount));
+ fprintf(stream, "%lu", (unsigned long)vcount);
+ FOR_EACH(i, 0, vcount) fprintf(stream, " %lu", (unsigned long)i);
+ fprintf(stream, "\n");
+ fprintf(stream, "POINT_DATA %lu\n", (unsigned long)vcount);
+ /* Write the type of the random walk vertices */
+ fprintf(stream, "SCALARS Vertex_Type float 1\n");
+ fprintf(stream, "LOOKUP_TABLE vertex_type\n");
+ FOR_EACH(i, 0, vcount) {
+ struct sdis_heat_vertex vtx;
+ CHK(sdis_heat_path_get_vertex(path, i, &vtx) == RES_OK);
+ 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;
+ }
+ }
+ fprintf(stream, "LOOKUP_TABLE vertex_type 3\n");
+ fprintf(stream, "0.0 1.0 1.0 1.0\n"); /* 0.0 = Magenta: conduction */
+ fprintf(stream, "1.0 1.0 0.0 1.0\n"); /* 0.5 = Yellow: convection */
+ fprintf(stream, "1.0 0.0 1.0 1.0\n"); /* 1.0 = Purple: radiative */
+ /* Write the weights of the random walk vertices */
+ fprintf(stream, "SCALARS Weight double 1\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ FOR_EACH(i, 0, vcount) {
+ struct sdis_heat_vertex vtx;
+ CHK(sdis_heat_path_get_vertex(path, i, &vtx) == RES_OK);
+ fprintf(stream, "%g\n", vtx.weight);
+ }
+ /* Write the time of the random walk vertices */
+ fprintf(stream, "SCALARS Time double 1\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ FOR_EACH(i, 0, vcount) {
+ struct sdis_heat_vertex vtx;
+ CHK(sdis_heat_path_get_vertex(path, i, &vtx) == RES_OK);
+ fprintf(stream, "%g\n", IS_INF(vtx.time) ? FLT_MAX : vtx.time);
+ }
+ /* Write path type */
+ fprintf(stream, "CELL_DATA %lu\n", 1);
+ fprintf(stream, "SCALARS Path_Type float 1\n");
+ fprintf(stream, "LOOKUP_TABLE path_type\n");
+ CHK(sdis_heat_path_get_status(path, &status) == RES_OK);
+ switch (status) {
+ case SDIS_HEAT_PATH_SUCCEED: fprintf(stream, "0.0\n"); break;
+ case SDIS_HEAT_PATH_FAILED: fprintf(stream, "1.0\n"); break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ fprintf(stream, "LOOKUP_TABLE path_type 2\n");
+ fprintf(stream, "0.0 0.0 1.0 1.0\n"); /* 0.0 = Blue: success */
+ fprintf(stream, "1.0 0.0 0.0 1.0\n"); /* 1.0 = Red: failure */
+ return RES_OK;
+}
+
res_T
stardis_compute(struct stardis* stardis, enum stardis_mode mode)
{
@@ -1103,7 +1181,7 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
stardis->scale_factor,
stardis->radiative_temp[0],
stardis->radiative_temp[1],
- SDIS_HEAT_PATH_NONE,
+ stardis->dump_paths,
&estimator));
} else {
SDIS(solve_probe_boundary(scn,
@@ -1115,7 +1193,7 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
stardis->scale_factor,
stardis->radiative_temp[0],
stardis->radiative_temp[1],
- SDIS_HEAT_PATH_NONE,
+ stardis->dump_paths,
&estimator));
}
}
@@ -1132,6 +1210,9 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
printf("#failures: %lu/%lu\n",
(unsigned long)nfailures,
(unsigned long)stardis->N);
+
+ /* Dump paths according to user settings */
+ sdis_estimator_for_each_path(estimator, dump_path, stdout);
}
end: