commit 03ea5f7ca645f39ec62d7a0dca6032061911777f
parent 8a56fd6a51ea677858b227a09cf2e0fed20712df
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 17 Feb 2021 16:51:29 +0100
Finished parsing probe interface
Diffstat:
5 files changed, 215 insertions(+), 46 deletions(-)
diff --git a/doc/stardis.1.txt.in b/doc/stardis.1.txt.in
@@ -95,11 +95,11 @@ EXCLUSIVE OPTIONS
be in a medium. The probe coordinates must be in the same system as the
geometry.
-*-P* _x,y,z[,time[,time]][,medium_name]_::
+*-P* _x,y,z[,time[,time]][:side_indicator]_::
Compute the temperature at the given probe on an interface at a given time.
If the probe is on an interface where a thermal contact resistance is
- defined it is mandatory to provide a medium name, as the temperature differs
- between the two sides.
+ defined, it is mandatory to provide a side indicator (either FRONT, BACK, or
+ a medium name), as the temperature differs between the two sides.
By default the compute time is @STARDIS_ARGS_DEFAULT_COMPUTE_TIME@. The
probe is supposed to be on an interface and is moved to the closest point of
the closest interface before the computation starts. The probe coordinates
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -31,10 +31,18 @@
#include <rsys/image.h>
#include <rsys/clock_time.h>
+#ifdef COMPILER_GCC
+#include <strings.h> /* strcasecmp */
+#else
+#include <string.h>
+#define strcasecmp(s1, s2) _stricmp((s1), (s2))
+#endif
+
/*******************************************************************************
* Local Functions
******************************************************************************/
+
struct filter_ctx {
const struct stardis* stardis;
unsigned prim;
@@ -456,19 +464,147 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start)
= SDIS_SOLVE_PROBE_BOUNDARY_ARGS_DEFAULT;
FILE* stream = NULL;
struct time compute_start, compute_end;
+ enum sdis_side compute_side;
+ unsigned prop[3];
+ const size_t dcount = darray_descriptions_size_get(&stardis->descriptions);
+ const struct description* descriptions
+ = darray_descriptions_cdata_get(&stardis->descriptions);
+ double tcr = 0;
+ const char* solve_name;
+ const char* compute_side_name = NULL;
+ const char* medium_name = NULL;
+ const struct description* intface_desc;
ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE));
ERR(check_probe_conform_to_type(stardis, 1, stardis->probe, &iprim, uv));
ASSERT(iprim != UINT_MAX);
- /* Find medium */
- medium = find_medium_by_name(stardis, &stardis->solve_name, NULL);
- if(medium == NULL) { /* Not found */
- logger_print(stardis->logger, LOG_ERROR,
- "Cannot solve on this side '%s' (unknown medium)\n",
- str_cget(&stardis->solve_name));
- res = RES_BAD_ARG;
- goto error;
+ ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d,
+ (unsigned)iprim, prop));
+
+ ASSERT(prop[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY
+ && prop[SG3D_INTFACE] < dcount);
+ intface_desc = descriptions + prop[SG3D_INTFACE];
+ if(intface_desc->type == DESC_SOLID_SOLID_CONNECT)
+ tcr = intface_desc->d.ss_connect.tcr;
+
+ solve_name = str_is_empty(&stardis->solve_name)
+ ? NULL : str_cget(&stardis->solve_name);
+ if(!solve_name) {
+ compute_side = SDIS_SIDE_NULL__; /* Side is let unspecified */
+ }
+ else if(0 == strcasecmp(solve_name, "FRONT")) {
+ const struct description* d;
+ ASSERT(prop[SG3D_FRONT] < dcount);
+ d = descriptions + prop[SG3D_FRONT];
+ ASSERT(d->type == DESC_MAT_SOLID || d->type == DESC_MAT_FLUID);
+ medium_name = str_cget(get_description_name(d));
+ compute_side = SDIS_FRONT;
+ compute_side_name = "FRONT";
+ }
+ else if(0 == strcasecmp(solve_name, "BACK")) {
+ const struct description* d;
+ ASSERT(prop[SG3D_BACK] < dcount);
+ d = descriptions + prop[SG3D_BACK];
+ ASSERT(d->type == DESC_MAT_SOLID || d->type == DESC_MAT_FLUID);
+ medium_name = str_cget(get_description_name(d));
+ compute_side = SDIS_BACK;
+ compute_side_name = "BACK";
+ } else { /* solve_name must be a medium name */
+ unsigned med_id, fmat_id, bmat_id;
+ const struct description* fd;
+ const struct description* bd;
+ struct sdis_medium* medium
+ = find_medium_by_name(stardis, &stardis->solve_name, &med_id);
+ if(medium == NULL) { /* Not found */
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot locate side from medium name '%s' (unknown medium)\n",
+ solve_name);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ fd = descriptions + prop[SG3D_FRONT];
+ bd = descriptions + prop[SG3D_BACK];
+ ASSERT(fd->type == DESC_MAT_SOLID || fd->type == DESC_MAT_FLUID);
+ fmat_id = (fd->type == DESC_MAT_SOLID)
+ ? fd->d.solid.solid_id : fd->d.fluid.fluid_id;
+ ASSERT(bd->type == DESC_MAT_SOLID || bd->type == DESC_MAT_FLUID);
+ bmat_id = (bd->type == DESC_MAT_SOLID)
+ ? bd->d.solid.solid_id : bd->d.fluid.fluid_id;
+
+ if(med_id != fmat_id && med_id != bmat_id) { /* Not here */
+ logger_print(stardis->logger, LOG_ERROR,
+ "Medium '%s' is not used at this interface (prim id=%lu)\n",
+ solve_name, (unsigned long)iprim);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(fmat_id == bmat_id) { /* Cannot differentiate */
+ logger_print(stardis->logger, LOG_ERROR,
+ "Medium '%s' is used on both sides of this interface (prim id=%lu)\n",
+ solve_name, (unsigned long)iprim);
+ logger_print(stardis->logger, LOG_ERROR,
+ "Side must be defined using either FRONT or BACK.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ medium_name = solve_name;
+ if(med_id == fmat_id) {
+ compute_side = SDIS_FRONT;
+ compute_side_name = "FRONT";
+ } else {
+ compute_side = SDIS_BACK;
+ compute_side_name = "BACK";
+ }
+ }
+
+ if(compute_side == SDIS_SIDE_NULL__) {
+ /* Cannot have defined a contact resistance here */
+ if(tcr != 0) {
+ const struct description* fdesc = NULL;
+ const struct description* bdesc = NULL;
+ if(prop[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY) {
+ ASSERT(prop[SG3D_FRONT] < dcount);
+ fdesc = descriptions + prop[SG3D_FRONT];
+ }
+ if(prop[SG3D_BACK] != SG3D_UNSPECIFIED_PROPERTY) {
+ ASSERT(prop[SG3D_BACK] < dcount);
+ bdesc = descriptions + prop[SG3D_BACK];
+ }
+ ASSERT(fdesc || bdesc);
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot let probe computation side unspecified on an interface with a "
+ "non-nul thermal resistance.\n");
+ logger_print(stardis->logger, LOG_ERROR,
+ "Interface '%s',%s%s%s%s%s%s%s, resistance=%g K.m^2/W.\n",
+ str_cget(get_description_name(intface_desc)),
+ (fdesc ? " FRONT:'" : ""),
+ (fdesc ? str_cget(get_description_name(fdesc)) : ""),
+ (fdesc ? "'" : ""),
+ (fdesc && bdesc ? "," : ""),
+ (bdesc ? " BACK:'" : ""),
+ (bdesc ? str_cget(get_description_name(bdesc)) : ""),
+ (bdesc ? "'" : ""),
+ tcr);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* Any side is OK as temperature is the same */
+ compute_side = SDIS_FRONT;
+ } else if (tcr == 0) {
+ /* Warn if side defined and no resistance defined */
+ logger_print(stardis->logger, LOG_WARNING,
+ "Specifying a compute side at an interface with no contact resistance "
+ "is meaningless.\n");
+ }
+
+ if(tcr > 0) {
+ ASSERT(compute_side_name && medium_name);
+ logger_print(stardis->logger, LOG_OUTPUT,
+ "Probe computation on an interface with a thermal resistance = %g K.m^2/W "
+ "on %s side (medium is '%s').\n",
+ tcr, compute_side_name, medium_name);
}
args.nrealisations = stardis->samples;
diff --git a/src/stardis-main.c b/src/stardis-main.c
@@ -56,7 +56,7 @@ main
ERR(init_args(&logger, &allocator, &args));
args_initialized = 1;
- ERR(parse_args(argc, argv, args));
+ ERR(parse_args(argc, argv, args, &allocator));
mode = args->mode;
if(mode & MODE_DUMP_HELP) {
diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c
@@ -31,17 +31,15 @@
#include <ctype.h>
#include <string.h>
#ifdef COMPILER_GCC
-#include <strings.h>
+#include <strings.h> /* strcasecmp */
+#else
+#define strcasecmp(s1, s2) _stricmp((s1), (s2))
#endif
/*******************************************************************************
* Local Functions
******************************************************************************/
-#ifdef COMPILER_CL
-#define strcasecmp(s1, s2) _stricmp((s1), (s2))
-#endif
-
static char**
split_line
(char* a_str,
@@ -506,13 +504,23 @@ short_help
fprintf(stream, " Set the verbosity level.\n");
}
+#define FREE_AARRAY(ARRAY) \
+if(ARRAY) {\
+ int i__ = 0; \
+ for(i__=0; *((ARRAY)+i__);i__++){\
+ free((ARRAY)[i__]);\
+ }\
+ free(ARRAY);\
+ (ARRAY) = NULL;\
+}
+
/* Workaround for a gcc warning when GET_OPTIONAL_TIME_RANGE used with Rank=0 */
FINLINE int is_less(size_t a, size_t b) { return a < b; }
/* Get a time range from a coma-separated list of doubles
* The first Rank values are mandatory, followed by an optional time range
* that can be a single time */
-#define GET_OPTIONAL_TIME_RANGE(Src, Rank, Dst, Logger, OptionString, Option) \
+#define GET_OPTIONAL_TIME_RANGE(Src, Rank, Dst, Logger, OptionString, Option, FullSrc) \
res = cstr_to_list_double((Src), ',', (Dst), &len, (Rank)+2); \
if(res != RES_OK \
|| is_less(len, (Rank)) \
@@ -523,7 +531,7 @@ FINLINE int is_less(size_t a, size_t b) { return a < b; }
if(res == RES_OK) res = RES_BAD_ARG; \
logger_print((Logger), LOG_ERROR, \
"Invalid argument for option "OptionString": %s\n", \
- (Option), (Src)); \
+ (Option), (FullSrc)); \
goto error; \
} else { \
if(len == (Rank)+1) (Dst)[(Rank)+1] = (Dst)[(Rank)];\
@@ -533,29 +541,33 @@ FINLINE int is_less(size_t a, size_t b) { return a < b; }
#define GET_STR_AND_OPTIONAL_TIME_RANGE(Str, Time) \
ptr = strchr(optarg, ','); /* First ',' */ \
if(ptr) { /* Time range provided */ \
- GET_OPTIONAL_TIME_RANGE(ptr+1, 0, (Time), args->logger, "-%c", opt); \
+ GET_OPTIONAL_TIME_RANGE(ptr+1, 0, (Time), args->logger, "-%c", opt, optarg); \
*ptr = '\0'; \
} \
(Str) = optarg;
/* Get a position followed by an optional time range */
-#define GET_POS_AND_OPTIONAL_TIME_RANGE(Dst) \
- GET_OPTIONAL_TIME_RANGE(optarg, 3, (Dst), args->logger, "-%c", opt);
+#define GET_POS_AND_OPTIONAL_TIME_RANGE(Src, Dst, FullSrc) \
+ GET_OPTIONAL_TIME_RANGE((Src), 3, (Dst), args->logger, "-%c", opt, (FullSrc));
res_T
parse_args
(const int argc,
char** argv,
- struct args* args)
+ struct args* args,
+ struct mem_allocator* allocator)
{
int opt = 0, n_used = 0;
size_t len = 0;
const char option_list[] = "a:c:dD:eF:gG:hm:M:n:p:P:r:R:s:S:t:vV:";
char buf[128];
+ struct str keep;
+ char** line = NULL;
res_T res = RES_OK;
ASSERT(argv && args);
+ str_init(allocator, &keep);
opterr = 0; /* No default error messages */
while((opt = getopt(argc, argv, option_list)) != -1) {
switch (opt) {
@@ -744,12 +756,10 @@ parse_args
goto error;
}
args->mode |= MODE_PROBE_COMPUTE;
- GET_POS_AND_OPTIONAL_TIME_RANGE(args->pos_and_time);
+ GET_POS_AND_OPTIONAL_TIME_RANGE(optarg, args->pos_and_time, optarg);
break;
case 'P':
- {
- static const char toto[] = "toto";
if(args->mode & EXCLUSIVE_MODES) {
res = RES_BAD_ARG;
logger_print(args->logger, LOG_ERROR,
@@ -758,10 +768,33 @@ parse_args
goto error;
}
args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE;
- GET_POS_AND_OPTIONAL_TIME_RANGE_AND_OPTIONAL_MEDIUM(args->pos_and_time);
- args->medium_name = toto;
+
+ ERR(str_set(&keep, optarg));
+ line = split_line(optarg, ':');
+ if(!line) {
+ res = RES_MEM_ERR;
+ str_release(&keep);
+ goto error;
+ }
+
+ /* We expect 1 or 2 parts in line */
+ if(!line[0] || (line[1] && line[2])) {
+ logger_print((args->logger), LOG_ERROR,
+ "Invalid argument for option ""-%c"": %s\n",
+ opt, str_cget(&keep));
+ str_release(&keep);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* First part is pos and optional time, optional second part is a
+ * medium name (OK if NULL) */
+ GET_POS_AND_OPTIONAL_TIME_RANGE(line[0], args->pos_and_time,
+ str_cget(&keep));
+ args->medium_name = optarg + strlen(line[0]) + 1;
+
break;
- }
+
case 'r':
res = cstr_to_double(optarg, &args->ref_temp);
if(res != RES_OK
@@ -940,12 +973,15 @@ parse_args
}
end:
+ FREE_AARRAY(line);
+ str_release(&keep);
return res;
error:
logger_print(args->logger, LOG_ERROR, "Use option -h to print help.\n");
goto end;
}
+
res_T
parse_camera
(struct logger* logger,
@@ -979,7 +1015,8 @@ parse_camera
goto error;
}
if(strcasecmp(opt[0], "T") == 0) {
- GET_OPTIONAL_TIME_RANGE(opt[1], 0, cam->time_range, logger, "%s", opt[0]);
+ GET_OPTIONAL_TIME_RANGE(opt[1], 0, cam->time_range, logger, "%s", opt[0],
+ str_cget(&keep));
}
else if(strcasecmp(opt[0], "FILE") == 0) {
ERR(str_set(&cam->file_name, opt[1]));
@@ -1026,23 +1063,12 @@ parse_camera
res = RES_BAD_ARG;
goto error;
}
-
-#define FREE_AARRAY(ARRAY) \
-if(ARRAY) {\
- int i__ = 0; \
- for(i__=0; *((ARRAY)+i__);i__++){\
- free((ARRAY)[i__]);\
- }\
- free(ARRAY);\
- (ARRAY) = NULL;\
-}
-
- FREE_AARRAY(opt)
+ FREE_AARRAY(opt);
}
end:
- FREE_AARRAY(line)
- FREE_AARRAY(opt)
+ FREE_AARRAY(line);
+ FREE_AARRAY(opt);
#undef FREE_AARRAY
str_release(&keep);
@@ -1484,10 +1510,16 @@ process_ssc
if(res != RES_OK
|| desc->d.ss_connect.tcr < 0)
{
- logger_print(stardis->logger, LOG_ERROR, "Invalid contact resistance: %s\n", tk);
+ logger_print(stardis->logger, LOG_ERROR,
+ "Invalid contact resistance: %s\n", tk);
if(res == RES_OK) res = RES_BAD_ARG;
goto end;
}
+ else if(desc->d.ss_connect.tcr == 0) {
+ logger_print(stardis->logger, LOG_WARNING,
+ "Solid-solid connection %s: defining a contact resistance to 0 has "
+ "no effect\n", str_cget(&desc->d.ss_connect.name));
+ }
ASSERT(sz <= UINT_MAX);
ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx));
diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h
@@ -175,7 +175,8 @@ extern res_T
parse_args
(const int argc,
char** argv,
- struct args* args);
+ struct args* args,
+ struct mem_allocator* allocator);
extern res_T
parse_camera