commit bd17c0e6867e6a84c0f3f40063d2d3bb52bf3a1c
parent 124f1ba33703524a312711f844859e4f012ac394
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 18 Jul 2019 10:25:29 +0200
Major refactoring: split huge files and functions
Diffstat:
| M | cmake/CMakeLists.txt | | | 12 | +++++++++++- |
| D | src/args.h | | | 373 | ------------------------------------------------------------------------------- |
| M | src/main.c | | | 24 | +++++++++++------------- |
| M | src/stardis-app.c | | | 603 | ++++++++----------------------------------------------------------------------- |
| M | src/stardis-app.h | | | 283 | +------------------------------------------------------------------------------ |
| M | src/stardis-compute.c | | | 2205 | ++++++++++++++++++------------------------------------------------------------- |
6 files changed, 572 insertions(+), 2928 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -57,11 +57,21 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SDIS_FILES_SRC
stardis-app.c
stardis-compute.c
+ stardis-fluid.c
+ stardis-intface.c
+ stardis-output.c
+ stardis-parsing.c
+ stardis-solid.c
main.c)
set(SDIS_FILES_INC
stardis-app.h
- args.h)
+ stardis-compute.h
+ stardis-fluid.h
+ stardis-intface.h
+ stardis-output.h
+ stardis-parsing.h
+ stardis-solid.h)
set(SDIS_FILES_DOC COPYING README.md)
diff --git a/src/args.h b/src/args.h
@@ -1,373 +0,0 @@
-/* Copyright (C) 2018 |Meso|Star> (contact@meso-star.com)*/
-
-#ifndef ARGS_H
-#define ARGS_H
-
-#include <getopt.h>
-#include <stdlib.h>
-
-#include <rsys/rsys.h>
-#include <rsys/cstr.h>
-#include <sdis_version.h>
-
-enum stardis_mode {
- UNDEF_MODE = 0,
- PROBE_COMPUTE = BIT(0),
- MEDIUM_COMPUTE = BIT(1),
- BOUNDARY_COMPUTE = BIT(2),
- GREEN_MODE = BIT(3),
- IR_COMPUTE = BIT(4),
- DUMP_VTK = BIT(5),
- PROBE_COMPUTE_ON_INTERFACE = BIT(6),
- COMPUTE_MODES = PROBE_COMPUTE | MEDIUM_COMPUTE | BOUNDARY_COMPUTE | IR_COMPUTE | DUMP_VTK | PROBE_COMPUTE_ON_INTERFACE
-};
-
-static char mode_option(const enum stardis_mode m) {
- int found = 0;
- char res = '?';
- if (m & PROBE_COMPUTE) { found++; res = 'p'; }
- if (m & MEDIUM_COMPUTE) { found++; res = 'm'; }
- if (m & BOUNDARY_COMPUTE) { found++; res = 'b'; }
- if (m & IR_COMPUTE) { found++; res = 'R'; }
- if (m & DUMP_VTK) { found++; res = 'd'; }
- if (m & PROBE_COMPUTE_ON_INTERFACE) { found++; res = 'P'; }
- ASSERT(found == 1);
- return res;
-}
-
-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;
- char* medium_name;
- char* solve_boundary_filename;
- size_t N;
- unsigned nthreads;
- union u { /* Trick to allow static initialization with INF */
- struct pt { double p[3]; uint64_t t; } pt;
- double probe[4];
- } u;
- enum stardis_mode mode;
- 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
-#else
-#define DEFAULT_NTHREADS 1
-#endif
-#define ARGS_DEFAULT__ {\
- NULL, NULL, NULL, NULL, 10000, DEFAULT_NTHREADS,\
- { { {0.0, 0.0, 0.0}, 0x7FF0000000000000 /* probe[3]=INF */}},\
- UNDEF_MODE, 1.0, {300.0, 300.0}, NULL, DUMP_NONE, 0}
-static const struct args ARGS_DEFAULT = ARGS_DEFAULT__;
-
-static void
-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\n", prog);
- printf("[ -p X,Y,Z,TIME | -m MEDIUM_NAME,TIME | -d | -b SURFACE.vtk,TIME\n");
- printf(" | -R t=TIME:spp=SPP:fov=FOV:up=XUP,YUP,ZUP:pos=X,Y,Z:tgt=XT,YT,ZT:img=WxH ]\n");
- printf("[ -g] [-s SCALE_FACTOR] [-D {all | error | success}] -d\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("\nMandatory arguments\n");
- printf("---------\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(" BOUNDARY.txt is a text file which contains the description of the\n");
- printf(" boundary conditions.\n");
- printf("\nExclusive arguments\n");
- printf("-------------------\n");
- printf("\n -p X:Y:Z:TIME:\n");
- printf(" Compute the temperature at the given probe.\n");
- printf(" The probe must be in a medium.\n");
- printf(" If some boundary conditions are time-dependant, TIME cannot be INF.\n");
- printf("\n -P X:Y:Z:TIME:\n");
- printf(" Compute the temperature at the given probe on an interface.\n");
- printf(" The probe must be in a medium and is moved to the closest interface.\n");
- printf(" If some boundary conditions are time-dependant, TIME cannot be INF.\n");
- printf("\n -m MEDIUM_NAME,TIME:\n");
- printf(" Compute the mean temperature in a given medium at a given time.\n");
- printf(" If some boundary conditions are time-dependant, TIME cannot be INF.\n");
- printf("\n -d:\n");
- printf(" Dump the geometry in VTK format with medium front/back id and\n");
- printf(" boundary id.\n");
- printf("\n -b SURFACE.vtk,TIME:\n");
- printf(" Compute the mean temperature on a given 2D shape at a given time.\n");
- printf(" Mean temperature is computed on the front sides of the primitives\n");
- printf(" listed in SURFACE.vtk. These primitives are not added to the geometry,\n");
- printf(" but must be already known. The shape doesn't need to be connex.\n");
- printf(" If some boundary conditions are time-dependant, TIME cannot be INF.\n");
- printf("\n -R t=TIME:spp=SPP:fov=FOV:up=XUP,YUP,ZUP:pos=X,Y,Z:tgt=XT,YT,ZT:img=WxH:\n");
- printf(" The infra-red rendering mode.\n");
- printf(" t is the rendering time (default: INF).\n");
- printf(" spp is the number of samples per pixel (default: 4).\n");
- printf(" fov is the field of view (default: 70 degrees).\n");
- printf(" up is the up direction (default: 0,0,1).\n");
- printf(" pos is the position of camera (default: 1,1,1).\n");
- printf(" tgt is the target (default: 0,0,0).\n");
- printf(" img is the resolution (default: 640x480).\n");
- printf("\nOptionnal arguments\n");
- printf("-------------------\n");
- printf("\n -g:\n");
- printf(" Compute the green function.\n");
- printf(" Must be used in conjonction with one the -p, -m or -b options.\n");
- printf(" Provided TIME is silently ignored.\n");
- printf("\n -s SCALE_FACTOR:\n");
- printf(" default value: 1.0.\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");
- printf("\n -t NUM_OF_THREADS:\n");
- printf(" Number of threads; default value is all threads available.\n");
- printf("\n -r AMBIENT_RAD_TEMP,REFERENCE_TEMP:\n");
- printf(" Parameters for the radiative transfer.\n");
- printf(" AMBIENT_RAD_TEMP is the ambient radiative temperature .\n");
- printf(" REFERENCE_TEMP is the temperature used for the linearization\n");
- printf(" of the radiative transfer.\n");
-}
-
-
-static INLINE res_T
-parse_args(const int argc, char** argv, struct args* args)
-{
- int opt = 0;
- size_t len = 0;
- res_T res = RES_OK;
-
- if (argc == 1) {
- print_help(argv[0]);
- res = RES_BAD_ARG;
- goto error;
- }
-
- opterr = 0; /* No default error messages */
- while((opt = getopt(argc, argv, "hgn:t:b:B:M:m:p:P:dD:s:r:R:")) != -1) {
- switch(opt) {
- case '?': /* Unreconised option */
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid option -%c\n", optopt);
- goto error;
-
- case 'h':
- print_help(argv[0]);
- args->just_help = 1;
- goto exit;
-
- case 'g':
- args->mode |= GREEN_MODE;
- break;
-
- case 'n': {
- unsigned long n;
- res = cstr_to_ulong(optarg, &n);
- if (res != RES_OK || n == 0) {
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid argument -%c %s\n", opt, optarg);
- goto error;
- }
- args->N = n;
- break;
- }
-
- case 'B':
- args->bc_filename = optarg;
- break;
-
- case 'M':
- args->medium_filename = optarg;
- break;
-
- case 't':
- res = cstr_to_uint(optarg, &args->nthreads);
- if (res != RES_OK
- || args->nthreads <= 0){
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid argument -%c %s\n", opt, optarg);
- goto error;
- }
- break;
-
- case 'p':
- if (args->mode & COMPUTE_MODES) {
- 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
- || args->u.probe[3] < 0)
- {
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid argument -%c %s\n", opt, optarg);
- goto error;
- }
- break;
-
- case 'P':
- if (args->mode & COMPUTE_MODES) {
- 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_ON_INTERFACE;
- cstr_to_list_double(optarg, ',', args->u.probe, &len, 4);
- if(len != 4
- || res != RES_OK
- || args->u.probe[3] < 0)
- {
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid argument -%c %s\n", opt, optarg);
- goto error;
- }
- break;
-
- case 'b': {
- int err = 0;
- char *ptr;
- if (args->mode & COMPUTE_MODES) {
- res = RES_BAD_ARG;
- fprintf(stderr, "Cannot specify multiple modes: -%c and -%c\n",
- (char)opt, mode_option(args->mode));
- goto error;
- }
- args->mode |= BOUNDARY_COMPUTE;
- ptr = strrchr(optarg, ',');
- /* Single ',' allowed */
- if (!ptr || ptr != strchr(optarg, ','))
- err = 1;
- else {
- *ptr = '\0';
- ptr++;
- args->solve_boundary_filename = optarg;
- err = (RES_OK != cstr_to_double(ptr, args->u.probe + 3) || args->u.probe[3] < 0);
- }
- if (err) {
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid argument -%c %s\n", opt, optarg);
- goto error;
- }
- break;
- }
-
- case 'm': {
- char* ptr;
- if (args->mode & COMPUTE_MODES) {
- 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;
- 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 -%c %s\n", opt, optarg);
- goto error;
- }
- *ptr = '\0';
- args->medium_name = optarg;
- break;
- }
-
- case 'd':
- if (args->mode & COMPUTE_MODES) {
- 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;
-
- 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 -%c %s\n", opt, optarg);
- goto error;
- }
- break;
-
- case 's':
- cstr_to_double(optarg, &args->scale_factor);
- if (res != RES_OK
- || args->scale_factor <=0){
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid argument -%c %s\n", opt, optarg);
- goto error;
- }
- break;
-
- case 'r':
- cstr_to_list_double(optarg, ',', args->radiative_temp, &len, 2);
- if (res != RES_OK
- || len != 2
- || args->radiative_temp[0] <=0
- || args->radiative_temp[1] <=0){
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid argument -%c %s\n", opt, optarg);
- goto error;
- }
- break;
-
- case 'R':
- if (args->mode & COMPUTE_MODES) {
- 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;
- }
- }
-
-if (!args->medium_filename){
- fprintf(stderr, "Argument required -m\n");
- res = RES_BAD_ARG;
- goto error;
-}
-
-if (!args->bc_filename){
- fprintf(stderr, "Argument required -b\n");
- res = RES_BAD_ARG;
- goto error;
-}
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-#endif /*ARGS_H*/
diff --git a/src/main.c b/src/main.c
@@ -1,12 +1,16 @@
/* Copyright (C) 2018 |Meso|Star> (contact@meso-star.com) */
#include "stardis-app.h"
+#include "stardis-output.h"
+
+#if !defined(ARCH_64BITS)
+#error "Please write the_version of hash functions needed by the current arch"
+#endif
int main(int argc, char** argv){
struct args args = ARGS_DEFAULT;
struct stardis stardis = NULL_STARDIS;
- size_t memsz = 0;
int err = 0;
res_T res = RES_OK;
@@ -25,21 +29,15 @@ int main(int argc, char** argv){
if (res != RES_OK) goto error;
goto exit;
}
-
- res = stardis_compute(&stardis, args.mode);
- if (res != RES_OK) goto error;
+ else if (args.mode & COMPUTE_MODES) {
+ res = stardis_compute(&stardis, args.mode);
+ if (res != RES_OK) goto error;
+ } else {
+ fprintf(stderr, "Unknown mode: %c.\n", mode_option(args.mode));
+ }
exit:
stardis_release(&stardis);
- if(stardis.allocator_initialized
- && (memsz = MEM_ALLOCATED_SIZE(&stardis.allocator)) != 0)
- {
- char dump[4096] = { '\0' };
- MEM_DUMP(&stardis.allocator, dump, sizeof(dump));
- fprintf(stderr, "%s\n", dump);
- fprintf(stderr, "Memory leaks: %lu Bytes\n", (unsigned long)memsz);
- }
- mem_shutdown_proxy_allocator(&stardis.allocator);
CHK(mem_allocated_size() == 0);
return err;
error:
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -1,10 +1,7 @@
/* Copyright (C) 2018 |Meso|Star> (contact@meso-star.com) */
-#define _GNU_SOURCE 1
-#include <string.h>
-#include <ctype.h>
#include "stardis-app.h"
-
+#include "stardis-output.h"
#include <rsys/hash_table.h>
#define HTABLE_NAME descriptions
@@ -14,16 +11,25 @@
#define HTABLE_KEY_FUNCTOR_HASH hash_description
#include <rsys/hash_table.h>
+#define _GNU_SOURCE 1
+#include <string.h>
+#include <ctype.h>
+
/*******************************************************************************
- *
+ * Local Functions
******************************************************************************/
-static INLINE char*
-read_line(char** pb, FILE* stream)
+
+static char*
+read_line
+ (char** pb,
+ FILE* stream)
{
const int chunk_sz = 32;
char* buf = *pb;
size_t idx;
+ ASSERT(pb && stream);
+
if(!buf) buf = sa_add(buf, 128);
do {
@@ -48,444 +54,6 @@ read_line(char** pb, FILE* stream)
return buf;
}
-static char** split_line(char* a_str, const char a_delim)
-{
- char** result = 0;
- size_t count = 0;
- char* tmp = a_str;
- char* last_comma = 0;
- char delim[2];
- delim[0] = a_delim;
- delim[1] = 0;
-
- /* Count how many elements will be extracted. */
- while (*tmp)
- {
- if (a_delim == *tmp)
- {
- count++;
- last_comma = tmp;
- }
- tmp++;
- }
-
- /* Add space for trailing token. */
- count += last_comma < (a_str + strlen(a_str) - 1);
-
- /* Add space for terminating null string so caller
- knows where the list of returned strings ends. */
- count++;
-
- result = malloc(sizeof(char*) * count);
-
- if (result)
- {
- size_t idx = 0;
- char* token = strtok(a_str, delim);
-
- while (token)
- {
- ASSERT(idx < count);
-#ifdef COMPILER_CL
- *(result + idx++) = _strdup(token);
-#else
- *(result + idx++) = strdup(token);
-#endif
- token = strtok(0, delim);
- }
- ASSERT(idx == count - 1);
- *(result + idx) = 0;
- }
-
- return result;
-}
-
-#ifdef COMPILER_GCC
-static char*
-_strupr(char* s)
-{
- char* ptr;
- for (ptr = s; *ptr; ++ptr) {
- int tmp = toupper(*ptr);
- ASSERT(tmp == (char)tmp);
- *ptr = (char)tmp;
- }
- return s;
-}
-#endif
-
-
-/* Read medium line; should be one of:
- * 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)
-{
- char* tk = NULL;
- res_T res = RES_OK;
-
-#define CHK_TOK(x, Name) if ((tk = (x)) == NULL) {\
- fprintf(stderr, "Invalid data (missing token " Name ")\n");\
- res = RES_BAD_ARG;\
- goto exit;\
- } (void)0
- CHK_TOK(_strupr(strtok(line, " ")), "medium type");
- if (strcmp(tk, "SOLID") == 0) {
- desc->type = DESC_MAT_SOLID;
- desc->d.solid = NULL_SOLID;
-
- CHK_TOK(strtok(NULL, " "), "medium name");
- if (strlen(tk) >= sizeof(desc->d.solid.name)) {
- fprintf(stderr, "Medium name is too long: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- strncpy(desc->d.solid.name, tk, sizeof(desc->d.solid.name));
-
- CHK_TOK(strtok(NULL, " "), "file name");
- *stl_filename = malloc(strlen(tk) + 1);
- strcpy(*stl_filename, tk);
-
- CHK_TOK(strtok(NULL, " "), "lambda");
- res = cstr_to_double(tk, &desc->d.solid.lambda);
- if (res != RES_OK || desc->d.solid.lambda <= 0) {
- fprintf(stderr, "Invalid lambda: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- CHK_TOK(strtok(NULL, " "), "rho");
- res = cstr_to_double(tk, &desc->d.solid.rho);
- if (res != RES_OK || desc->d.solid.rho <= 0) {
- fprintf(stderr, "Invalid rho: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- CHK_TOK(strtok(NULL, " "), "cp");
- res = cstr_to_double(tk, &desc->d.solid.cp);
- if (res != RES_OK || desc->d.solid.cp <= 0) {
- fprintf(stderr, "Invalid cp: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- CHK_TOK(strtok(NULL, " "), "delta");
- res = cstr_to_double(tk, &desc->d.solid.delta);
- if (res != RES_OK || desc->d.solid.delta <= 0) {
- fprintf(stderr, "Invalid delta: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- /* Depending of the number of spaces before '"' strtok should
- * be called once or twice */
- CHK_TOK(strtok(NULL, "\""), "Tinit");
- if (*(tk + strspn(tk, " \t")) == '\0') {
- CHK_TOK(strtok(NULL, "\""), "Tinit");
- }
- desc->d.solid.Tinit = malloc(strlen(tk) + 1);
- strcpy(desc->d.solid.Tinit, tk);
- /* Closing " fot Tinit; can return NULL if line ends just after "Tinit" */
- tk = strtok(NULL, "\"");
-
- /* Volumic Power is optional */
- if (tk && *(tk + strspn(tk, " \t")) == '\0') {
- /* Depending of the number of spaces before '"' strtok should
- * be called once or twice */
- tk = strtok(NULL, "\"");
- }
- if (tk) {
- desc->d.solid.power = malloc(strlen(tk) + 1);
- strcpy(desc->d.solid.power, tk);
- /* Can be changed aftwerwards if compiled to constant 0 */
- desc->d.solid.has_power = 1;
- }
- }
- else if (strcmp(tk, "FLUID") == 0) {
- desc->type = DESC_MAT_FLUID;
- desc->d.fluid = NULL_FLUID;
-
- CHK_TOK(strtok(NULL, " "), "medium name");
- if (strlen(tk) >= sizeof(desc->d.fluid.name)) {
- fprintf(stderr, "Medium name is too long: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- strncpy(desc->d.fluid.name, tk, sizeof(desc->d.fluid.name));
-
- CHK_TOK(strtok(NULL, " "), "file name");
- *stl_filename = malloc(strlen(tk) + 1);
- strcpy(*stl_filename, tk);
-
- CHK_TOK(strtok(NULL, " "), "rho");
- res = cstr_to_double(tk, &desc->d.fluid.rho);
- if (res != RES_OK || desc->d.fluid.rho <= 0) {
- fprintf(stderr, "Invalid rho: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- CHK_TOK(strtok(NULL, " "), "cp");
- res = cstr_to_double(tk, &desc->d.fluid.cp);
- if (res != RES_OK || desc->d.fluid.cp <= 0) {
- fprintf(stderr, "Invalid cp: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- /* Depending of the number of spaces before '"' strtok should
- * be called once or twice */
- CHK_TOK(strtok(NULL, "\""), "Tinit");
- if (*(tk + strspn(tk, " \t")) == '\0') {
- CHK_TOK(strtok(NULL, "\""), "Tinit");
- }
- desc->d.fluid.Tinit = malloc(strlen(tk) + 1);
- strcpy(desc->d.fluid.Tinit, tk);
- }
- else {
- res = RES_BAD_ARG;
- fprintf(stderr, "Invalid medium type: %s\n", tk);
- }
-
-#undef CHK_TOK
-exit:
- return res;
-}
-
-/* Read boundary line; should be one of:
-# H_BOUNDARY_FOR_SOLID Boundary_name STL_filename emissivity specular_fraction hc hc_max "T_env(x,y,z,t)"
-# | H_BOUNDARY_FOR_FLUID Boundary_name STL_filename emissivity specular_fraction hc hc_max "T_env(x,y,z,t)"
-# | T_BOUNDARY_FOR_SOLID Boundary_name STL_filename "T_value(x,y,z,t)"
-# | T_BOUNDARY_FOR_FLUID Boundary_name STL_filename "T_value(x,y,z,t)" hc hc_max
-# | F_BOUNDARY_FOR_SOLID Boundary_name STL_filename "F_value(x,y,z,t)"
-# ; no F_BOUNDARY_FOR_FLUID
-# | SOLID_FLUID_CONNECTION Connection_name STL_filename emissivity specular_fraction hc hc_max
- */
-static res_T
-parse_boundary_line(char* line, char** stl_filename, struct description* desc)
-{
- char* tk = NULL;
- int h_solid = 0, h_fluid = 0;
- int t_solid = 0, t_fluid = 0;
- int f_solid = 0;
- int sf_connect = 0;
- res_T res = RES_OK;
-
-#define CHK_TOK(x, Name) if ((tk = (x)) == NULL) {\
- fprintf(stderr, "Invalid data (missing token " Name ")\n");\
- res = RES_BAD_ARG;\
- goto exit;\
- } (void)0
- CHK_TOK(strtok(line, " "), "boundary type");
- h_solid = (0 == strcmp(tk, "H_BOUNDARY_FOR_SOLID"));
- if (!h_solid) {
- h_fluid = (0 == strcmp(tk, "H_BOUNDARY_FOR_FLUID"));
- if (!h_fluid) {
- t_solid = (0 == strcmp(tk, "T_BOUNDARY_FOR_SOLID"));
- if (!t_solid) {
- t_fluid = (0 == strcmp(tk, "T_BOUNDARY_FOR_FLUID"));
- if (!t_fluid) {
- f_solid = (0 == strcmp(tk, "F_BOUNDARY_FOR_SOLID"));
- if (!f_solid) {
- sf_connect = (0 == strcmp(tk, "SOLID_FLUID_CONNECTION"));
- }
- }
- }
- }
- }
-
- if (h_solid || h_fluid) {
- desc->type = h_solid ? DESC_BOUND_H_FOR_SOLID : DESC_BOUND_H_FOR_FLUID;
- desc->d.h_boundary = NULL_HBOUND;
-
- CHK_TOK(strtok(NULL, " "), "boundary name");
- if (strlen(tk) >= sizeof(desc->d.h_boundary.name)) {
- fprintf(stderr, "Boundary name is too long: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- strncpy(desc->d.h_boundary.name, tk, sizeof(desc->d.h_boundary.name));
-
- /* The description is parsed the same way for both types */
- CHK_TOK(strtok(NULL, " "), "file name");
- *stl_filename = malloc(strlen(tk) + 1);
- strcpy(*stl_filename, tk);
-
- CHK_TOK(strtok(NULL, " "), "emissivity");
- res = cstr_to_double(tk, &desc->d.h_boundary.emissivity);
- if (res != RES_OK ||
- desc->d.h_boundary.emissivity < 0 || desc->d.h_boundary.emissivity > 1) {
- fprintf(stderr, "Invalid emissivity: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- desc->d.h_boundary.has_emissivity = (desc->d.h_boundary.emissivity > 0);
- CHK_TOK(strtok(NULL, " "), "specular fraction");
- res = cstr_to_double(tk, &desc->d.h_boundary.specular_fraction);
- if (res != RES_OK
- || desc->d.h_boundary.specular_fraction < 0.0
- || desc->d.h_boundary.specular_fraction > 1.0) {
- fprintf(stderr, "Invalid specular_fraction: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- CHK_TOK(strtok(NULL, " "), "hc");
- res = cstr_to_double(tk, &desc->d.h_boundary.hc);
- if (res != RES_OK || desc->d.h_boundary.hc < 0) {
- fprintf(stderr, "Invalid hc value: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- desc->d.h_boundary.has_hc = (desc->d.h_boundary.hc > 0);
- CHK_TOK(strtok(NULL, " "), "hc max");
- res = cstr_to_double(tk, &desc->d.h_boundary.hc_max);
- if (res != RES_OK
- || desc->d.h_boundary.hc_max < desc->d.h_boundary.hc
- || desc->d.h_boundary.hc_max < 0) {
- fprintf(stderr, "Invalid hc_max value: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- /* Depending of the number of spaces before '"' strtok should
- * be called once or twice */
- CHK_TOK(strtok(NULL, "\""), "temperature");
- if (*(tk + strspn(tk, " \t")) == '\0') {
- CHK_TOK(strtok(NULL, "\""), "temperature");
- }
- desc->d.h_boundary.T = malloc(strlen(tk) + 1);
- strcpy(desc->d.h_boundary.T, tk);
- }
- else if (t_solid || t_fluid) {
- desc->type = t_solid ? DESC_BOUND_T_FOR_SOLID : DESC_BOUND_T_FOR_FLUID;
- desc->d.t_boundary = NULL_TBOUND;
-
- CHK_TOK(strtok(NULL, " "), "boundary name");
- if (strlen(tk) >= sizeof(desc->d.t_boundary.name)) {
- fprintf(stderr, "Boundary name is too long: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- strncpy(desc->d.t_boundary.name, tk, sizeof(desc->d.t_boundary.name));
-
- /* This part of the description is parsed the same way for both types */
- CHK_TOK(strtok(NULL, " "), "file name");
- *stl_filename = malloc(strlen(tk) + 1);
- strcpy(*stl_filename, tk);
-
- /* Depending of the number of spaces before '"' strtok should
- * be called once or twice */
- CHK_TOK(strtok(NULL, "\""), "temperature");
- if (*(tk + strspn(tk, " \t")) == '\0') {
- CHK_TOK(strtok(NULL, "\""), "temperature");
- }
- desc->d.t_boundary.T = malloc(strlen(tk) + 1);
- strcpy(desc->d.t_boundary.T, tk);
-
- /* Parse hc + hc_max only if fluid */
- if (t_fluid) {
- CHK_TOK(strtok(NULL, " "), "hc");
- res = cstr_to_double(tk, &desc->d.t_boundary.hc);
- if (res != RES_OK || desc->d.t_boundary.hc < 0) {
- fprintf(stderr, "Invalid hc value: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- desc->d.t_boundary.has_hc = (desc->d.t_boundary.hc > 0);
- CHK_TOK(strtok(NULL, " "), "hc max");
- res = cstr_to_double(tk, &desc->d.t_boundary.hc_max);
- if (res != RES_OK
- || desc->d.t_boundary.hc_max < desc->d.t_boundary.hc
- || desc->d.t_boundary.hc_max < 0) {
- fprintf(stderr, "Invalid hc_max value: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- }
- else desc->d.t_boundary.has_hc = 0;
- }
- else if (f_solid) {
- desc->type = DESC_BOUND_F_FOR_SOLID;
- desc->d.f_boundary = NULL_FBOUND;
-
- CHK_TOK(strtok(NULL, " "), "boundary name");
- if (strlen(tk) >= sizeof(desc->d.f_boundary.name)) {
- fprintf(stderr, "Boundary name is too long: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- strncpy(desc->d.f_boundary.name, tk, sizeof(desc->d.f_boundary.name));
-
- CHK_TOK(strtok(NULL, " "), "file name");
- *stl_filename = malloc(strlen(tk) + 1);
- strcpy(*stl_filename, tk);
-
- /* Depending of the number of spaces before '"' strtok should
- * be called once or twice */
- CHK_TOK(strtok(NULL, "\""), "flux");
- if (*(tk + strspn(tk, " \t")) == '\0') {
- CHK_TOK(strtok(NULL, "\""), "flux");
- }
- desc->d.f_boundary.flux = malloc(strlen(tk) + 1);
- strcpy(desc->d.f_boundary.flux, tk);
- }
- else if (sf_connect) {
- desc->type = DESC_SOLID_FLUID_CONNECT;
- desc->d.sf_connect = NULL_SFCONNECT;
-
- CHK_TOK(strtok(NULL, " "), "boundary name");
- if (strlen(tk) >= sizeof(desc->d.sf_connect.name)) {
- fprintf(stderr, "Boundary name is too long: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- strncpy(desc->d.sf_connect.name, tk, sizeof(desc->d.sf_connect.name));
-
- CHK_TOK(strtok(NULL, " "), "file name");
- *stl_filename = malloc(strlen(tk) + 1);
- strcpy(*stl_filename, tk);
-
- CHK_TOK(strtok(NULL, " "), "emissivity");
- res = cstr_to_double(tk, &desc->d.sf_connect.emissivity);
- if (res != RES_OK ||
- desc->d.sf_connect.emissivity < 0 || desc->d.sf_connect.emissivity > 1) {
- fprintf(stderr, "Invalid emissivity: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- desc->d.sf_connect.has_emissivity = (desc->d.sf_connect.emissivity > 0);
- CHK_TOK(strtok(NULL, " "), "specular fraction");
- res = cstr_to_double(tk, &desc->d.sf_connect.specular_fraction);
- if (res != RES_OK
- || desc->d.sf_connect.specular_fraction < 0.0
- || desc->d.sf_connect.specular_fraction > 1.0) {
- fprintf(stderr, "Invalid specular_fraction: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- CHK_TOK(strtok(NULL, " "), "hc");
- res = cstr_to_double(tk, &desc->d.sf_connect.hc);
- if (res != RES_OK || desc->d.sf_connect.hc < 0) {
- fprintf(stderr, "Invalid hc value: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- desc->d.sf_connect.has_hc = (desc->d.sf_connect.hc > 0);
- CHK_TOK(strtok(NULL, " "), "hc max");
- res = cstr_to_double(tk, &desc->d.h_boundary.hc_max);
- if (res != RES_OK
- || desc->d.h_boundary.hc_max < desc->d.h_boundary.hc
- || desc->d.h_boundary.hc_max < 0) {
- fprintf(stderr, "Invalid hc_max value: %s\n", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
- } else {
- fprintf(stderr, "Invalid boundary type: %s", tk);
- res = RES_BAD_ARG;
- goto exit;
- }
-
-#undef CHK_TOK
-exit:
- return res;
-}
-
static res_T
read_vertices
(struct sstl_desc* desc,
@@ -496,6 +64,8 @@ read_vertices
res_T res = RES_OK;
unsigned vtx_index = 0;
+ ASSERT(desc && vertex2id && id2id && geometry);
+
for (vtx_index = 0; vtx_index < desc->vertices_count; ++vtx_index){
struct vertex vtx = NULL_VERTEX;
unsigned *found_id = NULL;
@@ -523,9 +93,14 @@ read_vertices
}
static int
-indices_to_key(struct unsigned3* key, const struct unsigned3* indices)
+indices_to_key
+ (struct unsigned3* key,
+ const struct unsigned3* indices)
{
int i, reversed = 0;
+
+ ASSERT(key && indices);
+
FOR_EACH(i, 0, 3) key->data[i] = indices->data[i];
if (key->data[0] > key->data[1]) {
reversed = !reversed;
@@ -557,6 +132,9 @@ read_triangles
unsigned* packed_indices = NULL;
float* packed_normals = NULL;
unsigned tri_index = 0, drop_cpt = 0;
+
+ ASSERT(stl_desc && triangle2id && stl_filename && id2id && geometry && boundary);
+
for (tri_index = 0; tri_index < stl_desc->triangles_count; ++tri_index) {
struct triangle tri = NULL_TRIANGLE;
const unsigned *found_id = NULL;
@@ -678,7 +256,7 @@ end:
goto end;
}
-res_T
+static res_T
read_stl
(const unsigned desc_id,
const enum content_type file_type,
@@ -692,6 +270,8 @@ read_stl
struct sstl_desc stl_desc;
unsigned* id2id = NULL;
+ ASSERT(stl_filename && vertex2id && triangle2id && stardis);
+
if (!stl_filename) return RES_BAD_ARG;
SSTL(create(NULL, &stardis->allocator, 0, &sstl));
@@ -717,10 +297,6 @@ error:
goto end;
}
-/*******************************************************************************
- *
- ******************************************************************************/
-
static res_T
geometry_analyse
(const char* medium_filename,
@@ -731,13 +307,17 @@ geometry_analyse
res_T res = RES_OK;
FILE* input = NULL;
char* line = NULL;
- unsigned sz = (unsigned)sa_size(stardis->descriptions);
+ unsigned sz;
struct htable_vertex vertex2id;
struct htable_triangle triangle2id;
struct htable_descriptions descriptions;
int tables_initialised = 0;
unsigned desc_id;
unsigned *p_desc;
+
+ ASSERT(medium_filename && bc_filename && stardis);
+
+ sz = (unsigned)sa_size(stardis->descriptions);
ASSERT(sz == sa_size(stardis->descriptions));
stardis->geometry = NULL_GEOMETRY;
@@ -846,59 +426,8 @@ error:
goto exit;
}
-static res_T
-parse_camera
- (char* cam_param, struct camera* cam)
-{
- char** line = NULL;
- char** opt = NULL;
- res_T res = RES_OK;
-
- line = split_line(cam_param,':');
-
- if (line)
- {
- int i = 0;
- for (i = 0; *(line + i); i++)
- {
- size_t len = 0;
- opt = split_line(line[i],'=');
- if (strcmp(opt[0], "t") == 0) {
- res = cstr_to_double(opt[1], &cam->u.time);
- if (res != RES_OK) goto error;
- } else if (strcmp(opt[0],"fov")==0){
- res = cstr_to_double(opt[1], &cam->fov);
- if (res != RES_OK) goto error;
- } else if (strcmp(opt[0],"up")==0) {
- res = cstr_to_list_double(opt[1], ',', cam->up, &len, 3);
- if (res != RES_OK || len != 3) goto error;
- } else if (strcmp(opt[0],"tgt")==0) {
- res = cstr_to_list_double(opt[1], ',', cam->tgt, &len, 3);
- if (res != RES_OK || len != 3) goto error;
- } else if (strcmp(opt[0],"pos")==0) {
- res = cstr_to_list_double(opt[1], ',', cam->pos, &len, 3);
- if (res != RES_OK || len != 3) goto error;
- } else if (strcmp(opt[0],"img")==0) {
- res = cstr_to_list_uint(opt[1], 'x', cam->img, &len, 2);
- if (res != RES_OK || len != 2) goto error;
- } else if (strcmp(opt[0],"spp")==0) {
- res = cstr_to_uint(opt[1], &cam->spp);
- if (res != RES_OK) goto error;
- }
- }
- }
-
-exit:
- FREE_AARRAY(line)
- FREE_AARRAY(opt)
-
- return res;
-error:
- goto exit;
-}
-
/*******************************************************************************
- *
+ * Public Functions
******************************************************************************/
res_T
@@ -908,9 +437,12 @@ stardis_init
{
res_T res = RES_OK;
+ ASSERT(args && stardis);
+
res = mem_init_proxy_allocator(&stardis->allocator,
&mem_default_allocator);
if (res != RES_OK) goto error;
+ stardis->allocator_initialized = 1;
res = geometry_analyse(args->medium_filename,
args->bc_filename, args->solve_boundary_filename, stardis);
@@ -951,8 +483,18 @@ error:
void
stardis_release(struct stardis* stardis)
{
- size_t i = 0;
+ size_t memsz, i = 0;
+
+ if(!stardis) return;
+ if (stardis->geometry.interfaces) {
+ for (i = 0; i < sa_size(stardis->geometry.interfaces); ++i)
+ SDIS(interface_ref_put(stardis->geometry.interfaces[i]));
+ sa_release(stardis->geometry.interfaces);
+ stardis->geometry.interfaces = NULL;
+ }
+ sa_release(stardis->geometry.interf_bytrg);
+ stardis->geometry.interf_bytrg = NULL;
for (i=0; i<sa_size(stardis->descriptions); ++i) {
struct description* desc = &stardis->descriptions[i];
switch (desc->type) {
@@ -985,48 +527,17 @@ stardis_release(struct stardis* stardis)
release_geometry(&stardis->geometry);
sa_release(stardis->boundary.primitives);
sa_release(stardis->boundary.sides);
-}
-
-/* TODO: rewrite dump! */
-res_T
-dump_vtk
- (FILE* output,
- const struct geometry* geometry)
-{
- res_T res = RES_OK;
- unsigned i;
- struct vertex* vtx = geometry->vertex;
- struct triangle* tri = geometry->triangle;
-
- if (!output){
- fprintf(stderr, "Invalid output file to dump vtk.\n");
- res = RES_BAD_ARG;
- goto error;
- }
- fprintf(output,"# vtk DataFile Version 2.0\nvtk output\nASCII\nDATASET POLYDATA\n");
- fprintf(output,"POINTS %i float\n\n", (int)sa_size(vtx));
- for (i=0; i<sa_size(vtx); ++i){
- fprintf(output,"%f %f %f\n",SPLIT3(vtx[i].xyz));
- }
- fprintf(output,"\nPOLYGONS %i %i\n", (int)sa_size(tri), (int)(4*sa_size(tri)));
- for (i=0; i<sa_size(tri); ++i){
- fprintf(output,"3 %i %i %i\n",SPLIT3(tri[i].indices.data));
- }
- fprintf(output,"\nCELL_DATA %i \n", (int)sa_size(tri));
- fprintf(output,"SCALARS front_description float 1\n");
- fprintf(output,"LOOKUP_TABLE default\n");
- for (i=0; i<sa_size(tri); ++i) {
- fprintf(output,"%i\n",tri[i].front_description);
+ if (stardis->allocator_initialized
+ && (memsz = MEM_ALLOCATED_SIZE(&stardis->allocator)) != 0)
+ {
+ char dump[4096] = { '\0' };
+ MEM_DUMP(&stardis->allocator, dump, sizeof(dump));
+ fprintf(stderr, "%s\n", dump);
+ fprintf(stderr, "Memory leaks: %lu Bytes\n", (unsigned long)memsz);
}
- fprintf(output,"SCALARS back_description float 1\n");
- fprintf(output,"LOOKUP_TABLE default\n");
- for (i=0; i<sa_size(tri); ++i) {
- fprintf(output,"%i\n",tri[i].back_description);
+ if (stardis->allocator_initialized) {
+ mem_shutdown_proxy_allocator(&stardis->allocator);
+ stardis->allocator_initialized = 0;
}
-
-exit:
- return res;
-error:
- goto exit;
}
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -3,6 +3,8 @@
#ifndef STARDIS_APP_H
#define STARDIS_APP_H
+#include "stardis-parsing.h"
+
#include <star/sstl.h>
#include <rsys/rsys.h>
#include <rsys/float3.h>
@@ -10,7 +12,6 @@
#include <rsys/hash_table.h>
#include <sdis.h>
#include <tinyexpr.h>
-#include "args.h"
#define FREE_AARRAY(ARRAY) if (ARRAY) {\
int i = 0; \
@@ -63,19 +64,6 @@ struct triangle {
#define NULL_TRIANGLE__ {{{0, 0, 0}}, UINT_MAX, UINT_MAX, UINT_MAX }
static const struct triangle NULL_TRIANGLE = NULL_TRIANGLE__;
-static INLINE void
-print_trg_as_obj
- (FILE* stream,
- const struct vertex* vertices,
- const unsigned* indices)
-{
- ASSERT(stream && vertices && indices);
- fprintf(stream, "v %.8f %.8f %.8f\nv %.8f %.8f %.8f\nv %.8f %.8f %.8f\nf 1 2 3\n",
- SPLIT3(vertices[indices[0]].xyz),
- SPLIT3(vertices[indices[1]].xyz),
- SPLIT3(vertices[indices[2]].xyz));
-}
-
static INLINE char
eq_indices(const struct unsigned3* a, const struct unsigned3* b)
{
@@ -159,44 +147,6 @@ eq_fluid(const struct mat_fluid* a, const struct mat_fluid* b)
static size_t
hash_fluid(const struct mat_fluid* key)
{
-#ifdef ARCH_32BITS
- /* 32-bits Fowler/Noll/Vo hash function */
- const uint32_t FNV32_PRIME =
- (uint32_t) (((uint32_t) 1 << 24) + ((uint32_t) 1 << 8) + 0x93);
- const uint32_t OFFSET32_BASIS = 2166136261u;
- 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;
- }
- FOR_EACH(i, 0, sizeof(key->rho)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->rho)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->cp)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->cp)[i]);
- hash = hash * FNV32_PRIME;
- }
- hash = hash ^ (uint32_t)((unsigned char)(key->Tinit == 0));
- hash = hash * FNV32_PRIME;
- FOR_EACH(i, 0, key->Tinit ? strlen(key->Tinit) * sizeof(*key->Tinit) : 0) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)key->Tinit)[i]);
- hash = hash * FNV32_PRIME;
- }
- hash = hash ^ (uint32_t)((unsigned char)(key->Temp == 0));
- hash = hash * FNV32_PRIME;
- FOR_EACH(i, 0, key->Temp ? strlen(key->Temp) * sizeof(*key->Temp) : 0) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)key->Temp)[i]);
- hash = hash * FNV32_PRIME;
- }
- return hash;
-#elif defined(ARCH_64BITS)
/* 64-bits Fowler/Noll/Vo hash function */
const uint64_t FNV64_PRIME =
(uint64_t) (((uint64_t) 1 << 40) + ((uint64_t) 1 << 8) + 0xB3);
@@ -233,9 +183,6 @@ hash_fluid(const struct mat_fluid* key)
hash = hash * FNV64_PRIME;
}
return hash;
-#else
-#error "Unexpected architecture"
-#endif
}
struct mat_solid {
@@ -286,61 +233,6 @@ eq_solid(const struct mat_solid* a, const struct mat_solid* b)
static size_t
hash_solid(const struct mat_solid* key)
{
-#ifdef ARCH_32BITS
- /* 32-bits Fowler/Noll/Vo hash function */
- const uint32_t FNV32_PRIME =
- (uint32_t) (((uint32_t) 1 << 24) + ((uint32_t) 1 << 8) + 0x93);
- const uint32_t OFFSET32_BASIS = 2166136261u;
- 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;
- }
- FOR_EACH(i, 0, sizeof(key->lambda)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->lambda)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->rho)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->rho)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->cp)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->cp)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->delta)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->delta)[i]);
- hash = hash * FNV32_PRIME;
- }
- hash = hash ^ (uint32_t)((unsigned char)(key->Tinit == 0));
- hash = hash * FNV32_PRIME;
- FOR_EACH(i, 0, key->Tinit ? strlen(key->Tinit) * sizeof(*key->Tinit) : 0) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)key->Tinit)[i]);
- hash = hash * FNV32_PRIME;
- }
- hash = hash ^ (uint32_t)((unsigned char)(key->Temp == 0));
- hash = hash * FNV32_PRIME;
- FOR_EACH(i, 0, key->Temp ? strlen(key->Temp) * sizeof(*key->Temp) : 0) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)key->Temp)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->has_power)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->has_power)[i]);
- hash = hash * FNV32_PRIME;
- }
- if (!key->has_power) return hash;
- FOR_EACH(i, 0, strlen(key->Tinit) * sizeof(*key->power)) {
- hash = hash ^ (uint32_t) ((unsigned char) ((const char*) key->power)[i]);
- hash = hash * FNV32_PRIME;
- }
- return hash;
-#elif defined(ARCH_64BITS)
/* 64-bits Fowler/Noll/Vo hash function */
const uint64_t FNV64_PRIME =
(uint64_t) (((uint64_t) 1 << 40) + ((uint64_t) 1 << 8) + 0xB3);
@@ -394,9 +286,6 @@ hash_solid(const struct mat_solid* key)
hash = hash * FNV64_PRIME;
}
return hash;
-#else
-#error "Unexpected architecture"
-#endif
}
struct h_boundary {
@@ -451,53 +340,6 @@ eq_h_boundary
static size_t
hash_h_boundary(const struct h_boundary* key)
{
-#ifdef ARCH_32BITS
- /* 32-bits Fowler/Noll/Vo hash function */
- const uint32_t FNV32_PRIME =
- (uint32_t) (((uint32_t) 1 << 24) + ((uint32_t) 1 << 8) + 0x93);
- const uint32_t OFFSET32_BASIS = 2166136261u;
- 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->mat_id)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->mat_id)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->emissivity)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->emissivity)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->specular_fraction)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->specular_fraction)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, strlen(key->T) * sizeof(*key->T)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)key->T)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->has_emissivity)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->has_emissivity)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->has_hc)) {
- hash = hash ^ (uint32_t) ((unsigned char) ((const char*) &key->has_hc)[i]);
- hash = hash * FNV32_PRIME;
- }
- if (!key->has_hc) return hash;
- FOR_EACH(i, 0, sizeof(key->hc)) {
- hash = hash ^ (uint32_t) ((unsigned char) ((const char*) &key->hc)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->hc_max)) {
- hash = hash ^ (uint32_t) ((unsigned char) ((const char*) &key->hc_max)[i]);
- hash = hash * FNV32_PRIME;
- }
- return hash;
-#elif defined(ARCH_64BITS)
/* 64-bits Fowler/Noll/Vo hash function */
const uint64_t FNV64_PRIME =
(uint64_t) (((uint64_t) 1 << 40) + ((uint64_t) 1 << 8) + 0xB3);
@@ -543,9 +385,6 @@ hash_h_boundary(const struct h_boundary* key)
hash = hash * FNV64_PRIME;
}
return hash;
-#else
-#error "Unexpected architecture"
-#endif
}
struct t_boundary {
@@ -606,41 +445,6 @@ hash_t_boundary
{
(void)type;
ASSERT(type == DESC_BOUND_T_FOR_SOLID || type == DESC_BOUND_T_FOR_FLUID);
-#ifdef ARCH_32BITS
- /* 32-bits Fowler/Noll/Vo hash function */
- const uint32_t FNV32_PRIME =
- (uint32_t) (((uint32_t) 1 << 24) + ((uint32_t) 1 << 8) + 0x93);
- const uint32_t OFFSET32_BASIS = 2166136261u;
- 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->mat_id)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->mat_id)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->has_hc)) {
- hash = hash ^ (uint32_t) ((unsigned char) ((const char*) &key->has_hc)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, strlen(key->T) * sizeof(*key->T)) {
- hash = hash ^ (uint32_t) ((unsigned char) ((const char*) key->T)[i]);
- hash = hash * FNV32_PRIME;
- }
- if (!key->has_hc) return hash;
- FOR_EACH(i, 0, sizeof(key->hc)) {
- hash = hash ^ (uint32_t) ((unsigned char) ((const char*) &key->hc)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->hc_max)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->hc_max)[i]);
- hash = hash * FNV32_PRIME;
- }
- return hash;
-#elif defined(ARCH_64BITS)
/* 64-bits Fowler/Noll/Vo hash function */
const uint64_t FNV64_PRIME =
(uint64_t) (((uint64_t) 1 << 40) + ((uint64_t) 1 << 8) + 0xB3);
@@ -674,9 +478,6 @@ hash_t_boundary
hash = hash * FNV64_PRIME;
}
return hash;
-#else
-#error "Unexpected architecture"
-#endif
}
struct f_boundary {
@@ -712,28 +513,6 @@ eq_f_boundary(const struct f_boundary* a, const struct f_boundary* b)
static size_t
hash_f_boundary(const struct f_boundary* key)
{
-#ifdef ARCH_32BITS
- /* 32-bits Fowler/Noll/Vo hash function */
- const uint32_t FNV32_PRIME =
- (uint32_t) (((uint32_t) 1 << 24) + ((uint32_t) 1 << 8) + 0x93);
- const uint32_t OFFSET32_BASIS = 2166136261u;
- 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->mat_id)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->mat_id)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, strlen(key->flux) * sizeof(*key->flux)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)key->flux)[i]);
- hash = hash * FNV32_PRIME;
- }
- return hash;
-#elif defined(ARCH_64BITS)
/* 64-bits Fowler/Noll/Vo hash function */
const uint64_t FNV64_PRIME =
(uint64_t) (((uint64_t) 1 << 40) + ((uint64_t) 1 << 8) + 0xB3);
@@ -754,9 +533,6 @@ hash_f_boundary(const struct f_boundary* key)
hash = hash * FNV64_PRIME;
}
return hash;
-#else
-#error "Unexpected architecture"
-#endif
}
struct solid_fluid_connect {
@@ -785,44 +561,6 @@ eq_sf_connect(const struct solid_fluid_connect* a, const struct solid_fluid_conn
static size_t
hash_sf_connect(const struct solid_fluid_connect* key)
{
-#ifdef ARCH_32BITS
- /* 32-bits Fowler/Noll/Vo hash function */
- const uint32_t FNV32_PRIME =
- (uint32_t) (((uint32_t) 1 << 24) + ((uint32_t) 1 << 8) + 0x93);
- const uint32_t OFFSET32_BASIS = 2166136261u;
- 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->emissivity)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->emissivity)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->specular_fraction)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->specular_fraction)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->hc)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->hc)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->hc_max)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->hc_max)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->has_emissivity)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->has_emissivity)[i]);
- hash = hash * FNV32_PRIME;
- }
- FOR_EACH(i, 0, sizeof(key->has_hc)) {
- hash = hash ^ (uint32_t)((unsigned char)((const char*)&key->has_hc)[i]);
- hash = hash * FNV32_PRIME;
- }
- return hash;
-#elif defined(ARCH_64BITS)
/* 64-bits Fowler/Noll/Vo hash function */
const uint64_t FNV64_PRIME =
(uint64_t) (((uint64_t) 1 << 40) + ((uint64_t) 1 << 8) + 0xB3);
@@ -859,9 +597,6 @@ hash_sf_connect(const struct solid_fluid_connect* key)
hash = hash * FNV64_PRIME;
}
return hash;
-#else
-#error "Unexpected architecture"
-#endif
}
struct description {
@@ -885,7 +620,7 @@ init_description(struct description* desc) {
static INLINE void
print_description
(FILE* stream,
- struct description* desc)
+ const struct description* desc)
{
ASSERT(stream && desc);
switch (desc->type) {
@@ -1023,16 +758,4 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode);
extern void
stardis_release(struct stardis* stardis);
-extern res_T
-dump_vtk(FILE* output, const struct geometry* geometry);
-
-extern res_T
-read_stl
- (const unsigned desc_id,
- const enum content_type file_type,
- const char* stl_filename,
- struct htable_vertex* vertex2id,
- struct htable_triangle* triangle2id,
- struct stardis* stardis);
-
#endif /*STARDIS-APP_H*/
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -1,38 +1,33 @@
/* Copyright (C) 2018 |Meso|Star> (contact@meso-star.com)*/
#include "stardis-app.h"
+#include "stardis-output.h"
+#include "stardis-compute.h"
+#include "stardis-fluid.h"
+#include "stardis-solid.h"
+#include "stardis-intface.h"
+
#include <sdis.h>
#include <sdis_version.h>
#include <rsys/double3.h>
#include <rsys/double2.h>
-#include <rsys/dynamic_array_uint.h>
#include <rsys/image.h>
-#include<star/senc.h>
-
-#include <rsys/hash_table.h>
-#define HTABLE_NAME vrtx_rank
-#define HTABLE_DATA unsigned
-#define HTABLE_KEY unsigned
-#include <rsys/hash_table.h>
-#define HTABLE_NAME weigth
-#define HTABLE_DATA double
-#define HTABLE_KEY unsigned
-#include <rsys/hash_table.h>
-
-struct w_ctx {
- struct description* desc;
- struct htable_weigth weigths;
+struct dummies {
+ struct sdis_medium* dummy_fluid;
+ unsigned dummy_fluid_id;
+ struct sdis_medium* dummy_solid;
+ unsigned dummy_solid_id;
};
+#define DUMMIES_NULL__ {\
+ NULL, UINT_MAX, NULL, UINT_MAX\
+}
+static const struct dummies DUMMIES_NULL = DUMMIES_NULL__;
-/* A type to limit variable use in tinyexpr expressions */
-enum var_prohibited_t {
- ALL_VARS_ALLOWED = 0,
- T_PROHIBITED = BIT(4),
- XYZ_PROHIBITED = BIT(5),
- NO_VAR_ALLOWED = T_PROHIBITED | XYZ_PROHIBITED
-};
+/*******************************************************************************
+ * Local Functions
+ ******************************************************************************/
static void
geometry_get_position
@@ -41,6 +36,7 @@ geometry_get_position
void* context)
{
struct geometry* geom = context;
+ ASSERT(geom);
pos[0] = geom->vertex[ivert].xyz[0];
pos[1] = geom->vertex[ivert].xyz[1];
pos[2] = geom->vertex[ivert].xyz[2];
@@ -53,6 +49,7 @@ geometry_get_indices
void* context)
{
struct geometry* geom = context;
+ ASSERT(geom);
ids[0] = geom->triangle[itri].indices.data[0];
ids[1] = geom->triangle[itri].indices.data[1];
ids[2] = geom->triangle[itri].indices.data[2];
@@ -65,305 +62,16 @@ geometry_get_interface
void* context)
{
struct geometry* geom = context;
+ ASSERT(geom);
*interf = geom->interf_bytrg[itri];
}
-static res_T
-compile_expr_to_fn
- (struct te_expr** f,
- const char* math_expr,
- const int prohibited,
- int* is_zero)
-{
- te_variable vars[4] = {
- TE_DEF_OFFSET("x", offsetof(struct sdis_rwalk_vertex, P[0])),
- TE_DEF_OFFSET("y", offsetof(struct sdis_rwalk_vertex, P[1])),
- TE_DEF_OFFSET("z", offsetof(struct sdis_rwalk_vertex, P[2])),
- TE_DEF_OFFSET("t", offsetof(struct sdis_rwalk_vertex, time))
- };
- int fst = 0, lst = 4;
- ASSERT(math_expr);
- ASSERT(prohibited == (prohibited & NO_VAR_ALLOWED)); /* Use only defined flags */
- if (prohibited & XYZ_PROHIBITED) fst = 3;
- if(prohibited & T_PROHIBITED) lst = 3;
- *f = te_compile(math_expr, vars+fst, lst-fst, NULL);
- if (!*f) {
- if ((prohibited != ALL_VARS_ALLOWED)
- && te_compile(math_expr, vars, 4, NULL))
- fprintf(stderr, "Expression %s use a probibited variable ", math_expr);
- if (prohibited == NO_VAR_ALLOWED)
- fprintf(stderr, "(no variable allowed)\n");
- else if (prohibited == XYZ_PROHIBITED)
- fprintf(stderr, "(xyz prohibited)\n");
- else {
- ASSERT(prohibited == T_PROHIBITED);
- fprintf(stderr, "(t prohibited)\n");
- }
- return RES_BAD_ARG;
- }
- if (is_zero) *is_zero = !((*f)->type == TE_CONSTANT && (*f)->v.value == 0);
- return RES_OK;
-}
-
-/*******************************************************************************
- * Fluid data
- ******************************************************************************/
-struct fluid {
- char name[32];
- double cp; /* Calorific capacity */
- double rho; /* Volumic mass */
- /* Compute mode */
- int is_green, is_outside;
- double t0;
- /* TinyExpr stuff to compute temperature */
- struct te_expr *temp;
- struct te_expr *t_init;
- /* ID */
- unsigned id;
-};
-
-static double
-fluid_get_calorific_capacity
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct fluid* fluid_props = sdis_data_cget(data);
- (void)vtx;
- return fluid_props->cp;
-}
-
-static double
-fluid_get_volumic_mass
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct fluid* fluid_props = sdis_data_cget(data);
- (void)vtx;
- return fluid_props->rho;
-}
-
-static double
-fluid_get_temperature
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct fluid* fluid_props = sdis_data_cget(data);
- char msg[128];
- ASSERT(fluid_props->t_init || fluid_props->temp);
- if (fluid_props->is_green || vtx->time > fluid_props->t0) {
- /* Always use temp for Green mode, regardless of time */
- if (fluid_props->temp)
- return te_eval(fluid_props->temp, vtx);
- else return -1;
- }
- /* Time is t0: use t_init */
- if (fluid_props->t_init)
- return te_eval(fluid_props->t_init, vtx);
- /* Must have had t_init defined: error! */
- if (fluid_props->name[0])
- sprintf(msg,
- "fluid_get_temperature: getting undefined Tinit (fluid '%s')\n",
- fluid_props->name);
- else
- sprintf(msg, "fluid_get_temperature: getting undefined Tinit\n");
- FATAL(msg);
-}
-
-static void
-release_fluid_data(void* f)
-{
- struct fluid* fluid = (struct fluid*)f;
- te_free(fluid->t_init);
- te_free(fluid->temp);
-}
-
-/*******************************************************************************
- * Solid data
- ******************************************************************************/
-struct solid {
- char name[32];
- double cp; /* Calorific capacity */
- double lambda; /* Conductivity */
- double rho; /* Volumic mass */
- double delta; /* Numerical parameter */
- /* Compute mode */
- int is_green, is_outside;
- double t0;
- /* TinyExpr stuff to compute temperature & power */
- struct te_expr *temp;
- struct te_expr *t_init;
- struct te_expr *power;
- /* ID */
- unsigned id;
-};
-
-static double
-solid_get_calorific_capacity
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct solid* solid_props = sdis_data_cget(data);
- (void)vtx;
- return solid_props->cp;
-}
-
-static double
-solid_get_thermal_conductivity
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct solid* solid_props = sdis_data_cget(data);
- (void)vtx;
- return solid_props->lambda;
-}
-
-static double
-solid_get_volumic_mass
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct solid* solid_props = sdis_data_cget(data);
- (void)vtx;
- return solid_props->rho;
-}
-
-static double
-solid_get_delta
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct solid* solid_props = sdis_data_cget(data);
- (void)vtx;
- return solid_props->delta;
-}
-
-#if Stardis_VERSION_MINOR == 3
-static double
-solid_get_delta_boundary
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct solid* solid_props = sdis_data_cget(data);
- return solid_props->delta
- /* Emperical scale factor that ensures that delta_boundary > delta withouht
- * being an exact multiple of delta. */
- /** 2.1 */;
-}
-#endif
-
-static double
-solid_get_temperature
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct solid* solid_props = sdis_data_cget(data);
- char msg[128];
- ASSERT(solid_props->t_init || solid_props->temp);
- if (solid_props->is_green || vtx->time > solid_props->t0) {
- /* Always use temp for Green mode, regardless of time */
- if (solid_props->temp)
- return te_eval(solid_props->temp, vtx);
- else return -1;
- }
- /* Time is t0: use t_init */
- if (solid_props->t_init)
- return te_eval(solid_props->t_init, vtx);
- /* Must have had t_init defined: error! */
- if (solid_props->name[0])
- sprintf(msg,
- "solid_get_temperature: getting undefined Tinit (solid '%s')\n",
- solid_props->name);
- else
- sprintf(msg, "solid_get_temperature: getting undefined Tinit\n");
- FATAL(msg);
-}
-
-static double
-solid_get_power
- (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data)
-{
- const struct solid* solid_props = sdis_data_cget(data);
- return te_eval(solid_props->power, vtx);
-}
-
-static void
-release_solid_data(void* s)
-{
- struct solid* solid = (struct solid*)s;
- te_free(solid->t_init);
- te_free(solid->power);
-}
-
-/*******************************************************************************
- * Interface data
- ******************************************************************************/
-struct intface {
- double hc; /* Convection coefficient */
- double emissivity;
- double alpha;
- /* TinyExpr stuff to compute temperature & flux */
- struct te_expr *temperature;
- struct te_expr *flux;
- /* IDs */
- unsigned front_boundary_id, back_boundary_id;
-};
-
-static double
-interface_get_convection_coef
- (const struct sdis_interface_fragment* frag, struct sdis_data* data)
-{
- const struct intface* interface_props = sdis_data_cget(data);
- (void)frag;
- return interface_props->hc;
-}
-
-static double
-interface_get_temperature
- (const struct sdis_interface_fragment* frag, struct sdis_data* data)
-{
- const struct intface* interface_props = sdis_data_cget(data);
-
- if (interface_props->temperature == NULL)
- return -1;
-
- return te_eval(interface_props->temperature, frag);
-}
-
-static double
-interface_get_flux
- (const struct sdis_interface_fragment* frag, struct sdis_data* data)
-{
- const struct intface* interface_props = sdis_data_cget(data);
-
- if (interface_props->flux == NULL)
- return SDIS_FLUX_NONE;
-
- return te_eval(interface_props->flux, frag);
-}
-
-static void
-release_interface_data(void* s)
-{
- struct intface* intface = (struct intface*)s;
- te_free(intface->temperature);
- te_free(intface->flux);
-}
-
-static double
-interface_get_emissivity
- (const struct sdis_interface_fragment* frag, struct sdis_data* data)
-{
- const struct intface* interface_props = sdis_data_cget(data);
- (void)frag;
- return interface_props->emissivity;
-}
-
-static INLINE double
-interface_get_alpha
- (const struct sdis_interface_fragment* frag, struct sdis_data* data)
-{
- const struct intface* interface_props = sdis_data_cget(data);
- (void)frag;
- return interface_props->alpha;
-}
-
+/* Check probe position and move it to the closest point on an interface
+ * if on_interface is set */
static res_T
select_probe_type
(const struct sdis_scene* scn,
- const struct triangle* triangle,
- const struct vertex* vertex,
- const struct description* descriptions,
+ const struct stardis* stardis,
const int on_interface,
double pos[3],
size_t* iprim,
@@ -374,7 +82,14 @@ select_probe_type
const struct description *min_desc = NULL;
size_t i = 0, found = SIZE_MAX;
enum description_type min_type = DESCRIPTION_TYPE_COUNT__;
-
+ const struct triangle* triangle;
+ const struct vertex* vertex;
+ const struct description* descriptions;
+
+ ASSERT(scn && stardis && pos && iprim && uv);
+ triangle = stardis->geometry.triangle;
+ vertex = stardis->geometry.vertex;
+ descriptions = stardis->descriptions;
for (i = 0; i < sa_size(triangle); ++i) {
const struct triangle* tr = triangle + i;
double dp[3], d, projected_pos[3], nn[3];
@@ -437,7 +152,7 @@ select_probe_type
}
if (!min_desc) {
- /* Don't manage pos is outside the model
+ /* Doesn't handle the case where pos is outside the model
* but very close and could be considered on the boundary */
fprintf(stderr, "The probe is outside the model.\n");
return RES_BAD_ARG;
@@ -469,1114 +184,551 @@ select_probe_type
return res;
}
-static void
-dump_image(const struct sdis_estimator_buffer* buf)
-{
- size_t definition[2];
- double* temps = NULL;
- size_t ix, iy;
-
- CHK(buf != NULL);
- CHK(sdis_estimator_buffer_get_definition(buf, definition) == RES_OK);
-
- temps = mem_alloc(definition[0] * definition[1] *sizeof(double));
- CHK(temps != NULL);
-
- /* Compute the per pixel temperature */
- fprintf(stdout,"# vtk DataFile Version 2.0\nvtk output\nASCII\nDATASET STRUCTURED_POINTS\n");
- fprintf(stdout,"DIMENSIONS %zu %zu 1\n", definition[0], definition[1]);
- fprintf(stdout,"ORIGIN 0 0 0\n");
- fprintf(stdout,"SPACING 1 1 1\n");
- fprintf(stdout,"POINT_DATA %zu\n", definition[0] * definition[1]);
- fprintf(stdout,"SCALARS temperature_estimate float 1\n");
- fprintf(stdout,"LOOKUP_TABLE default\n");
- FOR_EACH(iy, 0, definition[1]) {
- FOR_EACH(ix, 0, definition[0]) {
- const struct sdis_estimator* estimator;
- struct sdis_mc T;
- CHK(sdis_estimator_buffer_at(buf, ix, iy, &estimator) == RES_OK);
- CHK(sdis_estimator_get_temperature(estimator, &T) == RES_OK);
- fprintf(stdout,"%f\n", T.E);
- }
- }
- fprintf(stdout, "SCALARS temperature_std_dev float 1\n");
- fprintf(stdout, "LOOKUP_TABLE default\n");
- FOR_EACH(iy, 0, definition[1]) {
- FOR_EACH(ix, 0, definition[0]) {
- const struct sdis_estimator* estimator;
- struct sdis_mc T;
- CHK(sdis_estimator_buffer_at(buf, ix, iy, &estimator) == RES_OK);
- CHK(sdis_estimator_get_temperature(estimator, &T) == RES_OK);
- fprintf(stdout, "%f\n", T.SE);
- }
- }
- fprintf(stdout, "SCALARS computation_time float 1\n");
- fprintf(stdout, "LOOKUP_TABLE default\n");
- FOR_EACH(iy, 0, definition[1]) {
- FOR_EACH(ix, 0, definition[0]) {
- const struct sdis_estimator* estimator;
- struct sdis_mc time;
- CHK(sdis_estimator_buffer_at(buf, ix, iy, &estimator) == RES_OK);
- CHK(sdis_estimator_get_realisation_time(estimator, &time) == RES_OK);
- fprintf(stdout, "%f\n", time.E);
- }
- }
- fprintf(stdout, "SCALARS computation_time_std_dev float 1\n");
- fprintf(stdout, "LOOKUP_TABLE default\n");
- FOR_EACH(iy, 0, definition[1]) {
- FOR_EACH(ix, 0, definition[0]) {
- const struct sdis_estimator* estimator;
- struct sdis_mc time;
- CHK(sdis_estimator_buffer_at(buf, ix, iy, &estimator) == RES_OK);
- CHK(sdis_estimator_get_realisation_time(estimator, &time) == RES_OK);
- fprintf(stdout, "%f\n", time.SE);
- }
- }
- fprintf(stdout, "SCALARS temperature_failures_count int 1\n");
- fprintf(stdout, "LOOKUP_TABLE default\n");
- FOR_EACH(iy, 0, definition[1]) {
- FOR_EACH(ix, 0, definition[0]) {
- const struct sdis_estimator* estimator;
- size_t nfails;
- CHK(sdis_estimator_buffer_at(buf, ix, iy, &estimator) == RES_OK);
- CHK(sdis_estimator_get_failure_count(estimator, &nfails) == RES_OK);
- fprintf(stdout, "%zu\n", nfails);
- }
- }
- mem_rm(temps);
-}
-
-
-/*******************************************************************************
- *
- ******************************************************************************/
-
-struct int_descs {
- unsigned front, back, connect;
-};
-#define INT_DESCS_NULL__ { UINT_MAX, UINT_MAX, UINT_MAX }
-static const struct int_descs INT_DESCS_NULL = INT_DESCS_NULL__;
-
-static INLINE char
-eq_desc(const struct int_descs* a, const struct int_descs* b)
-{
- return (char)(a->front == b->front && a->back == b->back
- && a->connect == b->connect);
-}
-
-static INLINE size_t
-hash_desc(struct int_descs const* key)
-{
-#ifdef ARCH_32BITS
- return (size_t)hash_fnv32(key, 3 * sizeof(unsigned));
-#elif defined(ARCH_64BITS)
- return (size_t)hash_fnv64(key, 3 * sizeof(unsigned));
-#else
-#error "Unexpected architecture"
-#endif
-}
-
-#include <rsys/hash_table.h>
-/* Declare the hash table that map a vertex to its index */
-#define HTABLE_NAME intface
-#define HTABLE_DATA struct sdis_interface*
-#define HTABLE_KEY struct int_descs
-#define HTABLE_KEY_FUNCTOR_EQ eq_desc
-#define HTABLE_KEY_FUNCTOR_HASH hash_desc
-#include <rsys/hash_table.h>
-
static res_T
-create_fluid
- (struct sdis_device* dev,
- const char* name,
- const double rho,
- const double cp,
- const int is_green,
- const int is_outside,
- const char* tinit_expr,
- const char* t_expr,
- struct sdis_medium*** media_ptr,
- unsigned* out_id)
+create_holder
+ (struct counts* counts,
+ struct dummies* dummies,
+ struct description* description,
+ struct sdis_device* dev,
+ struct sdis_medium*** media,
+ const int is_green)
{
res_T res = RES_OK;
- struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL;
- struct sdis_data* data = NULL;
- struct fluid* fluid_props;
- size_t sz;
/* Could be less restrictive if green output included positions/dates */
int prohibited = is_green ? NO_VAR_ALLOWED : ALL_VARS_ALLOWED;
- ASSERT(dev && rho >= 0 && cp >= 0 && media_ptr && out_id);
- fluid_shader.calorific_capacity = fluid_get_calorific_capacity;
- fluid_shader.volumic_mass = fluid_get_volumic_mass;
- fluid_shader.temperature = fluid_get_temperature;
- res = sdis_data_create(dev, sizeof(struct fluid), ALIGNOF(struct fluid),
- release_fluid_data, &data);
- if (res != RES_OK) goto error;
-
- sz = sa_size(*media_ptr);
- ASSERT(sz < INT_MAX);
- fluid_props = sdis_data_get(data); /* Fetch the allocated memory space */
- if (name) strncpy(fluid_props->name, name, sizeof(fluid_props->name));
- else fluid_props->name[0] = '\0';
- fluid_props->cp = cp;
- fluid_props->rho = rho;
- fluid_props->t_init = NULL;
- fluid_props->temp = NULL;
- fluid_props->is_green = is_green;
- fluid_props->is_outside = is_outside;
- fluid_props->t0 = 0;
- fluid_props->id = (unsigned)sz;
-
- if (tinit_expr) {
- res = compile_expr_to_fn(&fluid_props->t_init, tinit_expr,
- prohibited | T_PROHIBITED, NULL);
+ switch (description->type) {
+ case DESC_BOUND_H_FOR_SOLID:
+ counts->hbound_count++;
+ /* Create an external fluid with bound temp as fluid temp */
+ res = create_fluid(dev, NULL, 1, 1, is_green, 1, NULL,
+ description->d.h_boundary.T, media, &description->d.h_boundary.mat_id);
+ if (res != RES_OK) goto error;
+ break;
+ case DESC_BOUND_H_FOR_FLUID:
+ /* Create an external solid with bound temp as solid temp */
+ counts->hbound_count++;
+ res = create_solid(dev, NULL, INF, 1, 1, 1, is_green, 1, NULL,
+ description->d.h_boundary.T, NULL, media, NULL,
+ &description->d.h_boundary.mat_id);
+ if (res != RES_OK) goto error;
+ break;
+ case DESC_BOUND_T_FOR_SOLID:
+ counts->tbound_count++;
+ ASSERT(description->d.t_boundary.T != NULL);
+ res = compile_expr_to_fn(&description->d.t_boundary.te_temperature,
+ description->d.t_boundary.T, prohibited, NULL);
if (res != RES_OK) {
- fprintf(stderr, "Invalid initial temperature expression: %s\n",
- tinit_expr);
+ fprintf(stderr, "Invalid boundary temperature expression: %s\n",
+ description->d.t_boundary.T);
goto error;
}
- }
- if (t_expr) {
- res = compile_expr_to_fn(&fluid_props->temp, t_expr, prohibited, NULL);
+ if (dummies->dummy_fluid) {
+ /* Reuse external dummy fluid */
+ description->d.t_boundary.mat_id = dummies->dummy_fluid_id;
+ }
+ else {
+ /* Create dummy fluid */
+ res = create_fluid(dev, NULL, 1, 1, is_green, 1, NULL,
+ NULL, media, &description->d.t_boundary.mat_id);
+ if (res != RES_OK) goto error;
+ dummies->dummy_fluid = sa_last(*media);
+ dummies->dummy_fluid_id = description->d.t_boundary.mat_id;
+ }
+ break;
+ case DESC_BOUND_T_FOR_FLUID:
+ counts->tbound_count++;
+ ASSERT(description->d.t_boundary.T != NULL);
+ res = compile_expr_to_fn(&description->d.t_boundary.te_temperature,
+ description->d.t_boundary.T, prohibited, NULL);
if (res != RES_OK) {
- fprintf(stderr, "Invalid temperature expression: %s\n",
- t_expr);
+ fprintf(stderr, "Invalid boundary temperature expression: %s\n",
+ description->d.t_boundary.T);
goto error;
}
+ if (dummies->dummy_solid) {
+ /* Reuse external dummy solid */
+ description->d.t_boundary.mat_id = dummies->dummy_solid_id;
+ }
+ else {
+ /* Create dummy solid */
+ res = create_solid(dev, NULL, 1, 1, 1, 1, is_green, 1, NULL,
+ NULL, NULL, media, NULL, &description->d.t_boundary.mat_id);
+ if (res != RES_OK) goto error;
+ dummies->dummy_solid = sa_last(*media);
+ dummies->dummy_solid_id = description->d.t_boundary.mat_id;
+ }
+ break;
+ case DESC_BOUND_F_FOR_SOLID:
+ counts->fbound_count++;
+ ASSERT(description->d.f_boundary.flux != NULL);
+ res = compile_expr_to_fn(&description->d.f_boundary.te_flux,
+ description->d.f_boundary.flux, 1, NULL);
+ if (res != RES_OK) {
+ fprintf(stderr, "Invalid boundary flux expression: %s\n",
+ description->d.f_boundary.flux);
+ goto error;
+ }
+ if (dummies->dummy_fluid) {
+ /* Reuse external dummy fluid */
+ description->d.f_boundary.mat_id = dummies->dummy_fluid_id;
+ }
+ else {
+ /* Create dummy fluid */
+ res = create_fluid(dev, NULL, 1, 1, is_green, 1, NULL, NULL,
+ media, &description->d.f_boundary.mat_id);
+ if (res != RES_OK) goto error;
+ dummies->dummy_fluid = sa_last(*media);
+ dummies->dummy_fluid_id = description->d.f_boundary.mat_id;
+ }
+ break;
+ case DESC_SOLID_FLUID_CONNECT:
+ counts->sfconnect_count++;
+ ASSERT(description->d.sf_connect.specular_fraction >= 0
+ && description->d.sf_connect.specular_fraction <= 1);
+ ASSERT(description->d.sf_connect.emissivity >= 0);
+ ASSERT(description->d.sf_connect.hc >= 0);
+ break;
+ case DESC_MAT_SOLID:
+ counts->smed_count++;
+ res = create_solid(dev,
+ description->d.solid.name,
+ description->d.solid.lambda,
+ description->d.solid.rho,
+ description->d.solid.cp,
+ description->d.solid.delta,
+ is_green,
+ 0,
+ description->d.solid.Tinit,
+ description->d.solid.Temp,
+ description->d.solid.power,
+ media,
+ &description->d.solid.has_power,
+ &description->d.solid.solid_id);
+ if (res != RES_OK) goto error;
+ break;
+ case DESC_MAT_FLUID:
+ counts->fmed_count++;
+ res = create_fluid(dev,
+ description->d.fluid.name,
+ description->d.fluid.rho,
+ description->d.fluid.cp,
+ is_green,
+ 0,
+ description->d.fluid.Tinit,
+ description->d.fluid.Temp,
+ media,
+ &description->d.fluid.fluid_id);
+ if (res != RES_OK) goto error;
+
+ break;
+ default: FATAL("Invalid type.\n");
}
- res = sdis_fluid_create(dev, &fluid_shader, data, sa_add(*media_ptr, 1));
- if (res != RES_OK) goto error;
- *out_id = fluid_props->id;
end:
- if (data) SDIS(data_ref_put(data));
return res;
error:
goto end;
}
static res_T
-create_solid
- (struct sdis_device* dev,
- const char* name,
- const double lambda,
- const double rho,
- const double cp,
- const double delta,
- const int is_green,
- const int is_outside,
- const char* tinit_expr, /* Can be NULL if not used by getter */
- const char* t_expr, /* Can be NULL if not used by getter */
- const char* power_expr, /* Can be NULL */
- struct sdis_medium*** media_ptr,
- int* out_has_power, /* Can be NULL */
- unsigned* out_id)
+compute_probe
+ (struct sdis_scene* scn,
+ const struct counts* counts,
+ struct stardis* stardis,
+ enum stardis_mode mode)
{
res_T res = RES_OK;
- struct sdis_solid_shader solid_shader = SDIS_SOLID_SHADER_NULL;
- struct sdis_data* data = NULL;
- struct solid* solid_props;
- size_t sz;
- /* Could be less restrictive if green output included positions/dates */
- int prohibited = is_green ? NO_VAR_ALLOWED : ALL_VARS_ALLOWED;
+ double time[2], pos[3], uv[2] = { 0,0 };
+ size_t iprim = SIZE_MAX;
+ struct sdis_green_function* green = NULL;
+ struct sdis_estimator* estimator = NULL;
+
+ ASSERT(scn && counts && stardis && (mode & PROBE_COMPUTE));
- ASSERT(dev && lambda >= 0 && rho >= 0 && cp >= 0 && delta > 0
- && media_ptr && out_id);
- solid_shader.calorific_capacity = solid_get_calorific_capacity;
- solid_shader.thermal_conductivity = solid_get_thermal_conductivity;
- solid_shader.volumic_mass = solid_get_volumic_mass;
- solid_shader.delta_solid = solid_get_delta;
-#if Stardis_VERSION_MINOR == 3
- solid_shader.delta_boundary = solid_get_delta_boundary;
-#endif
- solid_shader.temperature = solid_get_temperature;
- res = sdis_data_create(dev, sizeof(struct solid), ALIGNOF(struct solid),
- release_solid_data, &data);
+ d3_set(pos, stardis->probe);
+ res = select_probe_type(scn, stardis, 0, pos, &iprim, uv);
if (res != RES_OK) goto error;
- sz = sa_size(*media_ptr);
- ASSERT(sz < INT_MAX);
- solid_props = sdis_data_get(data); /* Fetch the allocated memory space */
- if (name) strncpy(solid_props->name, name, sizeof(solid_props->name));
- else solid_props->name[0] = '\0';
- solid_props->lambda = lambda;
- solid_props->rho = rho;
- solid_props->cp = cp;
- solid_props->delta = delta;
- solid_props->t_init = NULL;
- solid_props->temp = NULL;
- solid_props->power = NULL;
- solid_props->is_green = is_green;
- solid_props->is_outside = is_outside;
- solid_props->t0 = 0;
- solid_props->id = (unsigned)sz;
- if (tinit_expr) {
- res = compile_expr_to_fn(&solid_props->t_init, tinit_expr,
- prohibited | T_PROHIBITED, NULL);
- if (res != RES_OK) {
- fprintf(stderr, "Invalid initial temperature expression: %s\n",
- tinit_expr);
- goto error;
- }
- }
- if (t_expr) {
- res = compile_expr_to_fn(&solid_props->temp, t_expr, prohibited, NULL);
- if (res != RES_OK) {
- fprintf(stderr, "Invalid temperature expression: %s\n",
- t_expr);
- goto error;
- }
- }
- if (power_expr) {
- int has_power;
- res = compile_expr_to_fn(&solid_props->power, power_expr, prohibited, &has_power);
- if (res != RES_OK) {
- fprintf(stderr, "Invalid volumic power expression: %s\n",
- power_expr);
- goto error;
- }
- if (out_has_power) *out_has_power = has_power;
- if(has_power) solid_shader.volumic_power = solid_get_power;
- }
- else {
- if (out_has_power) *out_has_power = 0;
+ if (mode & GREEN_MODE) {
+ ASSERT(iprim == SIZE_MAX);
+ res = sdis_solve_probe_green_function(scn,
+ stardis->N,
+ pos,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ &green);
+ if (res != RES_OK) goto error;
+ res = dump_green(green, counts, stardis->descriptions,
+ stardis->radiative_temp);
+ if (res != RES_OK) goto error;
+ } else {
+ ASSERT(iprim == SIZE_MAX);
+ d2_splat(time, stardis->probe[3]);
+ res = sdis_solve_probe(scn,
+ stardis->N,
+ pos,
+ time,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ stardis->dump_paths,
+ &estimator);
+ if (res != RES_OK) goto error;
+ res = print_single_MC_result(mode, estimator, stardis);
+ if (res != RES_OK) goto error;
}
- res = sdis_solid_create(dev, &solid_shader, data, sa_add(*media_ptr, 1));
- if (res != RES_OK) goto error;
- *out_id = solid_props->id;
-
end:
- if (data) SDIS(data_ref_put(data));
+ if (estimator) SDIS(estimator_ref_put(estimator));
+ if (green) SDIS(green_function_ref_put(green));
return res;
error:
goto end;
}
static res_T
-create_edge_file_if
+compute_probe_on_interface
(struct sdis_scene* scn,
- struct mem_allocator* allocator)
+ const struct counts* counts,
+ struct stardis* stardis,
+ enum stardis_mode mode)
{
res_T res = RES_OK;
- unsigned i, comp, scount, vcount;
- char name[64];
- FILE* obj = NULL;
- struct htable_vrtx_rank ranks;
- char structs_initialized = 0;
- struct senc_descriptor* analyze = NULL;
- struct darray_uint comps;
- struct darray_uint edges;
- unsigned cc_count = 0;
- unsigned *cc, *ee, uimax = UINT_MAX;
-
- res = sdis_scene_get_analysis(scn, &analyze);
- if (res != RES_OK) goto error;
- res = sdis_scene_release_analysis(scn);
- if (res != RES_OK) goto error;
-
- ASSERT(scn && allocator);
+ double time[2], pos[3], uv[2] = { 0,0 };
+ size_t iprim = SIZE_MAX;
+ struct sdis_estimator* estimator = NULL;
+ struct sdis_green_function* green = NULL;
- res = senc_descriptor_get_frontier_segments_count(analyze, &scount);
+ ASSERT(scn && counts && stardis && (mode & PROBE_COMPUTE_ON_INTERFACE));
+ d3_set(pos, stardis->probe);
+ res = select_probe_type(scn, stardis, 1, pos, &iprim, uv);
if (res != RES_OK) goto error;
- if(scount == 0)
- /* No edge to exit */
- goto end;
-
- fprintf(stderr, "Some frontier edges found: create OBJ files\n");
-
- htable_vrtx_rank_init(allocator, &ranks);
- darray_uint_init(allocator, &comps);
- darray_uint_init(allocator, &edges);
- structs_initialized = 1;
-
- /* Exit vertices, with a new numbering scheme */
- vcount = 0;
- FOR_EACH(i, 0, scount) {
- unsigned v, edge[2], rk[2];
- res = senc_descriptor_get_frontier_segment(analyze, i, edge);
- if(res != RES_OK) goto error;
- FOR_EACH(v, 0, 2) {
- unsigned* p_rank;
- p_rank = htable_vrtx_rank_find(&ranks, edge + v);
- if(p_rank) {
- rk[v] = *p_rank;
- } else {
- /* First appearance: allocate a rank and exit it */
- unsigned rank;
- size_t tmp = htable_vrtx_rank_size_get(&ranks);
- ASSERT(tmp < UINT_MAX);
- rank = (unsigned) tmp;
- res = htable_vrtx_rank_set(&ranks, edge + v, &rank);
- if (res != RES_OK) goto error;
- rk[v] = rank;
- darray_uint_push_back(&comps, &uimax);
- darray_uint_push_back(&edges, edge + v);
- vcount++;
- }
- /* Manage components */
- cc = darray_uint_data_get(&comps);
- if(cc[rk[0]] != UINT_MAX || cc[rk[1]] != UINT_MAX) {
- /* If both components known, they must be the same */
- ASSERT(cc[rk[0]] == UINT_MAX || cc[rk[1]] == UINT_MAX
- || cc[rk[0]] == cc[rk[1]]);
- FOR_EACH(v, 0, 2) {
- unsigned w = 1 - v; /* The other vertex */
- if (cc[rk[v]] == UINT_MAX) cc[rk[v]] = cc[rk[w]];
- }
- } else {
- /* None are in a know component: create a new one */
- cc[rk[0]] = cc[rk[1]] = cc_count++;
- }
- }
- }
-
- /* Exit segments by component using the new numbering scheme */
- cc = darray_uint_data_get(&comps);
- ee = darray_uint_data_get(&edges);
- FOR_EACH(comp, 0, cc_count) {
- unsigned v;
- snprintf(name, sizeof(name), "frontier_component_%u.obj", comp);
- obj = fopen(name, "w");
- if(!obj) goto error;
- /* Exit all vertices even unused
- * (same numbering scheme for all components) */
- FOR_EACH(v, 0, vcount) {
- double coord[3];
- res = senc_descriptor_get_global_vertex(analyze, ee[v], coord);
- if(res != RES_OK) goto error;
- fprintf(obj, "v %f %f %f\n", SPLIT3(coord));
- }
- FOR_EACH(i, 0, scount) {
- unsigned edge[2], new_ranks[2];
- res = senc_descriptor_get_frontier_segment(analyze, i, edge);
- if(res != RES_OK) goto error;
- ASSERT(cc[edge[0]] == cc[edge[1]]);
- if(cc[edge[0]] != comp)
- /* Segment not in this component */
- continue;
- FOR_EACH(v, 0, 2) {
- unsigned* p_rank;
- p_rank = htable_vrtx_rank_find(&ranks, edge + v);
- ASSERT(p_rank && *p_rank < vcount);
- new_ranks[v] = *p_rank;
- }
-#define OBJ_IDX(Rank) ((Rank)+1)
- fprintf(obj, "l %u %u\n", OBJ_IDX(new_ranks[0]), OBJ_IDX(new_ranks[1]));
-#undef OBJ_IDX
- }
- fclose(obj); obj = NULL;
+ if (mode & GREEN_MODE) {
+ ASSERT(iprim == SIZE_MAX);
+ res = sdis_solve_probe_boundary_green_function(scn,
+ stardis->N,
+ iprim,
+ uv,
+ SDIS_FRONT,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ &green);
+ if (res != RES_OK) goto error;
+ res = dump_green(green, counts, stardis->descriptions,
+ stardis->radiative_temp);
+ if (res != RES_OK) goto error;
+ } else {
+ ASSERT(iprim == SIZE_MAX);
+ d2_splat(time, stardis->probe[3]);
+ res = sdis_solve_probe_boundary(scn,
+ stardis->N,
+ iprim,
+ uv,
+ time,
+ SDIS_FRONT, /* FIXME!!!!!!! */
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ stardis->dump_paths,
+ &estimator);
+ if (res != RES_OK) goto error;
+ res = print_single_MC_result(mode, estimator, stardis);
+ if (res != RES_OK) goto error;
}
-
end:
- if(obj) fclose(obj);
- if(analyze) senc_descriptor_ref_put(analyze);
- if(structs_initialized) {
- htable_vrtx_rank_release(&ranks);
- darray_uint_release(&comps);
- darray_uint_release(&edges);
- }
+ if (estimator) SDIS(estimator_ref_put(estimator));
+ if (green) SDIS(green_function_ref_put(green));
return res;
error:
goto end;
}
static res_T
-dump_path
- (const struct sdis_heat_path* path,
- void* context)
+compute_camera
+ (struct sdis_device* dev,
+ struct sdis_scene* scn,
+ const struct stardis* stardis,
+ const enum stardis_mode mode)
{
- FILE* stream = context;
- enum sdis_heat_path_flag status = SDIS_HEAT_PATH_NONE;
- size_t i, vcount;
+ res_T res = RES_OK;
+ double time[2];
+ size_t width, height;
+ struct sdis_estimator_buffer* buf = NULL;
+ struct sdis_camera* cam = NULL;
- /* 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", 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");
- 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", 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);
- 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;
-}
+ ASSERT(!(mode & GREEN_MODE) && (mode & IR_COMPUTE) && scn && stardis);
+ (void)mode;
-static res_T
-print_power_term
- (struct sdis_medium* mdm,
- const double power_term,
- void* ctx)
-{
- struct sdis_data* data = NULL;
- enum sdis_medium_type type;
- unsigned id;
- struct w_ctx* w_ctx = ctx;
- (void)w_ctx;
- CHK(mdm && ctx);
+ width = (size_t)stardis->camera.img[0];
+ height = (size_t)stardis->camera.img[1];
+ /* Setup the camera */
+ res = sdis_camera_create(dev, &cam);
+ if (res != RES_OK) goto error;
+ res = sdis_camera_set_proj_ratio(cam, (double)width / (double)height);
+ if (res != RES_OK) goto error;
+ res = sdis_camera_set_fov(cam, MDEG2RAD(stardis->camera.fov));
+ if (res != RES_OK) goto error;
+ res = sdis_camera_look_at(cam,
+ stardis->camera.pos,
+ stardis->camera.tgt,
+ stardis->camera.up);
+ if (res != RES_OK) goto error;
- data = sdis_medium_get_data(mdm);
- type = sdis_medium_get_type(mdm);
+ /* Launch the simulation */
+ time[0] = time[1] = stardis->camera.u.time;
+ res = sdis_solve_camera(scn,
+ cam,
+ time,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ width,
+ height,
+ (size_t)stardis->camera.spp,
+ stardis->dump_paths,
+ &buf);
+ if (res != RES_OK) goto error;
- switch (type) {
- case SDIS_FLUID: {
- FATAL("Unexpected power term in fluid");
-#if 0
- struct fluid* d__ = sdis_data_get(data);
- id = d__->id;
- desc = (struct description*)ctx + id;
- ASSERT(id == desc->d.fluid.fluid_id);
- printf("\tF\t%u\t%g", id, power_term);
- break;
-#endif
- }
- case SDIS_SOLID: {
- struct solid* d__ = sdis_data_get(data);
- id = d__->id;
- ASSERT(id == w_ctx->desc[id].d.solid.solid_id);
- printf("\tS\t%u\t%g", id, power_term);
- break;
- }
- default: FATAL("Unreachable code.\n"); break;
- }
- return RES_OK;
+ /* Write the image */
+ res = dump_image(buf);
+ if (res != RES_OK) goto error;
+
+end:
+ if (cam) SDIS(camera_ref_put(cam));
+ if (buf) SDIS(estimator_buffer_ref_put(buf));
+ return res;
+error:
+ goto end;
}
static res_T
-get_flux_terms
- (struct sdis_interface* interf,
- const enum sdis_side side,
- const double flux_term,
- void* ctx)
+compute_medium
+ (struct sdis_scene* scn,
+ struct sdis_medium** media,
+ struct stardis* stardis,
+ enum stardis_mode mode)
{
- struct sdis_data* data = NULL;
- struct intface* d__;
- unsigned id;
- struct w_ctx* w_ctx = ctx;
res_T res = RES_OK;
+ double time[2];
+ size_t sz, ii;
+ struct sdis_medium* medium = NULL;
+ struct sdis_estimator* estimator = NULL;
+ struct sdis_green_function* green = NULL;
- CHK(interf && ctx);
-
- data = sdis_interface_get_data(interf);
- d__ = sdis_data_get(data);
- id = (side == SDIS_FRONT) ? d__->front_boundary_id : d__->back_boundary_id;
+ ASSERT(scn && media && stardis && (mode & MEDIUM_COMPUTE));
- switch (w_ctx->desc[id].type) {
- case DESC_BOUND_T_FOR_SOLID:
- case DESC_BOUND_T_FOR_FLUID:
- case DESC_BOUND_H_FOR_SOLID:
- case DESC_BOUND_H_FOR_FLUID:
- FATAL("Cannot have a flux term here.\n"); break;
- case DESC_BOUND_F_FOR_SOLID: {
- double* w;
- ASSERT(id == w_ctx->desc[id].d.f_boundary.mat_id);
- w = htable_weigth_find(&w_ctx->weigths, &id);
- if (w)
- *w += flux_term;
- else {
- res = htable_weigth_set(&w_ctx->weigths, &id, &flux_term);
+ /* 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->solve_name, desc->d.solid.name)) {
+ ASSERT(sa_size(media) > ii);
+ medium = media[ii];
+ break;
+ }
}
- break;
+ else if (desc->type == DESC_MAT_FLUID) {
+ if (0 == strcmp(stardis->solve_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->solve_name);
+ res = RES_BAD_ARG;
+ goto error;
}
- default: FATAL("Unreachable code.\n"); break;
+
+ if (mode & GREEN_MODE) {
+ res = sdis_solve_medium_green_function(scn,
+ stardis->N,
+ medium,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ &green);
+ if (res != RES_OK) goto error;
+ } else {
+ d2_splat(time, stardis->probe[3]);
+ time[0] = time[1] = stardis->probe[3];
+ res = sdis_solve_medium(scn,
+ stardis->N,
+ medium,
+ time,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ stardis->dump_paths,
+ &estimator);
+ if (res != RES_OK) goto error;
+ res = print_single_MC_result(mode, estimator, stardis);
+ if (res != RES_OK) goto error;
}
+end:
+ if (estimator) SDIS(estimator_ref_put(estimator));
+ if (green) SDIS(green_function_ref_put(green));
return res;
+error:
+ goto end;
}
static res_T
-print_sample
- (struct sdis_green_path* path,
- void* ctx)
+compute_boundary
+ (struct sdis_scene* scn,
+ const struct counts* counts,
+ struct stardis* stardis,
+ enum stardis_mode mode)
{
- struct sdis_point pt = SDIS_POINT_NULL;
- struct sdis_data* data = NULL;
- enum sdis_medium_type type;
- struct htable_weigth_iterator it, end;
- unsigned id;
- size_t pcount, fcount;
- struct w_ctx* w_ctx = ctx;
res_T res = RES_OK;
- CHK(path && ctx);
-
- res = sdis_green_path_get_limit_point(path, &pt);
- if (res != RES_OK) goto error;
-
+ double time[2], pos[3], uv[2] = { 0,0 };
+ size_t iprim = SIZE_MAX;
+ struct sdis_green_function* green = NULL;
+ struct sdis_estimator* estimator = NULL;
- /* For each path, prints:
- * # end #power_terms #flux_terms power_term_1 ... power_term_n flux_term_1 ... flux_term_n
- * with:
- * - end = end_type end_id; end_type = T | H | X | R | F | S
- * - power_term_i = power_type_i power_id_i factor_i
- * - flux_term_i = flux_id_i factor_i
- */
+ ASSERT(scn && counts && stardis && (mode & BOUNDARY_COMPUTE));
- switch (pt.type) {
- case SDIS_FRAGMENT: {
- struct intface* d__;
- data = sdis_interface_get_data(pt.data.itfrag.intface);
- d__ = sdis_data_get(data);
- id = (pt.data.itfrag.fragment.side == SDIS_FRONT)
- ? d__->front_boundary_id : d__->back_boundary_id;
- ASSERT(id != UINT_MAX);
- switch (w_ctx->desc[id].type) {
- case DESC_BOUND_T_FOR_SOLID:
- case DESC_BOUND_T_FOR_FLUID:
- ASSERT(id == w_ctx->desc[id].d.t_boundary.mat_id);
- printf("T\t%u", id);
- break;
- case DESC_BOUND_H_FOR_SOLID:
- case DESC_BOUND_H_FOR_FLUID:
- ASSERT(id == w_ctx->desc[id].d.h_boundary.mat_id);
- printf("H\t%u", id);
- break;
- case DESC_BOUND_F_FOR_SOLID:
- ASSERT(id == w_ctx->desc[id].d.f_boundary.mat_id);
- printf("X\t%u", id);
- break;
- default: FATAL("Unreachable code.\n"); break;
- }
- break;
+ /* FIXME: MOVE TO BOUNDARY SETTING */
+ ASSERT(sa_size(stardis->boundary.primitives)
+ == sa_size(stardis->boundary.sides));
+ if (sa_size(stardis->boundary.sides) == 0) {
+ fprintf(stderr, "Cannot solve boundary %s (empty geometry)\n",
+ stardis->solve_name);
}
- case SDIS_VERTEX:
- type = sdis_medium_get_type(pt.data.mdmvert.medium);
- data = sdis_medium_get_data(pt.data.mdmvert.medium);
- if (pt.data.mdmvert.vertex.P[0] == INF) {
- /* Radiative output */
- printf("R\t%u", (unsigned)sa_size(w_ctx->desc));
- }
- else if (type == SDIS_FLUID) {
- struct fluid* d__ = sdis_data_get(data);
- id = d__->id;
- ASSERT(id == w_ctx->desc[id].d.fluid.fluid_id);
- if (d__->is_outside)
- /* If outside the model and in a fluid with known temperature,
- * its a fluid attached to a H boundary */
- printf("H\t%u", id);
- /* In a standard fluid with known temperature */
- else printf("F\t%u", id);
- } else {
- struct solid* d__ = sdis_data_get(data);
- ASSERT(type == SDIS_SOLID);
- id = d__->id;
- ASSERT(id == w_ctx->desc[id].d.solid.solid_id);
- ASSERT(!d__->is_outside); /* FIXME: what if in external solid? */
- printf("S\t%u", id);
- }
- break;
- default: FATAL("Unreachable code.\n"); break;
- }
-
- res = sdis_green_function_get_power_terms_count(path, &pcount);
+ d3_set(pos, stardis->probe);
+ res = select_probe_type(scn, stardis, 0, pos, &iprim, uv);
if (res != RES_OK) goto error;
- htable_weigth_clear(&w_ctx->weigths);
- res = sdis_green_path_for_each_flux_term(path, get_flux_terms, w_ctx);
- if (res != RES_OK) goto error;
- fcount = htable_weigth_size_get(&w_ctx->weigths);
+ if (mode & GREEN_MODE) {
+ ASSERT(iprim == SIZE_MAX);
+ res = sdis_solve_boundary_green_function(scn,
+ stardis->N,
+ stardis->boundary.primitives,
+ stardis->boundary.sides,
+ sa_size(stardis->boundary.sides),
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ &green);
+ if (res != RES_OK) goto error;
+ res = dump_green(green, counts, stardis->descriptions,
+ stardis->radiative_temp);
+ if (res != RES_OK) goto error;
+ } else {
+ ASSERT(iprim == SIZE_MAX);
+ d2_splat(time, stardis->probe[3]);
+ res = sdis_solve_boundary(scn,
+ stardis->N,
+ stardis->boundary.primitives,
+ stardis->boundary.sides,
+ sa_size(stardis->boundary.sides),
+ time,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ stardis->dump_paths,
+ &estimator);
+ if (res != RES_OK) goto error;
+ res = print_single_MC_result(mode, estimator, stardis);
+ if (res != RES_OK) goto error;
+ }
+end:
+ if (estimator) SDIS(estimator_ref_put(estimator));
+ if (green) SDIS(green_function_ref_put(green));
+ return res;
+error:
+ goto end;
+}
- printf("\t%zu\t%zu", pcount, fcount);
+/*******************************************************************************
+ * Public Functions
+ ******************************************************************************/
- res = sdis_green_path_for_each_power_term(path, print_power_term, ctx);
- if (res != RES_OK) goto error;
+res_T
+compile_expr_to_fn
+ (struct te_expr** f,
+ const char* math_expr,
+ const int prohibited,
+ int* is_zero)
+{
+ te_variable vars[4] = {
+ TE_DEF_OFFSET("x", offsetof(struct sdis_rwalk_vertex, P[0])),
+ TE_DEF_OFFSET("y", offsetof(struct sdis_rwalk_vertex, P[1])),
+ TE_DEF_OFFSET("z", offsetof(struct sdis_rwalk_vertex, P[2])),
+ TE_DEF_OFFSET("t", offsetof(struct sdis_rwalk_vertex, time))
+ };
+ int fst = 0, lst = 4;
- htable_weigth_begin(&w_ctx->weigths, &it);
- htable_weigth_end(&w_ctx->weigths, &end);
- while (!htable_weigth_iterator_eq(&it, &end)) {
- double* w = htable_weigth_iterator_data_get(&it);
- unsigned* k = htable_weigth_iterator_key_get(&it);
- printf("\t%u\t%g", *k, *w);
- htable_weigth_iterator_next(&it);
- }
- printf("\n");
+ ASSERT(f && math_expr);
+ ASSERT(prohibited == (prohibited & NO_VAR_ALLOWED)); /* Use only defined flags */
-error:
- return res;
+ if (prohibited & XYZ_PROHIBITED) fst = 3;
+ if (prohibited & T_PROHIBITED) lst = 3;
+ *f = te_compile(math_expr, vars + fst, lst - fst, NULL);
+ if (!*f) {
+ if (!te_compile(math_expr, vars, 4, NULL))
+ return RES_BAD_ARG; /* Expr is not valid */
+ /* Expr is valid */
+ if (prohibited != ALL_VARS_ALLOWED)
+ fprintf(stderr, "Expression \"%s\" use a probibited variable ", math_expr);
+ if (prohibited == NO_VAR_ALLOWED)
+ fprintf(stderr, "(no variable allowed)\n");
+ else if (prohibited == XYZ_PROHIBITED)
+ fprintf(stderr, "(xyz prohibited)\n");
+ else {
+ ASSERT(prohibited == T_PROHIBITED);
+ fprintf(stderr, "(t prohibited)\n");
+ }
+ return RES_BAD_OP; /* Expr is valid, but use a forbidden var */
+ }
+ if (is_zero) *is_zero = !((*f)->type == TE_CONSTANT && (*f)->v.value == 0);
+ return RES_OK;
}
res_T
-stardis_compute(struct stardis* stardis, enum stardis_mode mode)
+stardis_compute
+ (struct stardis* stardis,
+ enum stardis_mode mode)
{
res_T res = RES_OK;
struct sdis_device* dev = NULL;
struct sdis_medium** media = NULL;
- struct sdis_interface** interfaces = NULL;
- struct sdis_interface** interf_bytrg = NULL;
- struct sdis_data* data = NULL;
-
struct sdis_scene* scn = NULL;
- struct sdis_estimator* estimator = NULL;
- struct sdis_mc temperature;
- struct sdis_estimator_buffer* buf = NULL;
- struct sdis_camera* cam = NULL;
-
- struct sdis_medium* dummy_fluid = NULL;
- unsigned dummy_fluid_id = UINT_MAX;
- struct sdis_medium* dummy_solid = NULL;
- unsigned dummy_solid_id = UINT_MAX;
-
+ struct dummies dummies = DUMMIES_NULL;
struct htable_intface htable_interfaces;
int htable_interfaces_initialised = 0;
- double pos[3] = { 0,0,0 };
- double time[2] = { 0, 0 };
- size_t nfailures;
- size_t smed_count = 0, fmed_count = 0,
- tbound_count = 0, hbound_count = 0, fbound_count = 0, sfconnect_count = 0;
+ struct counts counts = COUNTS_NULL;
unsigned i = 0;
+ ASSERT(stardis);
+
res = sdis_device_create(NULL, &stardis->allocator, stardis->nthreads, 1, &dev);
if (res != RES_OK) goto error;
/* Create media and property holders found in descriptions */
for (i = 0; i < sa_size(stardis->descriptions); ++i) {
- struct description* desc = stardis->descriptions + i;
- /* Could be less restrictive if green output included positions/dates */
- int prohibited = (mode & GREEN_MODE) ? NO_VAR_ALLOWED : ALL_VARS_ALLOWED;
-
- switch (desc->type) {
- case DESC_BOUND_H_FOR_SOLID:
- hbound_count++;
- /* Create an external fluid with bound temp as fluid temp */
- res = create_fluid(dev, NULL, 1, 1, (mode & GREEN_MODE), 1, NULL,
- desc->d.h_boundary.T, &media, &desc->d.h_boundary.mat_id);
- if (res != RES_OK) goto error;
- break;
- case DESC_BOUND_H_FOR_FLUID:
- /* Create an external solid with bound temp as solid temp */
- hbound_count++;
- res = create_solid(dev, NULL, INF, 1, 1, 1, (mode & GREEN_MODE), 1, NULL,
- desc->d.h_boundary.T, NULL, &media, NULL, &desc->d.h_boundary.mat_id);
- if (res != RES_OK) goto error;
- break;
- case DESC_BOUND_T_FOR_SOLID:
- tbound_count++;
- ASSERT(desc->d.t_boundary.T != NULL);
- res = compile_expr_to_fn(&desc->d.t_boundary.te_temperature,
- desc->d.t_boundary.T, prohibited, NULL);
- if (res != RES_OK) {
- fprintf(stderr, "Invalid boundary temperature expression: %s\n",
- desc->d.t_boundary.T);
- goto error;
- }
- if (dummy_fluid) {
- /* Reuse external dummy fluid */
- desc->d.t_boundary.mat_id = dummy_fluid_id;
- } else {
- /* Create dummy fluid */
- res = create_fluid(dev, NULL, 1, 1, (mode & GREEN_MODE), 1, NULL,
- NULL, &media, &desc->d.t_boundary.mat_id);
- if (res != RES_OK) goto error;
- dummy_fluid = sa_last(media);
- dummy_fluid_id = desc->d.t_boundary.mat_id;
- }
- break;
- case DESC_BOUND_T_FOR_FLUID:
- tbound_count++;
- ASSERT(desc->d.t_boundary.T != NULL);
- res = compile_expr_to_fn(&desc->d.t_boundary.te_temperature,
- desc->d.t_boundary.T, prohibited, NULL);
- if (res != RES_OK) {
- fprintf(stderr, "Invalid boundary temperature expression: %s\n",
- desc->d.t_boundary.T);
- goto error;
- }
- if (dummy_solid) {
- /* Reuse external dummy solid */
- desc->d.t_boundary.mat_id = dummy_solid_id;
- } else {
- /* Create dummy solid */
- res = create_solid(dev, NULL, 1, 1, 1, 1, (mode & GREEN_MODE), 1, NULL,
- NULL, NULL, &media, NULL, &desc->d.t_boundary.mat_id);
- if (res != RES_OK) goto error;
- dummy_solid = sa_last(media);
- dummy_solid_id = desc->d.t_boundary.mat_id;
- }
- break;
- case DESC_BOUND_F_FOR_SOLID:
- fbound_count++;
- ASSERT(desc->d.f_boundary.flux != NULL);
- res = compile_expr_to_fn(&desc->d.f_boundary.te_flux,
- desc->d.f_boundary.flux, 1, NULL);
- if (res != RES_OK) {
- fprintf(stderr, "Invalid boundary flux expression: %s\n",
- desc->d.f_boundary.flux);
- goto error;
- }
- if (dummy_fluid) {
- /* Reuse external dummy fluid */
- desc->d.f_boundary.mat_id = dummy_fluid_id;
- } else {
- /* Create dummy fluid */
- res = create_fluid(dev, NULL, 1, 1, (mode & GREEN_MODE), 1, NULL, NULL,
- &media, &desc->d.f_boundary.mat_id);
- if (res != RES_OK) goto error;
- dummy_fluid = sa_last(media);
- dummy_fluid_id = desc->d.f_boundary.mat_id;
- }
- break;
- case DESC_SOLID_FLUID_CONNECT:
- sfconnect_count++;
- ASSERT(desc->d.sf_connect.specular_fraction >= 0
- && desc->d.sf_connect.specular_fraction <= 1);
- ASSERT(desc->d.sf_connect.emissivity >= 0);
- ASSERT(desc->d.sf_connect.hc >= 0);
- break;
- case DESC_MAT_SOLID:
- smed_count++;
- res = create_solid(dev,
- stardis->descriptions[i].d.solid.name,
- stardis->descriptions[i].d.solid.lambda,
- stardis->descriptions[i].d.solid.rho,
- stardis->descriptions[i].d.solid.cp,
- stardis->descriptions[i].d.solid.delta,
- (mode & GREEN_MODE),
- 0,
- stardis->descriptions[i].d.solid.Tinit,
- stardis->descriptions[i].d.solid.Temp,
- stardis->descriptions[i].d.solid.power,
- &media,
- &stardis->descriptions[i].d.solid.has_power,
- &desc->d.solid.solid_id);
- if (res != RES_OK) goto error;
- break;
- case DESC_MAT_FLUID:
- fmed_count++;
- res = create_fluid(dev,
- stardis->descriptions[i].d.fluid.name,
- stardis->descriptions[i].d.fluid.rho,
- stardis->descriptions[i].d.fluid.cp,
- (mode & GREEN_MODE),
- 0,
- stardis->descriptions[i].d.fluid.Tinit,
- stardis->descriptions[i].d.fluid.Temp,
- &media,
- &desc->d.fluid.fluid_id);
- if (res != RES_OK) goto error;
-
- break;
- default: FATAL("Invalid type.\n");
- }
+ res = create_holder(&counts, &dummies, stardis->descriptions + i,
+ dev, &media, mode & GREEN_MODE);
+ if (res != RES_OK) goto error;
}
/* Create interfaces */
htable_intface_init(&stardis->allocator, &htable_interfaces);
htable_interfaces_initialised = 1;
for (i = 0; i < sa_size(stardis->geometry.triangle); ++i) {
- struct triangle *trg = stardis->geometry.triangle + i;
- struct int_descs int_descs = INT_DESCS_NULL;
- struct sdis_interface** p_intface;
- struct sdis_interface* intface;
- struct sdis_medium* front_med = NULL;
- struct sdis_medium* back_med = NULL;
- struct sdis_interface_side_shader* fluid_side_shader = NULL;
- unsigned fd = trg->front_description;
- unsigned bd = trg->back_description;
- unsigned cd = trg->connection_description;
- int fluid_count = 0, solid_count = 0;
- int solid_fluid_connection_count = 0, connection_count = 0, boundary_count = 0;
-
- /* Create key */
- int_descs.front = fd;
- int_descs.back = bd;
- int_descs.connect = trg->connection_description;
-
- /* Search if interface already exists, or create it */
- p_intface = htable_intface_find(&htable_interfaces, &int_descs);
- if (p_intface) {
- intface = *p_intface;
- } else {
- /* create new interface and register */
- struct sdis_interface_shader interface_shader = SDIS_INTERFACE_SHADER_NULL;
- struct intface* interface_props = NULL;
- unsigned id;
- int front_defined = (fd != UINT_MAX);
- int back_defined = (bd != UINT_MAX);
- int connect_defined = (cd != UINT_MAX);
-
- SDIS(data_create(dev, sizeof(struct intface), ALIGNOF(struct intface),
- release_interface_data, &data));
- interface_props = sdis_data_get(data);
- interface_props->temperature = NULL;
- interface_props->flux = NULL;
- interface_props->front_boundary_id = UINT_MAX;
- interface_props->back_boundary_id = UINT_MAX;
-
- if (front_defined) {
- switch (stardis->descriptions[fd].type) {
- case DESC_MAT_SOLID:
- id = stardis->descriptions[fd].d.solid.solid_id;
- solid_count++;
- front_med = media[id];
- break;
- case DESC_MAT_FLUID:
- fluid_count++;
- id = stardis->descriptions[fd].d.fluid.fluid_id;
- front_med = media[id];
- fluid_side_shader = &interface_shader.front;
- break;
- default: FATAL("Invalid type.\n");
- }
- }
- if (back_defined) {
- switch (stardis->descriptions[bd].type) {
- case DESC_MAT_SOLID:
- id = stardis->descriptions[bd].d.solid.solid_id;
- solid_count++;
- back_med = media[id];
- break;
- case DESC_MAT_FLUID:
- fluid_count++;
- id = stardis->descriptions[bd].d.fluid.fluid_id;
- back_med = media[id];
- fluid_side_shader = &interface_shader.back;
- break;
- default: FATAL("Invalid type.\n");
- }
- }
- if (connect_defined) {
- const struct description* connect = stardis->descriptions + cd;
- int type_checked = 0;
- struct sdis_medium* def_medium = NULL;
- unsigned ext_id;
- if (connect->type == DESC_SOLID_FLUID_CONNECT) {
- if (solid_count != 1 || fluid_count != 1) {
- ASSERT(front_defined && back_defined);
- fprintf(stderr,
- "Can only define a DESC_SOLID_FLUID_CONNECT between a fluid and a solid\n");
- res = RES_BAD_ARG;
- goto error;
- }
- } else {
- if (front_defined == back_defined) {
- fprintf(stderr,
- "Cannot define a boundary between 2 %s regions\n",
- front_defined ? "defined" : "undefined");
- res = RES_BAD_ARG;
- goto error;
- }
- def_medium = front_defined ? front_med : back_med;
- if (front_defined)
- interface_props->front_boundary_id = cd;
- else interface_props->back_boundary_id = cd;
- }
- switch (connect->type) {
- case DESC_BOUND_H_FOR_FLUID:
- if (sdis_medium_get_type(def_medium) != SDIS_FLUID) {
- fprintf(stderr,
- "Can only define a DESC_BOUND_H_FOR_FLUID boundary for a fluid region\n");
- res = RES_BAD_ARG;
- goto error;
- }
- type_checked = 1;
- /* fall through */
- case DESC_BOUND_H_FOR_SOLID:
- if (!type_checked
- && sdis_medium_get_type(def_medium) != SDIS_SOLID) {
- fprintf(stderr,
- "Can only define a DESC_BOUND_H_FOR_SOLID boundary for a solid region\n");
- res = RES_BAD_ARG;
- goto error;
- }
- ext_id = connect->d.h_boundary.mat_id; /* External material id */
- ASSERT(ext_id < sa_size(media));
- ASSERT(sdis_medium_get_type(media[ext_id]) ==
- (connect->type == DESC_BOUND_H_FOR_SOLID ? SDIS_FLUID : SDIS_SOLID));
- connection_count++;
- boundary_count++;
- if (front_defined) back_med = media[ext_id];
- else front_med = media[ext_id];
- interface_shader.convection_coef = interface_get_convection_coef;
- interface_shader.convection_coef_upper_bound = connect->d.h_boundary.hc_max;
- interface_props->hc = connect->d.h_boundary.hc;
- ASSERT(!fluid_side_shader); /* Cause defined medium is solid */
- if (connect->d.h_boundary.has_emissivity) {
- fluid_side_shader =
- front_defined ? &interface_shader.back : &interface_shader.front;
- fluid_side_shader->emissivity = interface_get_emissivity;
- interface_props->emissivity = connect->d.h_boundary.emissivity;
- interface_props->alpha = connect->d.h_boundary.specular_fraction;
- }
- break;
- case DESC_BOUND_T_FOR_FLUID:
- if (sdis_medium_get_type(def_medium) != SDIS_FLUID) {
- fprintf(stderr,
- "Can only define a DESC_BOUND_T_FOR_FLUID boundary for a fluid region\n");
- res = RES_BAD_ARG;
- goto error;
- }
- type_checked = 1;
- /* fall through */
- case DESC_BOUND_T_FOR_SOLID:
- if (!type_checked
- && sdis_medium_get_type(def_medium) != SDIS_SOLID) {
- fprintf(stderr,
- "Can only define a DESC_BOUND_T_FOR_SOLID boundary for a solid region\n");
- res = RES_BAD_ARG;
- goto error;
- }
- ext_id = connect->d.t_boundary.mat_id; /* External material id */
- ASSERT(ext_id < sa_size(media));
- ASSERT(sdis_medium_get_type(media[ext_id]) == SDIS_FLUID);
- connection_count++;
- boundary_count++;
- if (front_defined) {
- back_med = media[ext_id];
- /* We set the known T inside
- * TODO: should be outside to allow contact resistances */
- interface_shader.front.temperature = interface_get_temperature;
- } else {
- front_med = media[ext_id];
- /* We set the known T inside
- * TODO: should be outside to allow contact resistances */
- interface_shader.back.temperature = interface_get_temperature;
- }
- ASSERT(connect->d.t_boundary.te_temperature);
- interface_props->temperature
- = te_duplicate(connect->d.t_boundary.te_temperature);
- if (connect->d.t_boundary.has_hc) {
- ASSERT(connect->type == DESC_BOUND_T_FOR_FLUID);
- interface_shader.convection_coef = interface_get_convection_coef;
- interface_shader.convection_coef_upper_bound = connect->d.t_boundary.hc_max;
- interface_props->hc = connect->d.t_boundary.hc;
- }
- break;
- case DESC_BOUND_F_FOR_SOLID:
- if (sdis_medium_get_type(def_medium) != SDIS_SOLID) {
- fprintf(stderr,
- "Can only define a DESC_BOUND_F_FOR_SOLID boundary for a solid region\n");
- res = RES_BAD_ARG;
- goto error;
- }
- connection_count++;
- boundary_count++;
- if (front_defined) {
- back_med = media[connect->d.f_boundary.mat_id];
- interface_shader.front.flux = interface_get_flux;
- } else {
- front_med = media[connect->d.f_boundary.mat_id];
- interface_shader.back.flux = interface_get_flux;
- }
- ASSERT(connect->d.f_boundary.te_flux);
- interface_props->flux = te_duplicate(connect->d.f_boundary.te_flux);
- break;
- case DESC_SOLID_FLUID_CONNECT:
- /* Both front and back should be defined;
- * if not will raise an error below */
- connection_count++;
- solid_fluid_connection_count++;
- ASSERT(fluid_side_shader);
- if (connect->d.sf_connect.has_hc) {
- interface_shader.convection_coef = interface_get_convection_coef;
- interface_shader.convection_coef_upper_bound = connect->d.sf_connect.hc_max;
- interface_props->hc = connect->d.sf_connect.hc;
- }
- if (connect->d.sf_connect.has_emissivity) {
- fluid_side_shader->emissivity = interface_get_emissivity;
- interface_props->emissivity = connect->d.sf_connect.emissivity;
- interface_props->alpha = connect->d.sf_connect.specular_fraction;
- }
- break;
- default: FATAL("Invalid type.\n");
- }
- }
-
- if ((fluid_count == 2)
- || (fluid_count + solid_count + connection_count < 2)
- || (boundary_count ?
- (fluid_count + solid_count != 1) : (fluid_count + solid_count != 2))
- || (solid_fluid_connection_count && (fluid_count != 1 || solid_count != 1)))
- {
- /* Incoherent triangle description */
- fprintf(stderr, "Incoherent triangle description (%u)\n", i);
- print_trg_as_obj(stderr, stardis->geometry.vertex, trg->indices.data);
- fprintf(stderr, "Front: ");
- if (!front_defined) fprintf(stderr, "undefined\n");
- else print_description(stderr, &stardis->descriptions[fd]);
- fprintf(stderr, "Back: ");
- if (!back_defined) fprintf(stderr, "undefined\n");
- else print_description(stderr, &stardis->descriptions[bd]);
- fprintf(stderr, "Connection: ");
- if (!connect_defined) fprintf(stderr, "undefined\n");
- else print_description(stderr, &stardis->descriptions[cd]);
- res = RES_BAD_ARG;
- goto error;
- }
-
- res = sdis_interface_create(dev, front_med, back_med,
- &interface_shader, data, &intface);
- SDIS(data_ref_put(data)); data = NULL;
- if (res != RES_OK) {
- fprintf(stderr,
- "Cannot create interface associated to triangle %u\n", i);
- goto error;
- }
- sa_push(interfaces, intface);
- res = htable_intface_set(&htable_interfaces, &int_descs, &intface);
- if (res != RES_OK) goto error;
- }
- sa_push(interf_bytrg, intface);
+ res = create_intface(dev, i, &htable_interfaces, &stardis->geometry,
+ stardis->descriptions, media);
+ if (res != RES_OK) goto error;
}
- stardis->geometry.interf_bytrg = interf_bytrg;
- stardis->geometry.interfaces = interfaces;
+ /* Create scene */
res = sdis_scene_create(dev,
sa_size(stardis->geometry.triangle),
geometry_get_indices, geometry_get_interface,
@@ -1584,408 +736,31 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
geometry_get_position, &stardis->geometry, &scn);
if (res != RES_OK) goto error;
+ /* If the scene has holes dump them */
res = create_edge_file_if(scn, &stardis->allocator);
if (res != RES_OK) goto error;
- if (mode & GREEN_MODE) {
- struct sdis_green_function* green = NULL;
- size_t ok_count, failed_count;
- struct w_ctx w_ctx;
- ASSERT((mode & PROBE_COMPUTE) || (mode & PROBE_COMPUTE_ON_INTERFACE)
- || (mode & BOUNDARY_COMPUTE) || (mode & MEDIUM_COMPUTE));
-
- if (mode & PROBE_COMPUTE || mode & PROBE_COMPUTE_ON_INTERFACE) {
- 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];
-
- res = select_probe_type(scn,
- stardis->geometry.triangle,
- stardis->geometry.vertex,
- stardis->descriptions,
- (mode & PROBE_COMPUTE_ON_INTERFACE),
- pos,
- &iprim,
- uv);
- if (res != RES_OK) goto error;
-
- if (iprim == SIZE_MAX) {
- res = sdis_solve_probe_green_function(scn,
- stardis->N,
- pos,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- &green);
- } else {
- res = sdis_solve_probe_boundary_green_function(scn,
- stardis->N,
- iprim,
- uv,
- SDIS_FRONT,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- &green);
- }
- }
- else if (mode & BOUNDARY_COMPUTE) {
- ASSERT(sa_size(stardis->boundary.primitives)
- == sa_size(stardis->boundary.sides));
- if (sa_size(stardis->boundary.sides) == 0) {
- fprintf(stderr, "Cannot solve boundary %s (empty geometry)\n",
- stardis->solve_name);
- }
-
- res = sdis_solve_boundary_green_function(scn,
- stardis->N,
- stardis->boundary.primitives,
- stardis->boundary.sides,
- sa_size(stardis->boundary.sides),
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- &green);
- }
- 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->solve_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->solve_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->solve_name);
- res = RES_BAD_ARG;
- goto error;
- }
- res = sdis_solve_medium_green_function(scn,
- stardis->N,
- medium,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- &green);
- }
- if (res != RES_OK) goto error;
-
- /* Output the green function */
- CHK(sdis_green_function_get_invalid_paths_count(green, &failed_count) == RES_OK);
- CHK(sdis_green_function_get_paths_count(green, &ok_count) == RES_OK);
-
- /* Output counts */
- printf("---BEGIN GREEN---\n");
- printf("# #solids #fluids #t_boundaries #h_boundaries #f_boundaries #ok #failures\n");
- printf("%zu %zu %zu %zu %zu %zu %zu\n",
- smed_count, fmed_count,
- tbound_count, hbound_count, fbound_count,
- ok_count, failed_count);
-
- /* List Media */
- if (smed_count) {
- printf("# Solids\n");
- printf("# ID Name lambda rho cp power\n");
- FOR_EACH(i, 0, (unsigned)sa_size(stardis->descriptions)) {
- struct description* desc = stardis->descriptions + i;
- struct mat_solid* sl;
- if (desc->type != DESC_MAT_SOLID) continue;
- sl = &desc->d.solid;
- printf("%u\t%s\t%g\t%g\t%g\t%s\n",
- i, sl->name, sl->lambda, sl->rho, sl->cp, (sl->has_power ? sl->power : "0"));
- }
- }
- if (fmed_count) {
- printf("# Fluids\n");
- printf("# ID Name rho cp\n");
- FOR_EACH(i, 0, sa_size(stardis->descriptions)) {
- struct description* desc = stardis->descriptions + i;
- struct mat_fluid* fl;
- fl = &desc->d.fluid;
- printf("%u\t%s\t%g\t%g\n", i, fl->name, fl->rho, fl->cp);
- }
- }
-
- /* List Boundaries */
- if (tbound_count) {
- printf("# T Boundaries\n");
- printf("# ID Name temperature\n");
- FOR_EACH(i, 0, sa_size(stardis->descriptions)) {
- struct description* desc = stardis->descriptions + i;
- struct t_boundary* bd;
- if (desc->type != DESC_BOUND_T_FOR_SOLID
- && desc->type != DESC_BOUND_T_FOR_FLUID) continue;
- bd = &desc->d.t_boundary;
- printf("%u\t%s\t%s\n", i, bd->name, bd->T);
- }
- }
- if (hbound_count) {
- printf("# H Boundaries\n");
- printf("# ID Name emissivity specular_fraction hc hc_max T_env\n");
- FOR_EACH(i, 0, sa_size(stardis->descriptions)) {
- struct description* desc = stardis->descriptions + i;
- struct h_boundary* bd;
- if (desc->type != DESC_BOUND_H_FOR_SOLID
- && desc->type != DESC_BOUND_H_FOR_FLUID) continue;
- bd = &desc->d.h_boundary;
- printf("%u\t%s\t%g\t%g\t%g\t%g\t%s\n",
- i, bd->name, (bd->has_emissivity ? bd->emissivity : 0),
- (bd->has_emissivity ? bd->specular_fraction : 0),
- (bd->has_hc ? bd->hc : 0), (bd->has_hc ? bd->hc_max : 0), bd->T);
- }
- }
- if (fbound_count) {
- printf("# F Boundaries\n");
- printf("# ID Name flux\n");
- FOR_EACH(i, 0, sa_size(stardis->descriptions)) {
- struct description* desc = stardis->descriptions + i;
- struct f_boundary* bd;
- if (desc->type != DESC_BOUND_F_FOR_SOLID) continue;
- bd = &desc->d.f_boundary;
- printf("%u\t%s\t%s\n",
- i, bd->name, bd->flux);
- }
- }
-
- /* Radiative Temperatures */
- printf("# Radiative Temperatures\n");
- printf("# ID Rad_Temp Lin_Temp\n");
- printf("%u\t%g\t%g\n", (unsigned)sa_size(stardis->descriptions),
- stardis->radiative_temp[0], stardis->radiative_temp[1]);
-
- printf("# Samples\n");
- printf("# end #power_terms #flux_terms power_term_1 ... power_term_n flux_term_1 ... flux_term_n\n");
- printf("# end = end_type end_id; end_type = T | H | X | R | F | S\n");
- printf("# power_term_i = power_type_i power_id_i factor_i\n");
- printf("# flux_term_i = flux_id_i factor_i\n");
-
- w_ctx.desc = stardis->descriptions;
- htable_weigth_init(NULL, &w_ctx.weigths);
-
- res = sdis_green_function_for_each_path(green, print_sample, &w_ctx);
- htable_weigth_release(&w_ctx.weigths);
- if (res != RES_OK) goto error;
-
-
- printf("---END GREEN---\n");
-
- CHK(sdis_green_function_ref_put(green) == RES_OK);
- } else {
- if (mode & IR_COMPUTE) {
- size_t width = (size_t)stardis->camera.img[0];
- size_t height = (size_t)stardis->camera.img[1];
-
- /* Setup the camera */
- SDIS(camera_create(dev, &cam));
- SDIS(camera_set_proj_ratio(cam, (double)width / (double)height));
- SDIS(camera_set_fov(cam, MDEG2RAD(stardis->camera.fov)));
- SDIS(camera_look_at(cam,
- stardis->camera.pos,
- stardis->camera.tgt,
- stardis->camera.up));
-
- /* Launch the simulation */
- time[0] = time[1] = stardis->camera.u.time;
- res = sdis_solve_camera(scn,
- cam,
- time,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- width,
- height,
- (size_t)stardis->camera.spp,
- stardis->dump_paths,
- &buf);
- if (res != RES_OK) goto error;
-
- /* Write the image */
- dump_image(buf);
- }
- else if (mode & PROBE_COMPUTE || mode & PROBE_COMPUTE_ON_INTERFACE) {
- 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];
-
- res = select_probe_type(scn,
- stardis->geometry.triangle,
- stardis->geometry.vertex,
- stardis->descriptions,
- (mode & PROBE_COMPUTE_ON_INTERFACE),
- pos,
- &iprim,
- uv);
- if (res != RES_OK) goto error;
-
- if (iprim == SIZE_MAX) {
- res = sdis_solve_probe(scn,
- stardis->N,
- pos,
- time,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- stardis->dump_paths,
- &estimator);
- } else {
- res = 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);
- }
- }
- 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->solve_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->solve_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->solve_name);
- res = RES_BAD_ARG;
- goto error;
- }
- time[0] = time[1] = stardis->probe[3];
- res = sdis_solve_medium(scn,
- stardis->N,
- medium,
- time,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- stardis->dump_paths,
- &estimator);
- }
- else if (mode & BOUNDARY_COMPUTE) {
- ASSERT(sa_size(stardis->boundary.primitives)
- == sa_size(stardis->boundary.sides));
- if (sa_size(stardis->boundary.sides) == 0) {
- fprintf(stderr, "Cannot solve boundary %s (empty geometry)\n",
- stardis->solve_name);
- }
-
- time[0] = time[1] = stardis->probe[3];
- res = sdis_solve_boundary(scn,
- stardis->N,
- stardis->boundary.primitives,
- stardis->boundary.sides,
- sa_size(stardis->boundary.sides),
- time,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- stardis->dump_paths,
- &estimator);
- } else {
- CHK(0);
- }
- if (res != RES_OK) goto error;
- if (mode & PROBE_COMPUTE
- || mode & PROBE_COMPUTE_ON_INTERFACE
- || mode & MEDIUM_COMPUTE
- || mode & BOUNDARY_COMPUTE) {
- /* Fetch the estimation data */
- SDIS(estimator_get_temperature(estimator, &temperature));
- SDIS(estimator_get_failure_count(estimator, &nfailures));
-
- /* Print the results */
- switch (mode & COMPUTE_MODES) {
- case PROBE_COMPUTE:
- case PROBE_COMPUTE_ON_INTERFACE:
- printf("Temperature at t=[%g, %g, %g, %g] = %g +/- %g\n",
- pos[0], pos[1], pos[2], time[0],
- temperature.E, /* Expected value */
- temperature.SE); /* Standard error */
- break;
- case MEDIUM_COMPUTE:
- printf("Temperature in medium %s at t=%g = %g +/- %g\n",
- stardis->solve_name, time[0],
- temperature.E, /* Expected value */
- temperature.SE); /* Standard error */
- break;
- case BOUNDARY_COMPUTE:
- printf("Temperature at boundary %s at t=%g = %g +/- %g\n",
- stardis->solve_name, time[0],
- temperature.E, /* Expected value */
- temperature.SE); /* Standard error */
- break;
- default: FATAL("Invalid 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);
- }
- }
+ /* Compute */
+ if (mode & PROBE_COMPUTE)
+ res = compute_probe(scn, &counts, stardis, mode);
+ else if (mode & PROBE_COMPUTE_ON_INTERFACE)
+ res = compute_probe_on_interface(scn, &counts, stardis, mode);
+ else if (mode & IR_COMPUTE)
+ res = compute_camera(dev, scn, stardis, mode);
+ else if (mode & MEDIUM_COMPUTE)
+ res = compute_medium(scn, media, stardis, mode);
+ else if (mode & BOUNDARY_COMPUTE)
+ res = compute_boundary(scn, &counts, stardis, mode);
+ else FATAL("Unknown mode.\n");
+ if (res != RES_OK) goto error;
end:
- if (data) SDIS(data_ref_put(data));
- if (interfaces) {
- for (i = 0; i < sa_size(interfaces); ++i)
- SDIS(interface_ref_put(interfaces[i]));
- sa_release(interfaces);
- stardis->geometry.interfaces = NULL;
- }
- sa_release(interf_bytrg);
- stardis->geometry.interf_bytrg = NULL;
- if (htable_interfaces_initialised) htable_intface_release(&htable_interfaces);
+ if (htable_interfaces_initialised)
+ htable_intface_release(&htable_interfaces);
for (i = 0; i < sa_size(media); ++i)
SDIS(medium_ref_put(media[i]));
sa_release(media);
- if (cam) SDIS(camera_ref_put(cam));
- if (buf) SDIS(estimator_buffer_ref_put(buf));
- if (estimator) SDIS(estimator_ref_put(estimator));
if (scn) SDIS(scene_ref_put(scn));
if (dev) SDIS(device_ref_put(dev));