commit 0b55b361c80a46ea7640da87b375b79b63001e86
parent ac1c03a85352de91b3defb971fccd0ddb6c1861e
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 25 Mar 2019 18:22:39 +0100
Add option to integrate on a medium
Diffstat:
| M | src/args.h | | | 74 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- |
| M | src/stardis-app.c | | | 34 | +++++++++++++++++++++++++++------- |
| M | src/stardis-app.h | | | 51 | +++++++++++++++++++++++++++++++++++++++++---------- |
| M | src/stardis-compute.c | | | 155 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
4 files changed, 229 insertions(+), 85 deletions(-)
diff --git a/src/args.h b/src/args.h
@@ -12,8 +12,14 @@
enum stardis_mode{
PROBE_COMPUTE,
+ MEDIUM_COMPUTE,
IR_COMPUTE,
- DUMP_VTK
+ DUMP_VTK,
+ UNDEF_MODE
+};
+
+static const char MODE_OPTION[UNDEF_MODE] = {
+ 'p', 'm', 'R', 'd'
};
enum dump_path_type {
@@ -26,6 +32,7 @@ enum dump_path_type {
struct args{
char* medium_filename;
char* bc_filename;
+ char* medium_name;
size_t N;
unsigned nthreads;
union u {
@@ -45,9 +52,9 @@ struct args{
#define DEFAULT_NTHREADS 1
#endif
#define ARGS_DEFAULT__ {\
- NULL, NULL, 10000, DEFAULT_NTHREADS,\
+ NULL, NULL, NULL, 10000, DEFAULT_NTHREADS,\
{ { {0.0, 0.0, 0.0}, 0x7FF0000000000000 /* probe[3]=INF */}},\
- PROBE_COMPUTE, 1.0, {300.0, 300.0}, NULL, DUMP_NONE, 0}
+ UNDEF_MODE, 1.0, {300.0, 300.0}, NULL, DUMP_NONE, 0}
static const struct args ARGS_DEFAULT = ARGS_DEFAULT__;
static void
@@ -55,17 +62,19 @@ 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] [-D {all | error | success}]\n");
+ printf("usage : \n%s -M MEDIUM.txt -B BOUNDARY.txt\n", prog);
+ printf("[-p X,Y,Z,TIME | -m medium_name,TIME] | -d \n");
+ printf(" | -R spp = SPP:fov = FOV : up = XUP, YUP, ZUP : pos = X, Y, Z : tgt = XT, YT, ZT : img = WxH]\n");
+ printf("[-s SCALE_FACTOR] [-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");
printf("---------\n");
- printf("\n -m MEDIUM.txt :\n");
+ printf("\n -M MEDIUM.txt :\n");
printf(" MEDIUM.txt is a text file which contains the description of the\n");
printf(" media.\n");
- printf("\n -b BOUNDARY.txt :\n");
+ printf("\n -B BOUNDARY.txt :\n");
printf(" BOUNDARY.txt is a text file which contains the description of the\n");
printf(" boundary conditions.\n");
printf("\nOptionnal arguments\n");
@@ -75,6 +84,9 @@ print_help(char* prog)
printf(" default value: 0.0,0.0,0.0,INF.\n");
printf(" The probe must be in a medium. If some boundary conditions are\n");
printf(" time-dependant, TIME can not be INF.\n");
+ printf("\n -m medium_name,TIME :\n");
+ printf(" this is the medium name and the time of the by-medium integration.\n");
+ printf(" If some boundary conditions are time-dependant, TIME can not be INF.\n");
printf("\n -s SCALE_FACTOR :\n");
printf(" default value: 1.0.\n");
printf("\n -d :\n");
@@ -116,7 +128,7 @@ parse_args(const int argc, char** argv, struct args* args)
goto error;
}
- while((opt = getopt(argc, argv, "hn:t:b:m:p:dD:s:r:R:")) != -1) {
+ while((opt = getopt(argc, argv, "hn:t:B:M:m:p:dD:s:r:R:")) != -1) {
switch(opt) {
case 'h':
print_help(argv[0]);
@@ -133,11 +145,11 @@ parse_args(const int argc, char** argv, struct args* args)
break;
}
- case 'b':
+ case 'B':
args->bc_filename = optarg;
break;
- case 'm':
+ case 'M':
args->medium_filename = optarg;
break;
@@ -152,16 +164,50 @@ parse_args(const int argc, char** argv, struct args* args)
break;
case 'p':
+ if (args->mode != UNDEF_MODE) {
+ res = RES_BAD_ARG;
+ fprintf(stderr, "Cannot specify multiple modes: -%c and -%c\n",
+ (char)opt, MODE_OPTION[args->mode]);
+ goto error;
+ }
+ args->mode = PROBE_COMPUTE;
cstr_to_list_double(optarg, ',', args->u.probe, &len, 4);
if(len != 4
- || res != RES_OK){
+ || res != RES_OK) {
res = RES_BAD_ARG;
fprintf(stderr, "Invalid argument -p %s\n", optarg);
goto error;
}
break;
+ case 'm': {
+ if (args->mode != UNDEF_MODE) {
+ res = RES_BAD_ARG;
+ fprintf(stderr, "Cannot specify multiple modes: -%c and -%c\n",
+ (char)opt, MODE_OPTION[args->mode]);
+ goto error;
+ }
+ args->mode = MEDIUM_COMPUTE;
+ char* ptr = strpbrk(optarg, ",");
+ if (! ptr || ptr == optarg)
+ res = RES_BAD_ARG;
+ else res = cstr_to_double(ptr+1, args->u.probe+3);
+ if (res != RES_OK) {
+ fprintf(stderr, "Invalid argument -m %s\n", optarg);
+ goto error;
+ }
+ *ptr = '\0';
+ args->medium_name = optarg;
+ break;
+ }
+
case 'd':
+ if (args->mode != UNDEF_MODE) {
+ res = RES_BAD_ARG;
+ fprintf(stderr, "Cannot specify multiple modes: -%c and -%c\n",
+ (char)opt, MODE_OPTION[args->mode]);
+ goto error;
+ }
args->mode = DUMP_VTK;
break;
@@ -202,6 +248,12 @@ parse_args(const int argc, char** argv, struct args* args)
break;
case 'R':
+ if (args->mode != UNDEF_MODE) {
+ res = RES_BAD_ARG;
+ fprintf(stderr, "Cannot specify multiple modes: -%c and -%c\n",
+ (char)opt, MODE_OPTION[args->mode]);
+ goto error;
+ }
args->mode = IR_COMPUTE;
args->camera = optarg;
break;
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -116,8 +116,8 @@ _strupr(char* s)
/* Read medium line; should be one of:
- * SOLID STL_filename lambda rho cp delta "Tinit(x,y,z)" [ "volumic_power(x,y,z,t)" ]
- * FLUID STL_filename rho cp "Tinit(x,y,z)"
+ * SOLID medium_name STL_filename lambda rho cp delta "Tinit(x,y,z)" [ "volumic_power(x,y,z,t)" ]
+ * FLUID medium_name STL_filename rho cp "Tinit(x,y,z)"
*/
static res_T
parse_medium_line(char* line, char** stl_filename, struct description* desc)
@@ -134,6 +134,14 @@ parse_medium_line(char* line, char** stl_filename, struct description* desc)
if (strcmp(tk, "SOLID") == 0) {
desc->type = DESC_MAT_SOLID;
+ CHK_TOK(strtok(NULL, " "), "medium name");
+ if (strlen(tk) >= sizeof(desc->name)) {
+ fprintf(stderr, "Medium name is too long: %s\n", tk);
+ res = RES_BAD_ARG;
+ goto exit;
+ }
+ strncpy(desc->name, tk, sizeof(desc->name));
+
CHK_TOK(strtok(NULL, " "), "file name");
*stl_filename = malloc(strlen(tk) + 1);
strcpy(*stl_filename, tk);
@@ -194,6 +202,14 @@ parse_medium_line(char* line, char** stl_filename, struct description* desc)
else if (strcmp(tk, "FLUID") == 0) {
desc->type = DESC_MAT_FLUID;
+ CHK_TOK(strtok(NULL, " "), "medium name");
+ if (strlen(tk) >= sizeof(desc->name)) {
+ fprintf(stderr, "Medium name is too long: %s\n", tk);
+ res = RES_BAD_ARG;
+ goto exit;
+ }
+ strncpy(desc->name, tk, sizeof(desc->name));
+
CHK_TOK(strtok(NULL, " "), "file name");
*stl_filename = malloc(strlen(tk) + 1);
strcpy(*stl_filename, tk);
@@ -692,11 +708,12 @@ geometry_analyse
char* stl_filename = NULL;
struct description desc;
- desc.type = DESCRIPTION_TYPE_COUNT__;
+ init_description(&desc);
res = parse_medium_line(line, &stl_filename, &desc);
if (res != RES_OK) goto error;
- /* Deduplicate media: find if the same description already exists */
+ /* Deduplicate media: find if the same description already exists
+ * (including name) */
p_desc = htable_descriptions_find(&descriptions, &desc);
if (!p_desc) {
sa_push(stardis->descriptions, desc);
@@ -729,11 +746,12 @@ geometry_analyse
char* stl_filename = NULL;
struct description desc;
- desc.type = DESCRIPTION_TYPE_COUNT__;
+ init_description(&desc);
res = parse_boundary_line(line, &stl_filename, &desc);
if (res != RES_OK) goto error;
- /* Deduplicate media: find if the same description already exists */
+ /* Deduplicate media: find if the same description already exists
+ * (including name) */
p_desc = htable_descriptions_find(&descriptions, &desc);
if (!p_desc) {
sa_push(stardis->descriptions, desc);
@@ -852,7 +870,9 @@ stardis_init
res = parse_camera(args->camera, &stardis->camera);
if (res != RES_OK) goto error;
}
-
+ else if (args->mode == MEDIUM_COMPUTE) {
+ strcpy(stardis->medium_name, args->medium_name);
+ }
exit:
return res;
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -122,6 +122,7 @@ release_geometry(struct geometry* geom)
}
struct mat_fluid {
+ char name[16];
unsigned fluid_id;
double rho;
double cp;
@@ -133,14 +134,15 @@ print_fluid(FILE* stream, const struct mat_fluid* f)
{
ASSERT(stream && f);
fprintf(stream,
- "Fluid %u: cp=%g rho=%g Tinit='%s'\n",
- f->fluid_id, f->cp, f->rho, f->Tinit);
+ "Fluid '%s': cp=%g rho=%g Tinit='%s'\n",
+ f->name, f->cp, f->rho, f->Tinit);
}
static char
eq_fluid(const struct mat_fluid* a, const struct mat_fluid* b)
{
- if (a->fluid_id != b->fluid_id
+ if (strcmp(a->name, b->name)
+ || a->fluid_id != b->fluid_id
|| a->rho != b->rho
|| a->cp != b->cp
|| strcmp(a->Tinit, b->Tinit))
@@ -159,6 +161,10 @@ hash_fluid(const struct mat_fluid* key)
uint32_t hash = OFFSET32_BASIS;
size_t i;
ASSERT(key);
+ FOR_EACH(i, 0, sizeof(key->name)) {
+ hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->name)[i]);
+ hash = hash * FNV32_PRIME;
+ }
FOR_EACH(i, 0, sizeof(key->fluid_id)) {
hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->fluid_id)[i]);
hash = hash * FNV32_PRIME;
@@ -184,6 +190,10 @@ hash_fluid(const struct mat_fluid* key)
uint64_t hash = OFFSET64_BASIS;
size_t i;
ASSERT(key);
+ FOR_EACH(i, 0, sizeof(key->name)) {
+ hash = hash ^ (uint64_t)((unsigned char)((const char*)&key->name)[i]);
+ hash = hash * FNV64_PRIME;
+ }
FOR_EACH(i, 0, sizeof(key->fluid_id)) {
hash = hash ^ (uint64_t)((unsigned char)((const char*)&key->fluid_id)[i]);
hash = hash * FNV64_PRIME;
@@ -207,6 +217,7 @@ hash_fluid(const struct mat_fluid* key)
}
struct mat_solid {
+ char name[16];
unsigned solid_id;
double lambda;
double rho;
@@ -222,15 +233,16 @@ print_solid(FILE* stream, const struct mat_solid* s)
{
ASSERT(stream && s);
fprintf(stream,
- "Solid %u: lambda=%g cp=%g rho=%g delta=%g Tinit='%s' Power='%s'\n",
- s->solid_id, s->lambda, s->cp, s->rho, s->delta,
+ "Solid '%s': lambda=%g cp=%g rho=%g delta=%g Tinit='%s' Power='%s'\n",
+ s->name, s->lambda, s->cp, s->rho, s->delta,
s->Tinit, (s->has_power ? s->power : "0"));
}
static char
eq_solid(const struct mat_solid* a, const struct mat_solid* b)
{
- if (a->solid_id != b->solid_id
+ if (strcmp(a->name, b->name)
+ || a->solid_id != b->solid_id
|| a->lambda != b->lambda
|| a->rho != b->rho
|| a->cp != b->cp
@@ -253,6 +265,10 @@ hash_solid(const struct mat_solid* key)
uint32_t hash = OFFSET32_BASIS;
size_t i;
ASSERT(key);
+ FOR_EACH(i, 0, sizeof(key->name)) {
+ hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->name)[i]);
+ hash = hash * FNV32_PRIME;
+ }
FOR_EACH(i, 0, sizeof(key->solid_id)) {
hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->solid_id)[i]);
hash = hash * FNV32_PRIME;
@@ -295,6 +311,10 @@ hash_solid(const struct mat_solid* key)
uint64_t hash = OFFSET64_BASIS;
size_t i;
ASSERT(key);
+ FOR_EACH(i, 0, sizeof(key->name)) {
+ hash = hash ^ (uint64_t)((unsigned char)((const char*)&key->name)[i]);
+ hash = hash * FNV64_PRIME;
+ }
FOR_EACH(i, 0, sizeof(key->solid_id)) {
hash = hash ^ (uint64_t)((unsigned char)((const char*)&key->solid_id)[i]);
hash = hash * FNV64_PRIME;
@@ -781,6 +801,7 @@ hash_sf_connect(const struct solid_fluid_connect* key)
}
struct description {
+ char name[16];
enum description_type type;
union d {
struct mat_fluid fluid;
@@ -792,6 +813,13 @@ struct description {
} d;
};
+FINLINE void
+init_description(struct description* desc) {
+ ASSERT(desc);
+ desc->name[0] = '\0';
+ desc->type = DESCRIPTION_TYPE_COUNT__;
+}
+
static INLINE void
print_description
(FILE* stream,
@@ -880,19 +908,22 @@ struct stardis {
struct geometry geometry;
struct description* descriptions; /*array of materials and boundaries */
+ double probe[4]; /* x,y,z,t of probe when mode is PROBE_COMPUTE */
+ struct camera camera; /* camera when mode is IR_COMPUTE */
+ char medium_name[64]; /* medium name when mode is MEDIUM_COMPUTE */
+
size_t N; /*number of MC realizations*/
unsigned nthreads;
- double probe[4]; /*x,y,z,t of probe*/
double scale_factor;
double radiative_temp[2];
- 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, SDIS_HEAT_PATH_NONE}
+#define NULL_STARDIS__ {NULL_GEOMETRY__, NULL,\
+ {0,0,0,0}, NULL_CAMERA__, "",\
+ 0, 0, 0, {300,300}, 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
@@ -542,7 +542,8 @@ end:
error:
goto end;
}
-res_T
+
+static res_T
create_edge_file_if
(struct sdis_scene* scn,
struct mem_allocator* allocator)
@@ -695,7 +696,7 @@ dump_path
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, "LINES %lu %lu\n", 1lu, (unsigned long)(1 + vcount));
fprintf(stream, "%lu", (unsigned long)vcount);
FOR_EACH(i, 0, vcount) fprintf(stream, " %lu", (unsigned long)i);
fprintf(stream, "\n");
@@ -734,7 +735,7 @@ dump_path
fprintf(stream, "%g\n", IS_INF(vtx.time) ? FLT_MAX : vtx.time);
}
/* Write path type */
- fprintf(stream, "CELL_DATA %lu\n", 1);
+ fprintf(stream, "CELL_DATA %lu\n", 1lu);
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);
@@ -841,6 +842,7 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
solid_get_tinit,
&stardis->descriptions[i].d.solid.has_power,
&desc->d.solid.solid_id);
+ strcpy(desc->d.solid.name, desc->name);
if (res != RES_OK) goto error;
break;
case DESC_MAT_FLUID:
@@ -852,6 +854,7 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
&media,
fluid_get_tinit,
&desc->d.fluid.fluid_id);
+ strcpy(desc->d.fluid.name, desc->name);
if (res != RES_OK) goto error;
break;
default: FATAL("Invalid type.\n");
@@ -1120,7 +1123,7 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
res = create_edge_file_if(scn, &stardis->allocator);
if (res != RES_OK) goto error;
- if (mode == IR_COMPUTE){
+ if (mode == IR_COMPUTE) {
size_t width = (size_t)stardis->camera.img[0];
size_t height = (size_t)stardis->camera.img[1];
@@ -1155,65 +1158,103 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
/* Write the image */
dump_image(buf);
}
-
- if (mode == PROBE_COMPUTE){
+ else if (mode == PROBE_COMPUTE) {
+ double uv[2] = { 0,0 };
+ size_t iprim = SIZE_MAX;
/* Launch the probe simulation */
pos[0] = stardis->probe[0];
pos[1] = stardis->probe[1];
pos[2] = stardis->probe[2];
- time[0] = time[1] = stardis->probe[3];
- {
- double uv[2] = {0,0};
- size_t iprim = SIZE_MAX;
-
- res = select_probe_type(scn,
- stardis->geometry.triangle,
- stardis->descriptions,
- pos,
- &iprim,
- uv);
-
- if(iprim == SIZE_MAX){
- SDIS(solve_probe(scn,
- stardis->N,
- pos,
- time,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- stardis->dump_paths,
- &estimator));
- } else {
- SDIS(solve_probe_boundary(scn,
- stardis->N,
- iprim,
- uv,
- time,
- SDIS_FRONT,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- stardis->dump_paths,
- &estimator));
- }
+ time[0] = time[1] = stardis->probe[3];
+
+ res = select_probe_type(scn,
+ stardis->geometry.triangle,
+ stardis->descriptions,
+ pos,
+ &iprim,
+ uv);
+
+ if (iprim == SIZE_MAX) {
+ SDIS(solve_probe(scn,
+ stardis->N,
+ pos,
+ time,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ stardis->dump_paths,
+ &estimator));
+ } else {
+ SDIS(solve_probe_boundary(scn,
+ stardis->N,
+ iprim,
+ uv,
+ time,
+ SDIS_FRONT,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ stardis->dump_paths,
+ &estimator));
}
-
- /* Fetch the estimation data */
- SDIS(estimator_get_temperature(estimator, &temperature));
- SDIS(estimator_get_failure_count(estimator, &nfailures));
-
- /* Print the results */
- printf("Temperature at [%g, %g, %g, %g] = %g +/- %g\n",
- pos[0], pos[1], pos[2], time[0],
- temperature.E, /* Expected value */
- temperature.SE); /* Standard error */
- 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);
}
+ else if (mode == MEDIUM_COMPUTE) {
+ size_t sz, ii;
+ struct sdis_medium* medium = NULL;
+ /* Find medium */
+ sz = sa_size(stardis->descriptions);
+ FOR_EACH(ii, 0, sz) {
+ struct description* desc = stardis->descriptions + ii;
+ if (desc->type == DESC_MAT_SOLID) {
+ if (0 == strcmp(stardis->medium_name, desc->d.solid.name)) {
+ ASSERT(sa_size(media) > ii);
+ medium = media[ii];
+ break;
+ }
+ }
+ else if (desc->type == DESC_MAT_FLUID) {
+ if (0 == strcmp(stardis->medium_name, desc->d.fluid.name)) {
+ ASSERT(sa_size(media) > ii);
+ medium = media[ii];
+ break;
+ }
+ }
+ }
+ if (medium == NULL) {
+ /* Not found */
+ fprintf(stderr, "Cannot solve medium %s (unknown medium)\n",
+ stardis->medium_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ time[0] = time[1] = stardis->probe[3];
+ SDIS(solve_medium(scn,
+ stardis->N,
+ medium,
+ time,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ stardis->dump_paths,
+ &estimator));
+ }
+ if (mode == PROBE_COMPUTE || mode == MEDIUM_COMPUTE) {
+ /* Fetch the estimation data */
+ SDIS(estimator_get_temperature(estimator, &temperature));
+ SDIS(estimator_get_failure_count(estimator, &nfailures));
+
+ /* Print the results */
+ printf("Temperature at [%g, %g, %g, %g] = %g +/- %g\n",
+ pos[0], pos[1], pos[2], time[0],
+ temperature.E, /* Expected value */
+ temperature.SE); /* Standard error */
+ 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:
if (data) SDIS(data_ref_put(data));;