commit 277f8240fbe4849ba98646d5ca56c097554d5698
parent 143456ff49b2448b19af52e4c26c0f2c7f54f47c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 10 Mar 2021 16:51:49 +0100
Merge branch 'feature_thermal_contact_resistance' into develop
Diffstat:
10 files changed, 413 insertions(+), 50 deletions(-)
diff --git a/doc/stardis-input.5.txt b/doc/stardis-input.5.txt
@@ -99,6 +99,7 @@ _______
| <f-bound-for-solid>
<media-connection> ::= <solid-fluid-connect>
+ | <solid-solid-connect>
<comment> ::= "#" Any text introduced by the # character
@@ -132,9 +133,13 @@ _______
<solid-fluid-connect> ::= "SOLID_FLUID_CONNECTION" <bound-name> <emissivity> \
<specular-fraction> <hc> <triangles>
+<solid-solid-connect> ::= "SOLID_SOLID_CONNECTION" <bound-name> \
+ <contact-resistance> <triangles>
+
-------------------------------------
-<medium-name> ::= STRING # no space allowed
+<medium-name> ::= STRING # no space allowed, must not be parsable as a
+ # number, including INF and others
<lambda> ::= REAL # conductivity in W/(m.K); in ]0, INF)
@@ -167,6 +172,8 @@ _______
<hc> ::= REAL # in W/(m2.K); in [0, INF)
+<contact-resistance> ::= REAL # in m2.K/W in [0, INF)
+
<flux> ::= REAL # in W/m2; in (-INF , INF)
<triangles> ::= <file-name> [ <triangles> ]
diff --git a/doc/stardis.1.txt.in b/doc/stardis.1.txt.in
@@ -95,11 +95,14 @@ EXCLUSIVE OPTIONS
be in a medium. The probe coordinates must be in the same system as the
geometry.
-*-P* _x,y,z[,time[,time]]_::
+*-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 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 start. The probe coordinates
+ the closest interface before the computation starts. The probe coordinates
must be in the same system as the geometry.
*-m* _medium_name[,time[,time]]_::
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -261,6 +261,9 @@ stardis_init
else if(args->mode & MODE_MEDIUM_COMPUTE) {
ERR(str_set(&stardis->solve_name, args->medium_name));
}
+ else if(args->mode & MODE_PROBE_COMPUTE_ON_INTERFACE && args->medium_name) {
+ ERR(str_set(&stardis->solve_name, args->medium_name));
+ }
else if(args->mode & SURFACE_COMPUTE_MODES) {
ERR(str_set(&stardis->solve_name, args->solve_filename));
}
@@ -375,9 +378,6 @@ stardis_init
struct sdis_scene_create_args scn_args = SDIS_SCENE_CREATE_ARGS_DEFAULT;
ASSERT(darray_interface_ptrs_size_get(&stardis->geometry.interf_bytrg)
== tcount);
- /* Can release enclosures as they are no longer needed if compute */
- SENC3D(scene_ref_put(stardis->senc3d_scn));
- stardis->senc3d_scn = NULL;
scn_args.get_indices = sg3d_sdisXd_geometry_get_indices;
scn_args.get_interface = sg3d_sdisXd_geometry_get_interface;
scn_args.get_position = sg3d_sdisXd_geometry_get_position;
@@ -576,6 +576,13 @@ validate_properties
goto end;
}
break;
+ case DESC_SOLID_SOLID_CONNECT:
+ if(solid_count != 2) {
+ /*if(soli_count == 1 && fluid_count == 1)*/
+ /**properties_conflict_status = SSCONNECT_BETWEEN_SOLID_AND_FLUID;*/
+ goto end;
+ }
+ break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -106,6 +106,7 @@ enum description_type {
DESC_BOUND_T_FOR_SOLID,
DESC_BOUND_F_FOR_SOLID,
DESC_SOLID_FLUID_CONNECT,
+ DESC_SOLID_SOLID_CONNECT,
DESCRIPTION_TYPE_COUNT__,
DESC_OUTSIDE
};
@@ -415,6 +416,58 @@ cp_release_sf_connect
return cp_sf_connect(dst, src);
}
+struct solid_solid_connect {
+ struct str name;
+ double tcr;
+ unsigned connection_id;
+};
+
+static FINLINE void
+release_ss_connect(struct solid_solid_connect* connect)
+{
+ str_release(&connect->name);
+}
+
+static FINLINE void
+init_ss(struct mem_allocator* allocator, struct solid_solid_connect* dst)
+{
+ str_init(allocator, &dst->name);
+ dst->tcr = 0;
+ dst->connection_id = UINT_MAX;
+}
+
+static res_T
+str_print_ss_connect
+ (struct str* str,
+ const struct solid_solid_connect* c)
+{
+ res_T res = RES_OK;
+ ASSERT(str && c);
+ STR_APPEND_PRINTF(str, "Solid-Solid connection '%s':", ARG1( str_cget(&c->name) ) );
+ STR_APPEND_PRINTF(str, " contact resistance=%g", ARG1( c->tcr ) );
+end:
+ return res;
+error:
+ goto end;
+}
+
+static FINLINE res_T
+cp_ss_connect
+ (struct solid_solid_connect* dst, const struct solid_solid_connect* src)
+{
+ dst->connection_id = src->connection_id;
+ dst->tcr = src->tcr;
+ return str_copy(&dst->name, &src->name);
+}
+
+static FINLINE res_T
+cp_release_ss_connect
+ (struct solid_solid_connect* dst, struct solid_solid_connect* src)
+{
+ return cp_ss_connect(dst, src);
+}
+
+
struct description {
enum description_type type;
union {
@@ -424,6 +477,7 @@ struct description {
struct f_boundary f_boundary;
struct h_boundary h_boundary;
struct solid_fluid_connect sf_connect;
+ struct solid_solid_connect ss_connect;
} d;
};
@@ -460,6 +514,9 @@ release_description(struct description* desc)
case DESC_SOLID_FLUID_CONNECT:
release_sf_connect(&desc->d.sf_connect);
break;
+ case DESC_SOLID_SOLID_CONNECT:
+ release_ss_connect(&desc->d.ss_connect);
+ break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
@@ -496,6 +553,9 @@ str_print_description
case DESC_SOLID_FLUID_CONNECT:
ERR(str_print_sf_connect(str, &desc->d.sf_connect));
break;
+ case DESC_SOLID_SOLID_CONNECT:
+ ERR(str_print_ss_connect(str, &desc->d.ss_connect));
+ break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
@@ -525,6 +585,8 @@ get_description_name
return &desc->d.f_boundary.name;
case DESC_SOLID_FLUID_CONNECT:
return &desc->d.sf_connect.name;
+ case DESC_SOLID_SOLID_CONNECT:
+ return &desc->d.ss_connect.name;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
@@ -582,7 +644,14 @@ cp_description
}
ERR(cp_sf_connect(&dst->d.sf_connect, &src->d.sf_connect));
break;
- default:
+ case DESC_SOLID_SOLID_CONNECT:
+ if(dst->type == DESCRIPTION_TYPE_COUNT__) {
+ dst->type = src->type;
+ init_ss(src->d.ss_connect.name.allocator, &dst->d.ss_connect);
+ }
+ ERR(cp_ss_connect(&dst->d.ss_connect, &src->d.ss_connect));
+ break;
+ default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
end:
@@ -616,6 +685,7 @@ description_get_medium_id
*id = desc->d.f_boundary.mat_id;
return;
case DESC_SOLID_FLUID_CONNECT: /* No medium linked to SF */
+ case DESC_SOLID_SOLID_CONNECT: /* No medium linked to SS */
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
@@ -699,10 +769,10 @@ log_prt_fn(const char* msg, void* ctx)
struct counts {
unsigned smed_count, fmed_count, tbound_count, hbound_count,
- fbound_count, sfconnect_count;
+ fbound_count, sfconnect_count, ssconnect_count;
};
#define COUNTS_NULL__ {\
- 0, 0, 0, 0, 0, 0\
+ 0, 0, 0, 0, 0, 0, 0\
}
/* Type to store the primitives of a compute region */
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,11 +464,155 @@ 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);
+ 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=%u)\n",
+ solve_name, iprim);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(fmat_id == bmat_id) { /* Cannot differentiate */
+ unsigned encs[2];
+ ERR(senc3d_scene_get_triangle_enclosures(stardis->senc3d_scn, iprim,
+ encs));
+ logger_print(stardis->logger, LOG_ERROR,
+ "Medium '%s' is used on both sides of this interface (prim id=%u)\n",
+ solve_name,iprim);
+ logger_print(stardis->logger, LOG_ERROR,
+ "Side must be defined using either FRONT or BACK.\n");
+ logger_print(stardis->logger, LOG_ERROR,
+ "FRONT side is related to enclosure %u, BACK side to enclosure %u.\n",
+ encs[SENC3D_FRONT], encs[SENC3D_BACK]);
+ 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;
args.iprim = iprim;
d3_set(args.uv, uv);
diff --git a/src/stardis-intface.c b/src/stardis-intface.c
@@ -75,6 +75,17 @@ interface_get_alpha
return interface_props->alpha;
}
+static double
+interface_get_tcr
+ (const struct sdis_interface_fragment* frag,
+ struct sdis_data* data)
+{
+ const struct intface* interface_props = sdis_data_cget(data);
+ (void)frag;
+ return interface_props->tcr;
+}
+
+
/*******************************************************************************
* Public Functions
******************************************************************************/
@@ -94,7 +105,8 @@ create_intface
struct sdis_data* data = NULL;
unsigned fd, bd, cd, descr[SG3D_PROP_TYPES_COUNT__];
int fluid_count = 0, solid_count = 0;
- int solid_fluid_connection_count = 0, connection_count = 0, boundary_count = 0;
+ int solid_fluid_connection_count = 0, solid_solid_connection_count = 0;
+ int connection_count = 0, boundary_count = 0;
const struct description* descriptions;
struct sdis_medium** media;
res_T res = RES_OK;
@@ -185,7 +197,8 @@ create_intface
struct sdis_medium* def_medium = NULL;
unsigned ext_id;
if(connect->type != DESC_SOLID_FLUID_CONNECT
- && front_defined == back_defined)
+ && connect->type != DESC_SOLID_SOLID_CONNECT
+ && front_defined == back_defined)
{
/* 1 and only 1 defined */
res = RES_BAD_ARG;
@@ -335,6 +348,20 @@ create_intface
fluid_side_shader->specular_fraction = interface_get_alpha;
}
break;
+ case DESC_SOLID_SOLID_CONNECT:
+ /* Both front and back should be defined */
+ if(solid_count != 2 || fluid_count != 0) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ASSERT(front_defined && back_defined);
+ connection_count++;
+ solid_solid_connection_count++;
+ interface_props->tcr = connect->d.ss_connect.tcr;
+ if(connect->d.ss_connect.tcr > 0) {
+ interface_shader.thermal_contact_resistance = interface_get_tcr;
+ }
+ break;
default:
FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n");
}
diff --git a/src/stardis-intface.h b/src/stardis-intface.h
@@ -27,9 +27,12 @@ struct dummies;
* Interface data
******************************************************************************/
struct intface {
+ /* fluid - solid */
double hc;
double emissivity;
double alpha;
+ /* solid - solid */
+ double tcr;
/* Imposed compute temperature & flux */
double imposed_temperature;
double imposed_flux;
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,20 +756,44 @@ 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':
- if(args->mode & EXCLUSIVE_MODES) {
- res = RES_BAD_ARG;
- logger_print(args->logger, LOG_ERROR,
- "Options -%c and -%c are exclusive.\n",
- (char)opt, mode_option(args->mode));
- goto error;
- }
- args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE;
- GET_POS_AND_OPTIONAL_TIME_RANGE(args->pos_and_time);
- break;
+ if(args->mode & EXCLUSIVE_MODES) {
+ res = RES_BAD_ARG;
+ logger_print(args->logger, LOG_ERROR,
+ "Options -%c and -%c are exclusive.\n",
+ (char)opt, mode_option(args->mode));
+ goto error;
+ }
+ args->mode |= MODE_PROBE_COMPUTE_ON_INTERFACE;
+
+ 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);
@@ -937,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,
@@ -976,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]));
@@ -1023,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);
@@ -1439,6 +1468,68 @@ error:
goto end;
}
+/* SOLID_SOLID_CONNECTION Name contact-resitance STL_filenames */
+static res_T
+process_ssc
+ (struct stardis* stardis,
+ char** tok_ctx)
+{
+ char* tk = NULL;
+ struct description* desc;
+ size_t sz;
+ res_T res = RES_OK;
+
+ ASSERT(stardis && tok_ctx);
+
+ stardis->counts.ssconnect_count++;
+
+ sz = darray_descriptions_size_get(&stardis->descriptions);
+ ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1));
+ desc = darray_descriptions_data_get(&stardis->descriptions) + sz;
+ init_ss(stardis->allocator, &desc->d.ss_connect);
+
+ /* Use a medium ID even if there is no medium here
+ * As other cases use media IDs as unique IDs for read_sides_and_files calls
+ * we continue the trend to ensure connection ID is OK */
+ desc->type = DESC_SOLID_SOLID_CONNECT;
+ desc->d.ss_connect.connection_id = allocate_stardis_medium_id(stardis);
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid solid connection name");
+ ERR(description_set_name(stardis, &desc->d.ss_connect.name, tk));
+ if(find_description_by_name(stardis, &desc->d.ss_connect.name, NULL)
+ != desc)
+ {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Name already used: %s\n", tk);
+ if(res == RES_OK) res = RES_BAD_ARG;
+ goto end;
+ }
+
+ CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "contact resistance");
+ res = cstr_to_double(tk, &desc->d.ss_connect.tcr);
+ if(res != RES_OK
+ || desc->d.ss_connect.tcr < 0)
+ {
+ 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));
+
+end:
+ return res;
+error:
+ goto end;
+}
+
static res_T
read_imposed_temperature
(struct stardis* stardis,
@@ -1787,6 +1878,8 @@ process_model_line
ERR(process_flx(stardis, dummies, &tok_ctx));
else if(0 == strcasecmp(tk, "SOLID_FLUID_CONNECTION"))
ERR(process_sfc(stardis, &tok_ctx));
+ else if(0 == strcasecmp(tk, "SOLID_SOLID_CONNECTION"))
+ ERR(process_ssc(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "SOLID"))
ERR(process_solid(stardis, &tok_ctx));
else if(0 == strcasecmp(tk, "FLUID"))
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