stardis

Perform coupled heat transfer calculations
git clone git://git.meso-star.fr/stardis.git
Log | Files | Refs | README | LICENSE

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:
Msrc/args.h | 74+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/stardis-app.c | 34+++++++++++++++++++++++++++-------
Msrc/stardis-app.h | 51+++++++++++++++++++++++++++++++++++++++++----------
Msrc/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));;