stardis

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

commit 63e1e0c93742a5fe42569effbfe6ae31688af049
parent 61353d3a1e907aa5e81a35b8fb7fc49924b7d38d
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Sun,  2 Jan 2022 20:15:34 +0100

Add other programmable descriptions

Need more tests

Split some huge files, need to do more on this

Diffstat:
Mcmake/CMakeLists.txt | 20+++++++++++++++++---
Msrc/stardis-app.c | 13++++++++++---
Msrc/stardis-app.h | 526+------------------------------------------------------------------------------
Msrc/stardis-args.h | 12++++++------
Msrc/stardis-compute.c | 100++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/stardis-compute.h | 7+++----
Asrc/stardis-description.c | 520+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-description.h | 256+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fbound-prog.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-fbound-prog.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-fluid-prog.c | 58++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/stardis-fluid-prog.h | 40+++++++++++++++++++++++++---------------
Msrc/stardis-fluid.h | 6+++---
Asrc/stardis-hbound-prog.c | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-hbound-prog.h | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-intface.c | 278++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/stardis-intface.h | 13+++++++++++--
Msrc/stardis-output.c | 14+++++++-------
Msrc/stardis-output.h | 32++++++++++++++++----------------
Msrc/stardis-parsing.c | 1051+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/stardis-parsing.h | 19+++++--------------
Msrc/stardis-prog.h | 21+++++++++++++++++----
Asrc/stardis-sfconnect-prog.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-sfconnect-prog.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-solid-prog.c | 181+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-solid-prog.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-solid.h | 8++++----
Asrc/stardis-ssconnect-prog.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-ssconnect-prog.h | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-tbound-prog.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-tbound-prog.h | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31 files changed, 3327 insertions(+), 762 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -121,13 +121,20 @@ set(SDIS_FILES_SRC stardis-app.c stardis-args.c stardis-compute.c + stardis-description.c stardis-fluid.c + stardis-fluid-prog.c + stardis-fbound-prog.c + stardis-hbound-prog.c stardis-intface.c stardis-main.c stardis-output.c stardis-parsing.c - stardis-fluid-prog.c - stardis-solid.c) + stardis-sfconnect-prog.c + stardis-ssconnect-prog.c + stardis-solid.c + stardis-solid-prog.c + stardis-tbound-prog.c) set(SDIS_FILES_INC_API stardis-prog.h) @@ -136,13 +143,20 @@ set(SDIS_FILES_INC stardis-app.h stardis-args.h stardis-compute.h + stardis-description.h stardis-default.h.in stardis-fluid.h + stardis-fluid-prog.h + stardis-fbound-prog.h + stardis-hbound-prog.h stardis-intface.h stardis-output.h stardis-parsing.h - stardis-fluid-prog.h + stardis-sfconnect-prog.h + stardis-ssconnect-prog.h stardis-solid.h + stardis-solid-prog.h + stardis-tbound-prog.h stardis-version.h.in) set(SDIS_FILES_DOC COPYING README.md) diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -14,6 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "stardis-app.h" +#include "stardis-description.h" #include "stardis-output.h" #include "stardis-compute.h" #include "stardis-intface.h" @@ -494,9 +495,9 @@ error: if(properties[(Rank)] == SG3D_UNSPECIFIED_PROPERTY) undef_count++;\ else {\ ASSERT(properties[(Rank)] < darray_descriptions_size_get(&stardis->descriptions));\ - ASSERT(DESC_IS_MEDIUM(descs[properties[(Rank)]].type));\ - if(descs[properties[(Rank)]].type == DESC_MAT_SOLID) solid_count++;\ - else fluid_count++;\ + ASSERT(DESC_IS_MEDIUM(descs+properties[(Rank)]));\ + if(DESC_IS_SOLID(descs+properties[(Rank)])) { solid_count++; }\ + else { ASSERT(DESC_IS_FLUID(descs+properties[(Rank)])); fluid_count++; }\ }\ } @@ -533,6 +534,7 @@ validate_properties intface = descs + properties[SG3D_INTFACE]; switch (intface->type) { case DESC_BOUND_H_FOR_FLUID: + case DESC_BOUND_H_FOR_FLUID_PROG: if(!(solid_count == 0 && fluid_count == 1)) { if(solid_count + fluid_count == 2) *properties_conflict_status = BOUND_H_FOR_FLUID_BETWEEN_2_DEFS; @@ -545,6 +547,7 @@ validate_properties } break; case DESC_BOUND_H_FOR_SOLID: + case DESC_BOUND_H_FOR_SOLID_PROG: if(!(solid_count == 1 && fluid_count == 0)) { if(solid_count + fluid_count == 2) *properties_conflict_status = BOUND_H_FOR_SOLID_BETWEEN_2_DEFS; @@ -557,6 +560,7 @@ validate_properties } break; case DESC_BOUND_T_FOR_SOLID: + case DESC_BOUND_T_FOR_SOLID_PROG: if(!(solid_count == 1 && fluid_count == 0)) { if(solid_count + fluid_count == 2) *properties_conflict_status = BOUND_T_FOR_SOLID_BETWEEN_2_DEFS; @@ -569,6 +573,7 @@ validate_properties } break; case DESC_BOUND_F_FOR_SOLID: + case DESC_BOUND_F_FOR_SOLID_PROG: if(!(solid_count == 1 && fluid_count == 0)) { if(solid_count + fluid_count == 2) *properties_conflict_status = BOUND_F_FOR_SOLID_BETWEEN_2_DEFS; @@ -581,6 +586,7 @@ validate_properties } break; case DESC_SOLID_FLUID_CONNECT: + case DESC_SOLID_FLUID_CONNECT_PROG: if(solid_count != 1 || fluid_count != 1) { if(solid_count == 2) *properties_conflict_status = SFCONNECT_BETWEEN_2_SOLIDS; @@ -595,6 +601,7 @@ validate_properties } break; case DESC_SOLID_SOLID_CONNECT: + case DESC_SOLID_SOLID_CONNECT_PROG: if(solid_count != 2) { /*if(soli_count == 1 && fluid_count == 1)*/ /**properties_conflict_status = SSCONNECT_BETWEEN_SOLID_AND_FLUID;*/ diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -17,6 +17,7 @@ #define STARDIS_APP_H #include "stardis-args.h" +#include "stardis-description.h" #include "stardis-parsing.h" #include "stardis-default.h" #include "stardis-solid.h" @@ -95,38 +96,6 @@ enum properties_conflict_t { PROPERTIES_CONFLICT_COUNT__ }; -/* Different types of descriptions */ -enum description_type { - DESC_MAT_SOLID, - DESC_MAT_FLUID, - DESC_MAT_FLUID_PROG, - DESC_BOUND_H_FOR_FLUID, - DESC_BOUND_H_FOR_SOLID, - DESC_BOUND_T_FOR_SOLID, - DESC_BOUND_F_FOR_SOLID, - DESC_SOLID_FLUID_CONNECT, - DESC_SOLID_SOLID_CONNECT, - DESCRIPTION_TYPE_COUNT__, - DESC_OUTSIDE -}; - -#define DESC_IS_H(D) \ - ((D) == DESC_BOUND_H_FOR_SOLID || (D) == DESC_BOUND_H_FOR_FLUID) -#define DESC_IS_T(D) \ - ((D) == DESC_BOUND_T_FOR_SOLID) -#define DESC_IS_F(D) \ - ((D) == DESC_BOUND_F_FOR_SOLID) -#define DESC_IS_SOLID(D) \ - ((D) == DESC_MAT_SOLID) -#define DESC_IS_FLUID(D) \ - ((D) == DESC_MAT_FLUID || (D) == DESC_MAT_FLUID_PROG) -#define DESC_IS_MEDIUM(D) \ - (DESC_IS_SOLID(D) || DESC_IS_FLUID(D)) -#define DESC_IS_BOUNDARY(D) \ - (DESC_IS_H(D) || DESC_IS_T(D) || DESC_IS_F(D)) -#define DESC_IS_PROG(D) \ - ((D) == DESC_MAT_FLUID_PROG) - #define DARRAY_NAME interface_ptrs #define DARRAY_DATA struct sdis_interface* #include <rsys/dynamic_array.h> @@ -204,491 +173,6 @@ error: } /******************************************************************************/ - -struct fluid; -struct fluid_prog; -struct solid; -struct t_boundary; -struct f_boundary; -struct h_boundary; -struct solid_fluid_connect; -struct solid_solid_connect; - -struct description { - enum description_type type; - union { - struct fluid* fluid; - struct fluid_prog* fluid_prog; - struct solid* solid; - struct t_boundary* t_boundary; - struct f_boundary* f_boundary; - struct h_boundary* h_boundary; - struct solid_fluid_connect* sf_connect; - struct solid_solid_connect* ss_connect; - } d; -}; - -/******************************************************************************/ - -struct h_boundary { - struct str name; - double ref_temperature; - double emissivity; - double specular_fraction; - double hc; - double imposed_temperature; - unsigned mat_id; - struct fluid* possible_external_fluid; /* if H for solid */ -}; - -static FINLINE res_T -init_h - (struct mem_allocator* allocator, - struct h_boundary** dst) -{ - res_T res = RES_OK; - int str_initialized = 0; - ASSERT(allocator && dst && *dst == NULL); - *dst = MEM_ALLOC(allocator, sizeof(struct h_boundary)); - if(! *dst) { - res = RES_MEM_ERR; - goto error; - } - str_init(allocator, &(*dst)->name); - (*dst)->ref_temperature = 0; - (*dst)->emissivity = 0; - (*dst)->specular_fraction = 0; - (*dst)->hc = 0; - (*dst)->imposed_temperature = -1; - (*dst)->mat_id = UINT_MAX; - (*dst)->possible_external_fluid = NULL; -end: - return res; -error: - if(str_initialized) str_release(&(*dst)->name); - if(*dst) MEM_RM(allocator, *dst); - goto end; -} - -static FINLINE void -release_h_boundary - (struct h_boundary* bound, - struct mem_allocator* allocator) -{ - ASSERT(bound && allocator); - str_release(&bound->name); - if(bound->possible_external_fluid) { - release_fluid(bound->possible_external_fluid, allocator); - } - MEM_RM(allocator, bound); -} - -static res_T -str_print_h_boundary - (struct str* str, - const struct h_boundary* b, - const enum description_type type) -{ - res_T res = RES_OK; - ASSERT(str && b && DESC_IS_H(type)); - STR_APPEND_PRINTF(str, - "H boundary for %s '%s': ref_temperature=%g emissivity=%g specular_fraction=%g " - "hc=%g T=%g (using medium %u as external medium)", - ARG8( (type == DESC_BOUND_H_FOR_SOLID ? "solid" : "fluid"), str_cget(&b->name), - b->ref_temperature, b->emissivity, b->specular_fraction, b->hc, - b->imposed_temperature, b->mat_id ) ); -end: - return res; -error: - goto end; -} - -struct t_boundary { - struct str name; - double imposed_temperature; - unsigned mat_id; -}; - -static FINLINE res_T -init_t - (struct mem_allocator* allocator, - struct t_boundary** dst) -{ - res_T res = RES_OK; - int str_initialized = 0; - ASSERT(allocator && dst && *dst == NULL); - *dst = MEM_ALLOC(allocator, sizeof(struct t_boundary)); - if(! *dst) { - res = RES_MEM_ERR; - goto error; - } - str_init(allocator, &(*dst)->name); - (*dst)->imposed_temperature = -1; - (*dst)->mat_id = UINT_MAX; -end: - return res; -error: - if(str_initialized) str_release(&(*dst)->name); - if(*dst) MEM_RM(allocator, *dst); - goto end; -} - -static FINLINE void -release_t_boundary - (struct t_boundary* bound, - struct mem_allocator* allocator) -{ - ASSERT(bound && allocator); - str_release(&bound->name); - MEM_RM(allocator, bound); -} - -static res_T -str_print_t_boundary - (struct str* str, - const struct t_boundary* b) -{ - res_T res = RES_OK; - ASSERT(str && b); - STR_APPEND_PRINTF(str, "T boundary for solid '%s': T=%g ", - ARG2( str_cget(&b->name), b->imposed_temperature ) ); - - STR_APPEND_PRINTF(str, "(using medium %u as external medium)", - ARG1( b->mat_id ) ); -end: - return res; -error: - goto end; -} - -struct f_boundary { - struct str name; - double imposed_flux; - unsigned mat_id; -}; - -static FINLINE res_T -init_f - (struct mem_allocator* allocator, - struct f_boundary** dst) -{ - res_T res = RES_OK; - int str_initialized = 0; - ASSERT(allocator && dst && *dst == NULL); - *dst = MEM_ALLOC(allocator, sizeof(struct f_boundary)); - if(! *dst) { - res = RES_MEM_ERR; - goto error; - } - str_init(allocator, &(*dst)->name); - (*dst)->mat_id = UINT_MAX; - (*dst)->imposed_flux = -1; -end: - return res; -error: - if(str_initialized) str_release(&(*dst)->name); - if(*dst) MEM_RM(allocator, *dst); - goto end; -} - -static FINLINE void -release_f_boundary - (struct f_boundary* bound, - struct mem_allocator* allocator) -{ - ASSERT(bound && allocator); - str_release(&bound->name); - MEM_RM(allocator, bound); -} - -static res_T -str_print_f_boundary - (struct str* str, - const struct f_boundary* b) -{ - res_T res = RES_OK; - ASSERT(str && b); - STR_APPEND_PRINTF(str, - "F boundary for SOLID '%s': flux=%g (using medium %u as external medium)", - ARG3( str_cget(&b->name), b->imposed_flux, b->mat_id ) ); -end: - return res; -error: - goto end; -} - -struct solid_fluid_connect { - struct str name; - double ref_temperature; - double emissivity; - double specular_fraction; - double hc; - unsigned connection_id; -}; - -static FINLINE void -release_sf_connect - (struct solid_fluid_connect* connect, - struct mem_allocator* allocator) -{ - ASSERT(connect && allocator); - str_release(&connect->name); - MEM_RM(allocator, connect); -} - -static FINLINE res_T -init_sf - (struct mem_allocator* allocator, - struct solid_fluid_connect** dst) -{ - res_T res = RES_OK; - int str_initialized = 0; - ASSERT(allocator && dst && *dst == NULL); - *dst = MEM_ALLOC(allocator, sizeof(struct solid_fluid_connect)); - if(! *dst) { - res = RES_MEM_ERR; - goto error; - } - str_init(allocator, &(*dst)->name); - (*dst)->ref_temperature = 0; - (*dst)->emissivity = 0; - (*dst)->specular_fraction = 0; - (*dst)->hc = 0; - (*dst)->connection_id = UINT_MAX; -end: - return res; -error: - if(str_initialized) str_release(&(*dst)->name); - if(*dst) MEM_RM(allocator, *dst); - goto end; -} - -static res_T -str_print_sf_connect - (struct str* str, - const struct solid_fluid_connect* c) -{ - res_T res = RES_OK; - ASSERT(str && c); - STR_APPEND_PRINTF(str, "Solid-Fluid connection '%s': ", ARG1( str_cget(&c->name) ) ); - STR_APPEND_PRINTF(str, "ref_temperature=%g emissivity=%g, specular_fraction=%g hc=%g", - ARG4( c->ref_temperature, c->emissivity, c->specular_fraction, c->hc ) ); -end: - return res; -error: - goto end; -} - -struct solid_solid_connect { - struct str name; - double tcr; - unsigned connection_id; -}; - -static FINLINE void -release_ss_connect - (struct solid_solid_connect* connect, - struct mem_allocator* allocator) -{ - ASSERT(connect && allocator); - str_release(&connect->name); - MEM_RM(allocator, connect); -} - -static FINLINE res_T -init_ss - (struct mem_allocator* allocator, - struct solid_solid_connect** dst) -{ - res_T res = RES_OK; - int str_initialized = 0; - ASSERT(allocator && dst && *dst == NULL); - *dst = MEM_ALLOC(allocator, sizeof(struct solid_solid_connect)); - if(! *dst) { - res = RES_MEM_ERR; - goto error; - } - str_init(allocator, &(*dst)->name); - (*dst)->tcr = 0; - (*dst)->connection_id = UINT_MAX; -end: - return res; -error: - if(str_initialized) str_release(&(*dst)->name); - if(*dst) MEM_RM(allocator, *dst); - goto end; -} - -static res_T -str_print_ss_connect - (struct str* str, - const struct solid_solid_connect* c) -{ - res_T res = RES_OK; - ASSERT(str && c); - STR_APPEND_PRINTF(str, "Solid-Solid connection '%s': ", ARG1( str_cget(&c->name) ) ); - STR_APPEND_PRINTF(str, "contact resistance=%g", ARG1( c->tcr ) ); -end: - return res; -error: - goto end; -} - -static FINLINE res_T -init_description - (struct mem_allocator* alloc, - struct description* desc) -{ - ASSERT(desc); - (void)alloc; - desc->type = DESCRIPTION_TYPE_COUNT__; - desc->d.fluid = NULL; - return RES_OK; -} - -static FINLINE void -release_description - (struct description* desc, - struct mem_allocator* allocator) -{ - ASSERT(desc && allocator); - switch (desc->type) { - case DESC_MAT_SOLID: - release_solid(desc->d.solid, allocator); - break; - case DESC_MAT_FLUID: - release_fluid(desc->d.fluid, allocator); - break; - case DESC_MAT_FLUID_PROG: - release_fluid_prog(desc->d.fluid_prog, allocator); - break; - case DESC_BOUND_H_FOR_SOLID: - case DESC_BOUND_H_FOR_FLUID: - release_h_boundary(desc->d.h_boundary, allocator); - break; - case DESC_BOUND_T_FOR_SOLID: - release_t_boundary(desc->d.t_boundary, allocator); - break; - case DESC_BOUND_F_FOR_SOLID: - release_f_boundary(desc->d.f_boundary, allocator); - break; - case DESC_SOLID_FLUID_CONNECT: - release_sf_connect(desc->d.sf_connect, allocator); - break; - case DESC_SOLID_SOLID_CONNECT: - release_ss_connect(desc->d.ss_connect, allocator); - break; - default: - FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); - } -} - -static INLINE res_T -str_print_description - (struct str* str, - const unsigned rank, - const struct description* desc) -{ - res_T res = RES_OK; - ASSERT(str && desc); - str_clear(str); - ERR(str_printf(str, "Description %u: ", rank)); - switch (desc->type) { - case DESC_MAT_SOLID: - ERR(str_print_solid(str, desc->d.solid)); - break; - case DESC_MAT_FLUID: - ERR(str_print_fluid(str, desc->d.fluid)); - break; - case DESC_MAT_FLUID_PROG: - ERR(str_print_fluid_prog(str, desc->d.fluid_prog)); - break; - case DESC_BOUND_T_FOR_SOLID: - ERR(str_print_t_boundary(str, desc->d.t_boundary)); - break; - case DESC_BOUND_H_FOR_SOLID: - case DESC_BOUND_H_FOR_FLUID: - ERR(str_print_h_boundary(str, desc->d.h_boundary, desc->type)); - break; - case DESC_BOUND_F_FOR_SOLID: - ERR(str_print_f_boundary(str, desc->d.f_boundary)); - break; - case DESC_SOLID_FLUID_CONNECT: - ERR(str_print_sf_connect(str, desc->d.sf_connect)); - break; - case DESC_SOLID_SOLID_CONNECT: - ERR(str_print_ss_connect(str, desc->d.ss_connect)); - break; - default: - FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); - } -end: - return res; -error: - goto end; -} - -static INLINE const struct str* -get_description_name - (const struct description* desc) -{ - ASSERT(desc); - switch (desc->type) { - case DESC_MAT_SOLID: - return &desc->d.solid->name; - case DESC_MAT_FLUID: - return &desc->d.fluid->name; - case DESC_MAT_FLUID_PROG: - return &desc->d.fluid_prog->name; - case DESC_BOUND_T_FOR_SOLID: - return &desc->d.t_boundary->name; - case DESC_BOUND_H_FOR_SOLID: - case DESC_BOUND_H_FOR_FLUID: - return &desc->d.h_boundary->name; - case DESC_BOUND_F_FOR_SOLID: - return &desc->d.f_boundary->name; - case DESC_SOLID_FLUID_CONNECT: - return &desc->d.sf_connect->name; - case DESC_SOLID_SOLID_CONNECT: - return &desc->d.ss_connect->name; - default: - FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); - } -} - -static FINLINE void -description_get_medium_id - (const struct description* desc, - unsigned* id) -{ - ASSERT(desc && id); - switch (desc->type) { - case DESC_MAT_SOLID: - *id = desc->d.solid->solid_id; - return; - case DESC_MAT_FLUID: - *id = desc->d.fluid->fluid_id; - return; - case DESC_MAT_FLUID_PROG: - *id = desc->d.fluid_prog->fluid_id; - return; - case DESC_BOUND_H_FOR_SOLID: - case DESC_BOUND_H_FOR_FLUID: - *id = desc->d.h_boundary->mat_id; - return; - case DESC_BOUND_T_FOR_SOLID: - *id = desc->d.t_boundary->mat_id; - return; - case DESC_BOUND_F_FOR_SOLID: - *id = desc->d.f_boundary->mat_id; - return; - case DESC_SOLID_FLUID_CONNECT: /* No medium linked to SF */ - case DESC_SOLID_SOLID_CONNECT: /* No medium linked to SS */ - default: - FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); - } -} - enum stardis_output_fmt { STARDIS_RENDERING_OUTPUT_FILE_FMT_VTK, STARDIS_RENDERING_OUTPUT_FILE_FMT_HT @@ -838,22 +322,22 @@ allocate_stardis_medium_id(struct stardis* stardis) return stardis->next_medium_id++; } -extern LOCAL_SYM res_T +res_T stardis_init (const struct args* args, struct logger* logger, struct mem_allocator* allocator, struct stardis* stardis); -extern LOCAL_SYM void +void stardis_release (struct stardis* stardis); -extern LOCAL_SYM res_T +res_T init_enclosures (struct stardis* stardis); -extern LOCAL_SYM res_T +res_T validate_properties (const unsigned itri, const unsigned properties[SG3D_PROP_TYPES_COUNT__], diff --git a/src/stardis-args.h b/src/stardis-args.h @@ -106,33 +106,33 @@ struct args { int verbose; }; -extern LOCAL_SYM res_T +res_T init_args (struct logger* logger, struct mem_allocator* mem, struct args** args); -extern LOCAL_SYM void +void release_args (struct args* args); -extern void +void print_version (FILE* stream); -extern void +void short_help (FILE* stream, const char* prog); -extern res_T +res_T parse_args (const int argc, char** argv, struct args* args, struct mem_allocator* allocator); -extern res_T +res_T parse_camera (struct logger* logger, char* cam_param, diff --git a/src/stardis-compute.c b/src/stardis-compute.c @@ -14,10 +14,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "stardis-app.h" +#include "stardis-description.h" #include "stardis-output.h" #include "stardis-compute.h" #include "stardis-fluid.h" +#include "stardis-fluid-prog.h" #include "stardis-solid.h" +#include "stardis-solid-prog.h" #include <sdis.h> #include <sdis_version.h> @@ -40,7 +43,7 @@ #endif /******************************************************************************* - * Local Functions + * Local type; custom data for raytracing callbacks ******************************************************************************/ struct filter_ctx { const struct stardis* stardis; @@ -55,6 +58,10 @@ struct filter_ctx { #define FILTER_CTX_DEFAULT__ \ { NULL, S3D_INVALID_ID, NULL, { 0, 0, 0 }, FLT_MAX, 0, 0 } +/******************************************************************************* + * Local Functions + ******************************************************************************/ + /* Filter used from a point query to determine not only one of the closest * point, but the better one if there are more than one. In some circumstances * it is not possible to determine the medium we are in using a given hit, but @@ -182,6 +189,7 @@ check_probe_conform_to_type (const struct stardis* stardis, const int move2boundary, double pos[3], + double time, unsigned* iprim, double uv[2]) { @@ -245,46 +253,61 @@ check_probe_conform_to_type logger_print(stardis->logger, LOG_WARNING, "Could not determine the medium probe is in.\n"); } else { - if(DESC_IS_SOLID(filter_ctx.desc->type)) { - struct solid* solid = filter_ctx.desc->d.solid; - ASSERT(solid->delta < INF); + if(DESC_IS_SOLID(filter_ctx.desc)) { + double delta; + const char* pppp; + if(filter_ctx.desc->type == DESC_MAT_SOLID) { + struct solid* solid = filter_ctx.desc->d.solid; + delta = solid->delta; + pppp = ""; + } else { + struct solid_prog* solid_prog = filter_ctx.desc->d.solid_prog; + struct sdis_rwalk_vertex vtx; + ASSERT(filter_ctx.desc->type == DESC_MAT_SOLID_PROG); + d3_set(vtx.P, pos); + vtx.time = time; + delta = solid_prog->delta(&vtx, solid_prog->prog_data); + pppp = "programmed "; + } + ASSERT(delta < INF); logger_print(stardis->logger, LOG_OUTPUT, - "Probe was in solid '%s'.\n", str_cget(&solid->name)); - if(filter_ctx.dist > 2 * solid->delta) { + "Probe was in %ssolid '%s'.\n", + pppp, str_cget(get_description_name(filter_ctx.desc))); + if(filter_ctx.dist > 2 * delta) { logger_print(stardis->logger, LOG_ERROR, "Probe moved to (%g, %g, %g), primitive %u, uv = (%g, %g).\n", SPLIT3(filter_ctx.pos), hit.prim.prim_id, SPLIT2(hit.uv)); logger_print(stardis->logger, LOG_ERROR, "Move is %g delta long. Use -p instead of -P.\n", - filter_ctx.dist / solid->delta); + filter_ctx.dist / delta); res = RES_BAD_ARG; goto error; } - if(filter_ctx.dist > 0.5 * solid->delta) { + if(filter_ctx.dist > 0.5 * delta) { logger_print(stardis->logger, LOG_WARNING, "Probe was %g delta from closest boundary. " "Consider using -p instead of -P.\n", - filter_ctx.dist / solid->delta); + filter_ctx.dist / delta); } else { if(filter_ctx.dist != 0) logger_print(stardis->logger, LOG_OUTPUT, "Probe was %g delta from closest boundary.\n", - filter_ctx.dist / solid->delta); + filter_ctx.dist / delta); } } else { - ASSERT(DESC_IS_FLUID(filter_ctx.desc->type)); + const char* pppp; + ASSERT(DESC_IS_FLUID(filter_ctx.desc)); /* TODO: check move length wrt local geometry? */ if(filter_ctx.desc->type == DESC_MAT_FLUID) { - logger_print(stardis->logger, LOG_OUTPUT, - "Probe was in fluid '%s'.\n", - str_cget(&filter_ctx.desc->d.fluid->name)); + pppp = ""; } else { ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG); - logger_print(stardis->logger, LOG_OUTPUT, - "Probe was in programmed fluid '%s'.\n", - str_cget(&filter_ctx.desc->d.fluid_prog->name)); + pppp = "programmed "; } logger_print(stardis->logger, LOG_OUTPUT, + "Probe was in %sfluid '%s'.\n", + pppp, str_cget(get_description_name(filter_ctx.desc))); + logger_print(stardis->logger, LOG_OUTPUT, "Probe distance from closest boundary was %g.\n", filter_ctx.dist); } } @@ -337,30 +360,41 @@ check_probe_conform_to_type res = RES_BAD_ARG; goto error; } - if(DESC_IS_SOLID(filter_ctx.desc->type)) { - struct solid* solid = filter_ctx.desc->d.solid; - if(filter_ctx.dist < 0.25 * solid->delta) { + if(DESC_IS_SOLID(filter_ctx.desc)) { + double delta; + if(filter_ctx.desc->type == DESC_MAT_SOLID) { + struct solid* solid = filter_ctx.desc->d.solid; + delta = solid->delta; + } else { + struct solid_prog* solid_prog = filter_ctx.desc->d.solid_prog; + struct sdis_rwalk_vertex vtx; + ASSERT(filter_ctx.desc->type == DESC_MAT_SOLID_PROG); + d3_set(vtx.P, pos); + vtx.time = time; + delta = solid_prog->delta(&vtx, solid_prog->prog_data); + } + if(filter_ctx.dist < 0.25 * delta) { logger_print(stardis->logger, LOG_ERROR, "Probe is %g delta from closest boundary. Use -P instead of -p.\n", - filter_ctx.dist / solid->delta); + filter_ctx.dist / delta); logger_print(stardis->logger, LOG_ERROR, "Closest geometry is primitive %u, uv = (%g, %g).\n", hit.prim.prim_id, SPLIT2(hit.uv)); res = RES_BAD_ARG; goto error; } - if(filter_ctx.dist < 0.5 * solid->delta) { + if(filter_ctx.dist < 0.5 * delta) { logger_print(stardis->logger, LOG_WARNING, "Probe is %g delta from closest boundary. " "Consider using -P instead of -p.\n", - filter_ctx.dist / solid->delta); + filter_ctx.dist / delta); } else { logger_print(stardis->logger, LOG_OUTPUT, "Probe is %g delta from closest boundary.\n", - filter_ctx.dist / solid->delta); + filter_ctx.dist / delta); } } else { - ASSERT(DESC_IS_FLUID(filter_ctx.desc->type)); + ASSERT(DESC_IS_FLUID(filter_ctx.desc)); /* In fluid; TODO: check distance wrt local geometry (use 4V/S?) */ if(filter_ctx.desc->type == DESC_MAT_FLUID) { logger_print(stardis->logger, LOG_WARNING, @@ -370,7 +404,7 @@ check_probe_conform_to_type } else { ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG); logger_print(stardis->logger, LOG_WARNING, - "Probe is in fluid '%s': computing fluid temperature, " + "Probe is in fluid_prog '%s': computing fluid temperature, " "not using a specific position.\n", str_cget(&filter_ctx.desc->d.fluid_prog->name)); } @@ -442,7 +476,8 @@ compute_probe(struct stardis* stardis, struct time* start) ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE)); - ERR(check_probe_conform_to_type(stardis, 0, stardis->probe, &iprim, uv)); + ERR(check_probe_conform_to_type(stardis, 0, stardis->probe, + stardis->time_range[0], &iprim, uv)); args.nrealisations = stardis->samples; d3_set(args.position, stardis->probe); @@ -539,7 +574,8 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start) #endif ASSERT(stardis && start && (stardis->mode & MODE_PROBE_COMPUTE_ON_INTERFACE)); - ERR(check_probe_conform_to_type(stardis, 1, stardis->probe, &iprim, uv)); + ERR(check_probe_conform_to_type(stardis, 1, stardis->probe, + stardis->time_range[0], &iprim, uv)); ASSERT(iprim != UINT_MAX); ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, @@ -561,7 +597,7 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start) const struct description* d; ASSERT(prop[SG3D_FRONT] < dcount); d = descriptions + prop[SG3D_FRONT]; - ASSERT(DESC_IS_MEDIUM(d->type)); + ASSERT(DESC_IS_MEDIUM(d)); medium_name = str_cget(get_description_name(d)); compute_side = SDIS_FRONT; compute_side_name = "FRONT"; @@ -570,7 +606,7 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start) const struct description* d; ASSERT(prop[SG3D_BACK] < dcount); d = descriptions + prop[SG3D_BACK]; - ASSERT(DESC_IS_MEDIUM(d->type)); + ASSERT(DESC_IS_MEDIUM(d)); medium_name = str_cget(get_description_name(d)); compute_side = SDIS_BACK; compute_side_name = "BACK"; @@ -590,8 +626,8 @@ compute_probe_on_interface(struct stardis* stardis, struct time* start) fd = descriptions + prop[SG3D_FRONT]; bd = descriptions + prop[SG3D_BACK]; - ASSERT(DESC_IS_MEDIUM(fd->type)); - ASSERT(DESC_IS_MEDIUM(bd->type)); + ASSERT(DESC_IS_MEDIUM(fd)); + ASSERT(DESC_IS_MEDIUM(bd)); description_get_medium_id(fd, &fmat_id); description_get_medium_id(bd, &bmat_id); diff --git a/src/stardis-compute.h b/src/stardis-compute.h @@ -33,13 +33,13 @@ find_medium_by_name const struct str* name, unsigned* id); /* Can be NULL */ -extern LOCAL_SYM res_T +res_T stardis_compute (struct stardis* stardis, struct time* start); -extern LOCAL_SYM res_T +res_T read_compute_surface (struct stardis* stardis); -#endif -\ No newline at end of file +#endif diff --git a/src/stardis-description.c b/src/stardis-description.c @@ -0,0 +1,520 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "stardis-description.h" +#include "stardis-prog.h" +#include "stardis-solid.h" +#include "stardis-solid-prog.h" +#include "stardis-fluid.h" +#include "stardis-fluid-prog.h" +#include "stardis-hbound-prog.h" +#include "stardis-tbound-prog.h" +#include "stardis-fbound-prog.h" +#include "stardis-sfconnect-prog.h" +#include "stardis-ssconnect-prog.h" + +#include <rsys/rsys.h> +#include <rsys/mem_allocator.h> +#include <rsys/str.h> + +#include <sdis.h> + +#include <limits.h> + +/* Utility macros */ +#define ERR(Expr) if((res = (Expr)) != RES_OK) goto error; else (void)0 + +res_T +init_h + (struct mem_allocator* allocator, + struct h_boundary** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_initialized = 1; + (*dst)->imposed_temperature = -1; + (*dst)->mat_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) str_release(&(*dst)->name); + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_h_boundary + (struct h_boundary* bound, + struct mem_allocator* allocator) +{ + ASSERT(bound && allocator); + str_release(&bound->name); + if(bound->possible_external_fluid) + release_fluid(bound->possible_external_fluid, allocator); + MEM_RM(allocator, bound); +} + +res_T +str_print_h_boundary + (struct str* str, + const struct description* desc) +{ + res_T res = RES_OK; + const struct h_boundary* b; + ASSERT(str && desc && DESC_IS_H(desc)); + b = desc->d.h_boundary; + ERR(str_append_printf(str, + "H boundary for %s '%s': ref_temperature=%g emissivity=%g specular_fraction=%g " + "hc=%g T=%g (using medium %u as external medium)", + (desc->type == DESC_BOUND_H_FOR_SOLID ? "solid" : "fluid"), + str_cget(&b->name), b->ref_temperature, b->emissivity, + b->specular_fraction, b->hc, b->imposed_temperature, b->mat_id)); +end: + return res; +error: + goto end; +} + +res_T +init_t + (struct mem_allocator* allocator, + struct t_boundary** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_initialized = 1; + (*dst)->imposed_temperature = -1; + (*dst)->mat_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) str_release(&(*dst)->name); + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_t_boundary + (struct t_boundary* bound, + struct mem_allocator* allocator) +{ + ASSERT(bound && allocator); + str_release(&bound->name); + MEM_RM(allocator, bound); +} + +res_T +str_print_t_boundary + (struct str* str, + const struct t_boundary* b) +{ + res_T res = RES_OK; + ASSERT(str && b); + ERR(str_append_printf(str, + "T boundary for solid '%s': T=%g (using medium %u as external medium)", + str_cget(&b->name), b->imposed_temperature, b->mat_id)); +end: + return res; +error: + goto end; +} + +res_T +init_f + (struct mem_allocator* allocator, + struct f_boundary** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_initialized = 1; + (*dst)->mat_id = UINT_MAX; + (*dst)->imposed_flux = -1; +end: + return res; +error: + if(str_initialized) str_release(&(*dst)->name); + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_f_boundary + (struct f_boundary* bound, + struct mem_allocator* allocator) +{ + ASSERT(bound && allocator); + str_release(&bound->name); + MEM_RM(allocator, bound); +} + +res_T +str_print_f_boundary + (struct str* str, + const struct f_boundary* b) +{ + res_T res = RES_OK; + ASSERT(str && b); + ERR(str_append_printf(str, + "F boundary for SOLID '%s': flux=%g (using medium %u as external medium)", + str_cget(&b->name), b->imposed_flux, b->mat_id)); +end: + return res; +error: + goto end; +} + +void +release_sf_connect + (struct solid_fluid_connect* connect, + struct mem_allocator* allocator) +{ + ASSERT(connect && allocator); + str_release(&connect->name); + MEM_RM(allocator, connect); +} + +res_T +init_sf + (struct mem_allocator* allocator, + struct solid_fluid_connect** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_initialized = 1; + (*dst)->connection_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) str_release(&(*dst)->name); + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +res_T +str_print_sf_connect + (struct str* str, + const struct solid_fluid_connect* c) +{ + res_T res = RES_OK; + ASSERT(str && c); + ERR(str_append_printf(str, + "Solid-Fluid connection '%s': " + "ref_temperature=%g emissivity=%g, specular_fraction=%g hc=%g", + str_cget(&c->name), + c->ref_temperature, c->emissivity, c->specular_fraction, c->hc)); +end: + return res; +error: + goto end; +} + +void +release_ss_connect + (struct solid_solid_connect* connect, + struct mem_allocator* allocator) +{ + ASSERT(connect && allocator); + str_release(&connect->name); + MEM_RM(allocator, connect); +} + +res_T +init_ss + (struct mem_allocator* allocator, + struct solid_solid_connect** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_initialized = 1; + (*dst)->connection_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) str_release(&(*dst)->name); + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +res_T +str_print_ss_connect + (struct str* str, + const struct solid_solid_connect* c) +{ + res_T res = RES_OK; + ASSERT(str && c); + ERR(str_append_printf(str, + "Solid-Solid connection '%s': contact resistance=%g", + str_cget(&c->name), c->tcr)); +end: + return res; +error: + goto end; +} + +res_T +init_description + (struct mem_allocator* alloc, + struct description* desc) +{ + ASSERT(desc); + (void)alloc; + desc->type = DESCRIPTION_TYPE_COUNT__; + desc->d.fluid = NULL; + return RES_OK; +} + +void +release_description + (struct description* desc, + struct mem_allocator* allocator) +{ + ASSERT(desc && allocator); + switch (desc->type) { + case DESC_MAT_SOLID: + release_solid(desc->d.solid, allocator); + break; + case DESC_MAT_SOLID_PROG: + release_solid_prog(desc->d.solid_prog, allocator); + break; + case DESC_MAT_FLUID: + release_fluid(desc->d.fluid, allocator); + break; + case DESC_MAT_FLUID_PROG: + release_fluid_prog(desc->d.fluid_prog, allocator); + break; + case DESC_BOUND_H_FOR_SOLID: + case DESC_BOUND_H_FOR_FLUID: + release_h_boundary(desc->d.h_boundary, allocator); + break; + case DESC_BOUND_H_FOR_SOLID_PROG: + case DESC_BOUND_H_FOR_FLUID_PROG: + release_h_boundary_prog(desc->d.h_boundary_prog, allocator); + break; + case DESC_BOUND_T_FOR_SOLID: + release_t_boundary(desc->d.t_boundary, allocator); + break; + case DESC_BOUND_T_FOR_SOLID_PROG: + release_t_boundary_prog(desc->d.t_boundary_prog, allocator); + break; + case DESC_BOUND_F_FOR_SOLID: + release_f_boundary(desc->d.f_boundary, allocator); + break; + case DESC_BOUND_F_FOR_SOLID_PROG: + release_f_boundary_prog(desc->d.f_boundary_prog, allocator); + break; + case DESC_SOLID_FLUID_CONNECT: + release_sf_connect(desc->d.sf_connect, allocator); + break; + case DESC_SOLID_FLUID_CONNECT_PROG: + release_sf_connect_prog(desc->d.sf_connect_prog, allocator); + break; + case DESC_SOLID_SOLID_CONNECT: + release_ss_connect(desc->d.ss_connect, allocator); + break; + case DESC_SOLID_SOLID_CONNECT_PROG: + release_ss_connect_prog(desc->d.ss_connect_prog, allocator); + break; + default: + FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); + } +} + +res_T +str_print_description + (struct str* str, + const unsigned rank, + const struct description* desc) +{ + res_T res = RES_OK; + ASSERT(str && desc); + str_clear(str); + ERR(str_printf(str, "Description %u: ", rank)); + switch (desc->type) { + case DESC_MAT_SOLID: + ERR(str_print_solid(str, desc->d.solid)); + break; + case DESC_MAT_SOLID_PROG: + ERR(str_print_solid_prog(str, desc->d.solid_prog)); + break; + case DESC_MAT_FLUID: + ERR(str_print_fluid(str, desc->d.fluid)); + break; + case DESC_MAT_FLUID_PROG: + ERR(str_print_fluid_prog(str, desc->d.fluid_prog)); + break; + case DESC_BOUND_T_FOR_SOLID: + ERR(str_print_t_boundary(str, desc->d.t_boundary)); + break; + case DESC_BOUND_T_FOR_SOLID_PROG: + ERR(str_print_t_boundary_prog(str, desc->d.t_boundary_prog)); + break; + case DESC_BOUND_H_FOR_SOLID: + case DESC_BOUND_H_FOR_FLUID: + ERR(str_print_h_boundary(str, desc)); + break; + case DESC_BOUND_H_FOR_SOLID_PROG: + case DESC_BOUND_H_FOR_FLUID_PROG: + ERR(str_print_h_boundary_prog(str, desc)); + break; + case DESC_BOUND_F_FOR_SOLID: + ERR(str_print_f_boundary(str, desc->d.f_boundary)); + break; + case DESC_BOUND_F_FOR_SOLID_PROG: + ERR(str_print_f_boundary_prog(str, desc->d.f_boundary_prog)); + break; + case DESC_SOLID_FLUID_CONNECT: + ERR(str_print_sf_connect(str, desc->d.sf_connect)); + break; + case DESC_SOLID_FLUID_CONNECT_PROG: + ERR(str_print_sf_connect_prog(str, desc->d.sf_connect_prog)); + break; + case DESC_SOLID_SOLID_CONNECT: + ERR(str_print_ss_connect(str, desc->d.ss_connect)); + break; + case DESC_SOLID_SOLID_CONNECT_PROG: + ERR(str_print_ss_connect_prog(str, desc->d.ss_connect_prog)); + break; + default: + FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); + } +end: + return res; +error: + goto end; +} + +const struct str* +get_description_name + (const struct description* desc) +{ + ASSERT(desc); + switch (desc->type) { + case DESC_MAT_SOLID: + return &desc->d.solid->name; + case DESC_MAT_SOLID_PROG: + return &desc->d.solid_prog->name; + case DESC_MAT_FLUID: + return &desc->d.fluid->name; + case DESC_MAT_FLUID_PROG: + return &desc->d.fluid_prog->name; + case DESC_BOUND_T_FOR_SOLID: + return &desc->d.t_boundary->name; + case DESC_BOUND_T_FOR_SOLID_PROG: + return &desc->d.t_boundary_prog->name; + case DESC_BOUND_H_FOR_SOLID: + case DESC_BOUND_H_FOR_FLUID: + return &desc->d.h_boundary->name; + case DESC_BOUND_H_FOR_SOLID_PROG: + case DESC_BOUND_H_FOR_FLUID_PROG: + return &desc->d.h_boundary_prog->name; + case DESC_BOUND_F_FOR_SOLID: + return &desc->d.f_boundary->name; + case DESC_BOUND_F_FOR_SOLID_PROG: + return &desc->d.f_boundary_prog->name; + case DESC_SOLID_FLUID_CONNECT: + return &desc->d.sf_connect->name; + case DESC_SOLID_FLUID_CONNECT_PROG: + return &desc->d.sf_connect_prog->name; + case DESC_SOLID_SOLID_CONNECT: + return &desc->d.ss_connect->name; + case DESC_SOLID_SOLID_CONNECT_PROG: + return &desc->d.ss_connect_prog->name; + default: + FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); + } +} + +void +description_get_medium_id + (const struct description* desc, + unsigned* id) +{ + ASSERT(desc && id); + switch (desc->type) { + case DESC_MAT_SOLID: + *id = desc->d.solid->solid_id; + return; + case DESC_MAT_SOLID_PROG: + *id = desc->d.solid_prog->solid_id; + return; + case DESC_MAT_FLUID: + *id = desc->d.fluid->fluid_id; + return; + case DESC_MAT_FLUID_PROG: + *id = desc->d.fluid_prog->fluid_id; + return; + case DESC_BOUND_H_FOR_SOLID: + case DESC_BOUND_H_FOR_FLUID: + *id = desc->d.h_boundary->mat_id; + return; + case DESC_BOUND_H_FOR_SOLID_PROG: + case DESC_BOUND_H_FOR_FLUID_PROG: + *id = desc->d.h_boundary_prog->mat_id; + return; + case DESC_BOUND_T_FOR_SOLID: + *id = desc->d.t_boundary->mat_id; + return; + case DESC_BOUND_T_FOR_SOLID_PROG: + *id = desc->d.t_boundary_prog->mat_id; + return; + case DESC_BOUND_F_FOR_SOLID: + *id = desc->d.f_boundary->mat_id; + return; + case DESC_BOUND_F_FOR_SOLID_PROG: + *id = desc->d.f_boundary_prog->mat_id; + return; + case DESC_SOLID_FLUID_CONNECT: /* No medium linked to SF */ + case DESC_SOLID_SOLID_CONNECT: /* No medium linked to SS */ + case DESC_SOLID_FLUID_CONNECT_PROG: /* No medium linked to SF */ + case DESC_SOLID_SOLID_CONNECT_PROG: /* No medium linked to SS */ + default: + FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); + } +} diff --git a/src/stardis-description.h b/src/stardis-description.h @@ -0,0 +1,256 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef STARDIS_DESCRIPTION_H +#define STARDIS_DESCRIPTION_H + +#include "stardis-prog.h" + +#include <rsys/rsys.h> +#include <rsys/dynamic_array.h> +#include <rsys/str.h> + +#include <sdis.h> + +#include <limits.h> + +/* Forward declarations */ +struct mem_allocator; + +/* Different types of descriptions */ +enum description_type { + DESC_MAT_SOLID, + DESC_MAT_SOLID_PROG, + DESC_MAT_FLUID, + DESC_MAT_FLUID_PROG, + DESC_BOUND_H_FOR_FLUID, + DESC_BOUND_H_FOR_FLUID_PROG, + DESC_BOUND_H_FOR_SOLID, + DESC_BOUND_H_FOR_SOLID_PROG, + DESC_BOUND_T_FOR_SOLID, + DESC_BOUND_T_FOR_SOLID_PROG, + DESC_BOUND_F_FOR_SOLID, + DESC_BOUND_F_FOR_SOLID_PROG, + DESC_SOLID_FLUID_CONNECT, + DESC_SOLID_FLUID_CONNECT_PROG, + DESC_SOLID_SOLID_CONNECT, + DESC_SOLID_SOLID_CONNECT_PROG, + DESCRIPTION_TYPE_COUNT__, + DESC_OUTSIDE +}; + +#define DESC_IS_H(D) \ + ((D)->type == DESC_BOUND_H_FOR_SOLID || (D)->type == DESC_BOUND_H_FOR_FLUID \ + || (D)->type == DESC_BOUND_H_FOR_SOLID_PROG \ + || (D)->type == DESC_BOUND_H_FOR_FLUID_PROG) +#define DESC_IS_T(D) \ + ((D)->type == DESC_BOUND_T_FOR_SOLID \ + || (D)->type == DESC_BOUND_T_FOR_SOLID_PROG) +#define DESC_IS_F(D) \ + ((D)->type == DESC_BOUND_F_FOR_SOLID \ + || (D)->type == DESC_BOUND_F_FOR_SOLID_PROG) +#define DESC_IS_SOLID(D) \ + ((D)->type == DESC_MAT_SOLID || (D)->type == DESC_MAT_SOLID_PROG) +#define DESC_IS_FLUID(D) \ + ((D)->type == DESC_MAT_FLUID || (D)->type == DESC_MAT_FLUID_PROG) +#define DESC_IS_MEDIUM(D) \ + (DESC_IS_SOLID(D) || DESC_IS_FLUID(D)) +#define DESC_IS_BOUNDARY(D) \ + (DESC_IS_H(D) || DESC_IS_T(D) || DESC_IS_F(D)) +#define DESC_IS_SOLID_FLUID(D) \ + ((D)->type == DESC_SOLID_FLUID_CONNECT \ + || (D)->type == DESC_SOLID_FLUID_CONNECT_PROG) +#define DESC_IS_SOLID_SOLID(D) \ + ((D)->type == DESC_SOLID_SOLID_CONNECT \ + || (D)->type == DESC_SOLID_SOLID_CONNECT_PROG) + +/******************************************************************************/ + +struct fluid; +struct fluid_prog; +struct solid; +struct solid_prog; +struct t_boundary; +struct t_boundary_prog; +struct f_boundary; +struct f_boundary_prog; +struct h_boundary; +struct h_boundary_prog; +struct solid_fluid_connect; +struct solid_fluid_connect_prog; +struct solid_solid_connect; +struct solid_solid_connect_prog; + +struct description { + enum description_type type; + union { + struct fluid* fluid; + struct fluid_prog* fluid_prog; + struct solid* solid; + struct solid_prog* solid_prog; + struct t_boundary* t_boundary; + struct t_boundary_prog* t_boundary_prog; + struct f_boundary* f_boundary; + struct f_boundary_prog* f_boundary_prog; + struct h_boundary* h_boundary; + struct h_boundary_prog* h_boundary_prog; + struct solid_fluid_connect* sf_connect; + struct solid_fluid_connect_prog* sf_connect_prog; + struct solid_solid_connect* ss_connect; + struct solid_solid_connect_prog* ss_connect_prog; + } d; +}; + +/******************************************************************************/ + +struct h_boundary { + struct str name; + double ref_temperature; + double emissivity; + double specular_fraction; + double hc; + double imposed_temperature; + unsigned mat_id; + struct fluid* possible_external_fluid; /* if H for solid */ +}; + +res_T +init_h + (struct mem_allocator* allocator, + struct h_boundary** dst); + +void +release_h_boundary + (struct h_boundary* bound, + struct mem_allocator* allocator); + +res_T +str_print_h_boundary + (struct str* str, + const struct description* desc); + +struct t_boundary { + struct str name; + double imposed_temperature; + unsigned mat_id; +}; + +res_T +init_t + (struct mem_allocator* allocator, + struct t_boundary** dst); + +void +release_t_boundary + (struct t_boundary* bound, + struct mem_allocator* allocator); + +res_T +str_print_t_boundary + (struct str* str, + const struct t_boundary* b); + +struct f_boundary { + struct str name; + double imposed_flux; + unsigned mat_id; +}; + +res_T +init_f + (struct mem_allocator* allocator, + struct f_boundary** dst); + +void +release_f_boundary + (struct f_boundary* bound, + struct mem_allocator* allocator); + +res_T +str_print_f_boundary + (struct str* str, + const struct f_boundary* b); + +struct solid_fluid_connect { + struct str name; + double ref_temperature; + double emissivity; + double specular_fraction; + double hc; + unsigned connection_id; +}; + +void +release_sf_connect + (struct solid_fluid_connect* connect, + struct mem_allocator* allocator); + +res_T +init_sf + (struct mem_allocator* allocator, + struct solid_fluid_connect** dst); + +res_T +str_print_sf_connect + (struct str* str, + const struct solid_fluid_connect* c); + +struct solid_solid_connect { + struct str name; + double tcr; + unsigned connection_id; +}; + +void +release_ss_connect + (struct solid_solid_connect* connect, + struct mem_allocator* allocator); + +res_T +init_ss + (struct mem_allocator* allocator, + struct solid_solid_connect** dst); + +res_T +str_print_ss_connect + (struct str* str, + const struct solid_solid_connect* c); + +res_T +init_description + (struct mem_allocator* alloc, + struct description* desc); + +void +release_description + (struct description* desc, + struct mem_allocator* allocator); + +res_T +str_print_description + (struct str* str, + const unsigned rank, + const struct description* desc); + +const struct str* +get_description_name + (const struct description* desc); + +void +description_get_medium_id + (const struct description* desc, + unsigned* id); + +#endif diff --git a/src/stardis-fbound-prog.c b/src/stardis-fbound-prog.c @@ -0,0 +1,94 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "stardis-app.h" +#include "stardis-fbound-prog.h" +#include "stardis-prog.h" +#include "stardis-intface.h" + +#include <rsys/rsys.h> +#include <rsys/mem_allocator.h> +#include <rsys/str.h> + +#include <sdis.h> + +#include <limits.h> + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +res_T +init_f_boundary_prog + (struct mem_allocator* allocator, + struct f_boundary_prog** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_init(allocator, &(*dst)->prog_name); + str_init(allocator, &(*dst)->args); + str_initialized = 1; + (*dst)->mat_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) { + str_release(&(*dst)->name); + str_release(&(*dst)->prog_name); + str_release(&(*dst)->args); + } + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_f_boundary_prog + (struct f_boundary_prog* bound, + struct mem_allocator* allocator) +{ + ASSERT(bound && allocator); + str_release(&bound->name); + str_release(&bound->prog_name); + str_release(&bound->args); + if(bound->prog_data) + bound->release(bound->prog_data); + MEM_RM(allocator, bound); +} + +res_T +str_print_f_boundary_prog + (struct str* str, + const struct f_boundary_prog* b) +{ + res_T res = RES_OK; + ASSERT(str && b); + ERR(str_append_printf(str, + "programmed F boundary for SOLID '%s': lib='%s', args=[%s]" + " (using medium %u as external medium)", + str_cget(&b->name), str_cget(&b->prog_name), + str_cget(&b->args), b->mat_id)); +end: + return res; +error: + goto end; +} + diff --git a/src/stardis-fbound-prog.h b/src/stardis-fbound-prog.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SDIS_FBOUND_PROG_H +#define SDIS_FBOUND_PROG_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +#include "stardis-prog.h" + +struct stardis; +struct mem_allocator; +struct fluid_prog; +struct description; + +struct sdis_interface_fragment; +struct sdis_rwalk_vertex; +struct sdis_data; + +/******************************************************************************* + * F boundary prog data + ******************************************************************************/ +struct f_boundary_prog { + void* prog_data; /* result of the init_f_prog() call */ + struct str name; + struct str prog_name; + struct str args; + /* lib handle and function ptrs */ + void* lib; + void* (*create)(); + enum stardis_return_code (*init)(void*, const char*); + void (*release)(void*); + double (*flux)(const struct sdis_interface_fragment*, void*); + unsigned mat_id; +}; + +res_T +init_f_boundary_prog + (struct mem_allocator* allocator, + struct f_boundary_prog** dst); + +void +release_f_boundary_prog + (struct f_boundary_prog* bound, + struct mem_allocator* allocator); + +res_T +str_print_f_boundary_prog + (struct str* str, + const struct f_boundary_prog* b); + +#endif diff --git a/src/stardis-fluid-prog.c b/src/stardis-fluid-prog.c @@ -13,21 +13,22 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "stardis-fluid-prog.h" +#include "stardis-app.h" #include "stardis-prog.h" #include "stardis-compute.h" #include "stardis-app.h" -#include <rsys/library.h> -#include <rsys/logger.h> +#include <rsys/mem_allocator.h> #include <sdis.h> #include <limits.h> + /******************************************************************************* * Local Functions ******************************************************************************/ - static double fluid_prog_get_calorific_capacity (const struct sdis_rwalk_vertex* vtx, @@ -58,7 +59,6 @@ fluid_prog_get_temperature /******************************************************************************* * Public Functions ******************************************************************************/ - res_T create_solver_fluid_prog (struct stardis* stardis, @@ -93,12 +93,46 @@ error: } res_T +create_solver_external_fluid_prog + (struct stardis* stardis, + const struct fluid_prog* fluid_props) +{ + res_T res = RES_OK; + struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL; + struct sdis_data* data = NULL; + const struct fluid_prog** props; + + ASSERT(stardis && fluid_props); + fluid_shader.calorific_capacity = fluid_prog_get_calorific_capacity; + fluid_shader.volumic_mass = fluid_prog_get_volumic_mass; + fluid_shader.temperature = fluid_prog_get_temperature; + /* temperature has to be provided by h_boundary_prog */ + ERR(sdis_data_create(stardis->dev, sizeof(struct fluid_prog*), + ALIGNOF(struct fluid_prog*), NULL, &data)); + + props = sdis_data_get(data); /* Fetch the allocated memory space */ + *props = fluid_props; + if(fluid_props->fluid_id >= darray_media_ptr_size_get(&stardis->media)) { + ERR(darray_media_ptr_resize(&stardis->media, fluid_props->fluid_id + 1)); + } + ASSERT(!darray_media_ptr_data_get(&stardis->media)[fluid_props->fluid_id]); + ERR(sdis_fluid_create(stardis->dev, &fluid_shader, data, + darray_media_ptr_data_get(&stardis->media) + fluid_props->fluid_id)); + +end: + if(data) SDIS(data_ref_put(data)); + return res; +error: + goto end; +} + +res_T init_fluid_prog(struct mem_allocator* allocator, struct fluid_prog** dst) { res_T res = RES_OK; int str_initialized = 0; ASSERT(allocator && dst && *dst == NULL); - *dst = MEM_ALLOC(allocator, sizeof(struct fluid_prog)); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); if(! *dst) { res = RES_MEM_ERR; goto error; @@ -107,17 +141,8 @@ init_fluid_prog(struct mem_allocator* allocator, struct fluid_prog** dst) str_init(allocator, &(*dst)->prog_name); str_init(allocator, &(*dst)->args); str_initialized = 1; - (*dst)->prog_data = NULL; - (*dst)->is_outside = 0; (*dst)->desc_id = UINT_MAX; (*dst)->fluid_id = UINT_MAX; - (*dst)->lib = NULL; - (*dst)->cp = NULL; - (*dst)->rho = NULL; - (*dst)->temp = NULL; - (*dst)->create = NULL; - (*dst)->release = NULL; - (*dst)->init = NULL; end: return res; error: @@ -140,9 +165,10 @@ release_fluid_prog str_release(&fluid->prog_name); str_release(&fluid->args); - if(fluid->prog_data) { + if(fluid->prog_data + && fluid->release) /* can be NULL if external fluid */ + { fluid->release(fluid->prog_data); - fluid->prog_data = NULL; } MEM_RM(allocator, fluid); } diff --git a/src/stardis-fluid-prog.h b/src/stardis-fluid-prog.h @@ -13,22 +13,22 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SDIS_PROG_H -#define SDIS_PROG_H - -#include <sdis.h> +#ifndef SDIS_FLUID_PROG_H +#define SDIS_FLUID_PROG_H #include <rsys/rsys.h> #include <rsys/str.h> +#include "stardis-prog.h" + struct stardis; +struct mem_allocator; +struct sdis_rwalk_vertex; /******************************************************************************* * Fluid prog data ******************************************************************************/ struct fluid_prog { - /* This field must come first as a struct fluid_prog* must be usable as - * an struct custom_data** */ void* prog_data; /* result of the init_fluid() call */ struct str name; struct str prog_name; @@ -38,12 +38,13 @@ struct fluid_prog { unsigned fluid_id; /* lib handle and function ptrs */ void* lib; - double (*cp)(const struct sdis_rwalk_vertex*, struct sdis_data*); - double (*rho)(const struct sdis_rwalk_vertex*, struct sdis_data*); - double (*temp)(const struct sdis_rwalk_vertex*, struct sdis_data*); void* (*create)(); - int (*init)(void*, const char*); + enum stardis_return_code (*init)(void*, const char*); void (*release)(void*); + double (*rho)(const struct sdis_rwalk_vertex*, void*); + double (*cp)(const struct sdis_rwalk_vertex*, void*); + double (*temp)(const struct sdis_rwalk_vertex*, void*); + double* (*t_range)(void*, double trange[2]); }; res_T @@ -51,15 +52,24 @@ create_solver_fluid_prog (struct stardis* stardis, const struct fluid_prog* fluid_props); -LOCAL_SYM res_T -init_fluid_prog(struct mem_allocator* allocator, struct fluid_prog** dst); +res_T +create_solver_external_fluid_prog + (struct stardis* stardis, + const struct fluid_prog* fluid_props); + +res_T +init_fluid_prog + (struct mem_allocator* allocator, + struct fluid_prog** dst); -LOCAL_SYM void +void release_fluid_prog (struct fluid_prog* fluid, struct mem_allocator* allocator); -LOCAL_SYM res_T -str_print_fluid_prog(struct str* str, const struct fluid_prog* s); +res_T +str_print_fluid_prog + (struct str* str, + const struct fluid_prog* s); #endif diff --git a/src/stardis-fluid.h b/src/stardis-fluid.h @@ -45,15 +45,15 @@ create_solver_fluid (struct stardis* stardis, const struct fluid* fluid_props); -LOCAL_SYM res_T +res_T init_fluid(struct mem_allocator* allocator, struct fluid** dst); -LOCAL_SYM void +void release_fluid (struct fluid* desc, struct mem_allocator* allocator); -LOCAL_SYM res_T +res_T str_print_fluid(struct str* str, const struct fluid* s); #endif diff --git a/src/stardis-hbound-prog.c b/src/stardis-hbound-prog.c @@ -0,0 +1,105 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "stardis-app.h" +#include "stardis-hbound-prog.h" +#include "stardis-fluid-prog.h" +#include "stardis-prog.h" +#include "stardis-intface.h" + +#include <rsys/rsys.h> +#include <rsys/mem_allocator.h> +#include <rsys/str.h> + +#include <sdis.h> + +#include <limits.h> + +/******************************************************************************* + * Public Functions + ******************************************************************************/ +res_T +init_h_boundary_prog + (struct mem_allocator* allocator, + struct h_boundary_prog** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_init(allocator, &(*dst)->prog_name); + str_init(allocator, &(*dst)->args); + str_initialized = 1; + (*dst)->mat_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) { + str_release(&(*dst)->name); + str_release(&(*dst)->prog_name); + str_release(&(*dst)->args); + } + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_h_boundary_prog + (struct h_boundary_prog* bound, + struct mem_allocator* allocator) +{ + ASSERT(bound && allocator); + str_release(&bound->name); + str_release(&bound->prog_name); + str_release(&bound->args); + if(bound->prog_data) + bound->release(bound->prog_data); + if(bound->possible_external_fluid) + release_fluid_prog(bound->possible_external_fluid, allocator); + MEM_RM(allocator, bound); +} + +res_T +str_print_h_boundary_prog + (struct str* str, + const struct description* desc) +{ + res_T res = RES_OK; + const struct h_boundary_prog* b; + ASSERT(str && desc && DESC_IS_H(desc)); + b = desc->d.h_boundary_prog; + ERR(str_append_printf(str, + "programmed H boundary for %s '%s': lib='%s', args=[%s] " + "(using medium %u as external medium)", + (desc->type == DESC_BOUND_H_FOR_SOLID_PROG ? "solid" : "fluid"), + str_cget(&b->name), str_cget(&b->prog_name), str_cget(&b->args), + b->mat_id)); +end: + return res; +error: + goto end; +} + +double +h_bound_prog_get_hmax + (struct h_boundary_prog* h_boundary_props) +{ + return h_boundary_props->hmax(h_boundary_props->prog_data); +} diff --git a/src/stardis-hbound-prog.h b/src/stardis-hbound-prog.h @@ -0,0 +1,84 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SDIS_HBOUND_PROG_H +#define SDIS_HBOUND_PROG_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +#include "stardis-prog.h" + +struct stardis; +struct mem_allocator; +struct fluid_prog; +struct description; + +struct sdis_interface_fragment; +struct sdis_rwalk_vertex; +struct sdis_data; + +/******************************************************************************* + * H boundary prog data + ******************************************************************************/ +struct h_boundary_prog { + void* prog_data; /* result of the init_h_prog() call */ + struct str name; + struct str prog_name; + struct str args; + /* lib handle and function ptrs */ + void* lib; + void* (*create)(); + enum stardis_return_code (*init)(void*, const char*); + void (*release)(void*); + double (*ref_temp)(const struct sdis_interface_fragment*, void*); + double (*emissivity)(const struct sdis_interface_fragment*, void*); + double (*alpha)(const struct sdis_interface_fragment*, void*); + double (*hc)(const struct sdis_interface_fragment*, void*); + double (*hmax)(void*); + double* (*t_range)(void*, double trange[2]); + /* for h for solid */ + double (*boundary_temp)(const struct sdis_interface_fragment*, void*); + /* for h for fluid */ + double (*fluid_temp)(const struct sdis_rwalk_vertex*, void*); + unsigned mat_id; + struct fluid_prog* possible_external_fluid; /* if H for solid */ +}; + +res_T +create_solver_h_boundary_prog + (struct stardis* stardis, + const struct h_boundary_prog* h_boundary_props); + +res_T +init_h_boundary_prog + (struct mem_allocator* allocator, + struct h_boundary_prog** dst); + +void +release_h_boundary_prog + (struct h_boundary_prog* fluid, + struct mem_allocator* allocator); + +res_T +str_print_h_boundary_prog + (struct str* str, + const struct description* s); + +double +h_bound_prog_get_hmax + (struct h_boundary_prog* h_boundary_props); + +#endif diff --git a/src/stardis-intface.c b/src/stardis-intface.c @@ -18,6 +18,11 @@ #include "stardis-compute.h" #include "stardis-output.h" #include "stardis-solid.h" +#include "stardis-hbound-prog.h" +#include "stardis-tbound-prog.h" +#include "stardis-fbound-prog.h" +#include "stardis-ssconnect-prog.h" +#include "stardis-sfconnect-prog.h" #include <sdis.h> @@ -95,6 +100,77 @@ interface_get_tcr return interface_props->tcr; } +static double +emissivity_1 + (const struct sdis_interface_fragment* frag, + void* data) +{ + (void)frag, (void)data; + return 1; +} + +static double +intface_prog_get_temp + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct intface* interface_props = sdis_data_cget(data); + return interface_props->get_temp(frag, interface_props->prog_data); +} + +static double +intface_prog_get_flux + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct intface* interface_props = sdis_data_cget(data); + return interface_props->get_flux(frag, interface_props->prog_data); +} + +static double +intface_prog_get_hc + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct intface* interface_props = sdis_data_cget(data); + return interface_props->get_hc(frag, interface_props->prog_data); +} + +static double +intface_prog_get_emissivity + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct intface* interface_props = sdis_data_cget(data); + return interface_props->get_emissivity(frag, interface_props->prog_data); +} + +static double +intface_prog_get_alpha + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct intface* interface_props = sdis_data_cget(data); + return interface_props->get_alpha(frag, interface_props->prog_data); +} + +static double +intface_prog_get_ref_temp + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct intface* interface_props = sdis_data_cget(data); + return interface_props->get_ref_temp(frag, interface_props->prog_data); +} + +static double +intface_prog_get_tcr + (const struct sdis_interface_fragment* frag, + struct sdis_data* data) +{ + const struct intface* interface_props = sdis_data_cget(data); + return interface_props->get_tcr(frag, interface_props->prog_data); +} /******************************************************************************* * Public Functions @@ -116,7 +192,7 @@ create_intface unsigned fd, bd, cd, descr[SG3D_PROP_TYPES_COUNT__]; int fluid_count = 0, solid_count = 0; int solid_fluid_connection_count = 0, solid_solid_connection_count = 0; - int connection_count = 0, boundary_count = 0; + int connection_count = 0, boundary_count = 0, prog_count = 0; const struct description* descriptions; struct sdis_medium** media; res_T res = RES_OK; @@ -156,27 +232,31 @@ create_intface interface_props->front_medium_id = UINT_MAX; interface_props->back_medium_id = UINT_MAX; interface_props->desc_id = UINT_MAX; + interface_props->get_temp = NULL; + interface_props->get_flux = NULL; + interface_props->get_hc = NULL; + interface_props->get_emissivity = NULL; + interface_props->get_alpha = NULL; + interface_props->get_ref_temp = NULL; + interface_props->get_tcr = NULL; + interface_props->prog_data = NULL; if(front_defined) { + description_get_medium_id(&descriptions[fd], &id); + interface_props->front_medium_id = id; + front_med = media[id]; switch (descriptions[fd].type) { + case DESC_MAT_SOLID_PROG: + prog_count++; + /* fall through */ case DESC_MAT_SOLID: - id = descriptions[fd].d.solid->solid_id; solid_count++; - interface_props->front_medium_id = id; - front_med = media[id]; - break; - case DESC_MAT_FLUID: - fluid_count++; - id = descriptions[fd].d.fluid->fluid_id; - interface_props->front_medium_id = id; - front_med = media[id]; - fluid_side_shader = &interface_shader.front; break; case DESC_MAT_FLUID_PROG: + prog_count++; + /* fall through */ + case DESC_MAT_FLUID: fluid_count++; - id = descriptions[fd].d.fluid_prog->fluid_id; - interface_props->front_medium_id = id; - front_med = media[id]; fluid_side_shader = &interface_shader.front; break; default: @@ -184,27 +264,21 @@ create_intface } } if(back_defined) { + description_get_medium_id(&descriptions[bd], &id); + interface_props->back_medium_id = id; + back_med = media[id]; switch (descriptions[bd].type) { + case DESC_MAT_SOLID_PROG: + prog_count++; + /* fall through */ case DESC_MAT_SOLID: - id = descriptions[bd].d.solid->solid_id; solid_count++; - interface_props->back_medium_id = id; - back_med = media[id]; - break; - case DESC_MAT_FLUID: - fluid_count++; - id = descriptions[bd].d.fluid->fluid_id; - interface_props->back_medium_id = id; - back_med = media[id]; - /* Can overwrite fluid_side_shader. However it would imply two - * fluids and this case lead to an error */ - fluid_side_shader = &interface_shader.back; break; case DESC_MAT_FLUID_PROG: + prog_count++; + /* fall through */ + case DESC_MAT_FLUID: fluid_count++; - id = descriptions[bd].d.fluid_prog->fluid_id; - interface_props->back_medium_id = id; - back_med = media[id]; /* Can overwrite fluid_side_shader. However it would imply two * fluids and this case lead to an error */ fluid_side_shader = &interface_shader.back; @@ -219,11 +293,11 @@ create_intface } if(connect_defined) { const struct description* connect = descriptions + cd; - int type_checked = 0; + int for_fluid = 0; struct sdis_medium* def_medium = NULL; unsigned ext_id; - if(connect->type != DESC_SOLID_FLUID_CONNECT - && connect->type != DESC_SOLID_SOLID_CONNECT + if(!DESC_IS_SOLID_FLUID(connect) + && !DESC_IS_SOLID_SOLID(connect) && front_defined == back_defined) { /* 1 and only 1 defined */ @@ -232,12 +306,12 @@ create_intface } if(front_defined) { def_medium = front_med; - fluid_side_shader = DESC_IS_FLUID(descriptions[fd].type) + fluid_side_shader = DESC_IS_FLUID(descriptions+fd) ? &interface_shader.front : &interface_shader.back; } else { ASSERT(back_defined); def_medium = back_med; - fluid_side_shader = DESC_IS_FLUID(descriptions[bd].type) + fluid_side_shader = DESC_IS_FLUID(descriptions+bd) ? &interface_shader.back : &interface_shader.front; } interface_props->desc_id = cd; @@ -247,7 +321,7 @@ create_intface res = RES_BAD_ARG; goto error; } - type_checked = 1; + for_fluid = 1; ASSERT(connect->d.h_boundary->imposed_temperature >= 0); interface_props->imposed_temperature = connect->d.h_boundary->imposed_temperature; @@ -255,7 +329,7 @@ create_intface fluid_side_shader->temperature = interface_get_temperature; /* fall through */ case DESC_BOUND_H_FOR_SOLID: - if(!type_checked + if(!for_fluid && sdis_medium_get_type(def_medium) != SDIS_SOLID) { res = RES_BAD_ARG; goto error; @@ -263,7 +337,7 @@ create_intface ext_id = connect->d.h_boundary->mat_id; /* External material id */ ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); ASSERT(sdis_medium_get_type(media[ext_id]) == - (connect->type == DESC_BOUND_H_FOR_SOLID ? SDIS_FLUID : SDIS_SOLID)); + (for_fluid ? SDIS_SOLID : SDIS_FLUID)); connection_count++; boundary_count++; if(front_defined) back_med = media[ext_id]; @@ -283,6 +357,47 @@ create_intface fluid_side_shader->specular_fraction = interface_get_alpha; } break; + case DESC_BOUND_H_FOR_FLUID_PROG: + if(sdis_medium_get_type(def_medium) != SDIS_FLUID) { + res = RES_BAD_ARG; + goto error; + } + for_fluid = 1; + ASSERT(fluid_side_shader); + fluid_side_shader->temperature = intface_prog_get_temp; + /* fall through */ + case DESC_BOUND_H_FOR_SOLID_PROG: + if(!for_fluid + && sdis_medium_get_type(def_medium) != SDIS_SOLID) + { + res = RES_BAD_ARG; goto error; + } + ext_id = connect->d.h_boundary_prog->mat_id; /* External material id */ + ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); + ASSERT(sdis_medium_get_type(media[ext_id]) == + (for_fluid ? SDIS_SOLID : SDIS_FLUID)); + prog_count++; + connection_count++; + boundary_count++; + if(front_defined) back_med = media[ext_id]; + else front_med = media[ext_id]; + interface_shader.convection_coef_upper_bound + = h_bound_prog_get_hmax(connect->d.h_boundary_prog); + ASSERT(interface_shader.convection_coef_upper_bound >= 0); + interface_shader.convection_coef + = intface_prog_get_hc; + ASSERT(fluid_side_shader); + fluid_side_shader->reference_temperature + = intface_prog_get_ref_temp; + fluid_side_shader->emissivity = intface_prog_get_emissivity; + fluid_side_shader->specular_fraction = intface_prog_get_alpha; + interface_props->get_temp = connect->d.h_boundary_prog->boundary_temp; + interface_props->get_hc = connect->d.h_boundary_prog->hc; + interface_props->get_emissivity = connect->d.h_boundary_prog->emissivity; + interface_props->get_alpha = connect->d.h_boundary_prog->alpha; + interface_props->get_ref_temp = connect->d.h_boundary_prog->ref_temp; + interface_props->prog_data = connect->d.h_boundary_prog->prog_data; + break; case DESC_BOUND_T_FOR_SOLID: if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { res = RES_BAD_ARG; @@ -300,19 +415,47 @@ create_intface ASSERT(!front_med); front_med = media[ext_id]; } - /* The imposed T is for the 2 sides (until there is contact resistances) */ + /* The imposed T is for the 2 sides (there is no contact resistance) */ interface_shader.front.temperature = interface_get_temperature; interface_shader.back.temperature = interface_get_temperature; /* Set emissivity to 1 to allow radiative paths comming from * a possible external fluid to 'see' the imposed T */ ASSERT(fluid_side_shader); - fluid_side_shader->reference_temperature = interface_get_ref_temperature; fluid_side_shader->emissivity = interface_get_emissivity; interface_props->emissivity = 1; ASSERT(connect->d.t_boundary->imposed_temperature >= 0); interface_props->imposed_temperature = connect->d.t_boundary->imposed_temperature; break; + case DESC_BOUND_T_FOR_SOLID_PROG: + if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { + res = RES_BAD_ARG; + goto error; + } + ext_id = connect->d.t_boundary_prog->mat_id; /* External material id */ + ASSERT(ext_id < darray_media_ptr_size_get(&stardis->media)); + ASSERT(sdis_medium_get_type(media[ext_id]) == SDIS_FLUID); + prog_count++; + connection_count++; + boundary_count++; + if(front_defined) { + ASSERT(!back_med); + back_med = media[ext_id]; + } else { + ASSERT(!front_med); + front_med = media[ext_id]; + } + /* The imposed T is for the 2 sides (there is no contact resistance) */ + interface_shader.front.temperature = intface_prog_get_temp; + interface_shader.back.temperature = intface_prog_get_temp; + /* Set emissivity to 1 to allow radiative paths comming from + * a possible external fluid to 'see' the imposed T */ + ASSERT(fluid_side_shader); + fluid_side_shader->emissivity = interface_get_emissivity; + interface_props->get_emissivity = emissivity_1; + interface_props->get_temp = connect->d.t_boundary_prog->temperature; + interface_props->prog_data = connect->d.t_boundary_prog->prog_data; + break; case DESC_BOUND_F_FOR_SOLID: if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { res = RES_BAD_ARG; @@ -330,6 +473,24 @@ create_intface ASSERT(connect->d.f_boundary->imposed_flux != SDIS_FLUX_NONE); interface_props->imposed_flux = connect->d.f_boundary->imposed_flux; break; + case DESC_BOUND_F_FOR_SOLID_PROG: + if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { + res = RES_BAD_ARG; + goto error; + } + prog_count++; + connection_count++; + boundary_count++; + if(front_defined) { + back_med = media[connect->d.f_boundary_prog->mat_id]; + interface_shader.front.flux = intface_prog_get_flux; + } else { + front_med = media[connect->d.f_boundary_prog->mat_id]; + interface_shader.back.flux = intface_prog_get_flux; + } + interface_props->get_flux = connect->d.f_boundary_prog->flux; + interface_props->prog_data = connect->d.f_boundary_prog->prog_data; + break; case DESC_SOLID_FLUID_CONNECT: /* Both front and back should be defined */ if(solid_count != 1 || fluid_count != 1) { @@ -354,6 +515,31 @@ create_intface fluid_side_shader->specular_fraction = interface_get_alpha; } break; + case DESC_SOLID_FLUID_CONNECT_PROG: + /* Both front and back should be defined */ + if(solid_count != 1 || fluid_count != 1) { + res = RES_BAD_ARG; + goto error; + } + ASSERT(front_defined && back_defined); + prog_count++; + connection_count++; + solid_fluid_connection_count++; + interface_shader.convection_coef_upper_bound + = sf_connect_prog_get_hmax(connect->d.sf_connect_prog); + ASSERT(interface_shader.convection_coef_upper_bound >= 0); + interface_props->get_ref_temp = connect->d.sf_connect_prog->ref_temp; + interface_props->get_hc = connect->d.sf_connect_prog->hc; + interface_props->get_emissivity + = connect->d.sf_connect_prog->emissivity; + interface_props->get_alpha = connect->d.sf_connect_prog->alpha; + interface_shader.convection_coef = intface_prog_get_hc; + ASSERT(fluid_side_shader); + fluid_side_shader->emissivity = intface_prog_get_emissivity; + fluid_side_shader->specular_fraction = intface_prog_get_alpha; + fluid_side_shader->reference_temperature = intface_prog_get_ref_temp; + interface_props->prog_data = connect->d.sf_connect_prog->prog_data; + break; case DESC_SOLID_SOLID_CONNECT: /* Both front and back should be defined */ if(solid_count != 2 || fluid_count != 0) { @@ -368,6 +554,20 @@ create_intface interface_shader.thermal_contact_resistance = interface_get_tcr; } break; + case DESC_SOLID_SOLID_CONNECT_PROG: + /* Both front and back should be defined */ + if(solid_count != 2 || fluid_count != 0) { + res = RES_BAD_ARG; + goto error; + } + ASSERT(front_defined && back_defined); + prog_count++; + connection_count++; + solid_solid_connection_count++; + interface_props->get_tcr = connect->d.ss_connect_prog->tcr; + interface_shader.thermal_contact_resistance = intface_prog_get_tcr; + interface_props->prog_data = connect->d.ss_connect_prog->prog_data; + break; default: FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); } diff --git a/src/stardis-intface.h b/src/stardis-intface.h @@ -21,12 +21,21 @@ #include <limits.h> struct stardis; -struct dummies; +struct sdis_interface_fragment; /******************************************************************************* * Interface data ******************************************************************************/ struct intface { + /* programmed interfaces */ + double (*get_temp)(const struct sdis_interface_fragment*, void*); + double (*get_flux)(const struct sdis_interface_fragment*, void*); + double (*get_hc)(const struct sdis_interface_fragment*, void*); + double (*get_emissivity)(const struct sdis_interface_fragment*, void*); + double (*get_alpha)(const struct sdis_interface_fragment*, void*); + double (*get_ref_temp)(const struct sdis_interface_fragment*, void*); + double (*get_tcr)(const struct sdis_interface_fragment*, void*); + void* prog_data; /* fluid - solid */ double hc; double ref_temperature; @@ -62,7 +71,7 @@ eq_desc(const struct int_descs* a, const struct int_descs* b) #define HTABLE_KEY_FUNCTOR_EQ eq_desc #include <rsys/hash_table.h> -extern res_T +res_T create_intface (struct stardis* stardis, unsigned tr_idx, diff --git a/src/stardis-output.c b/src/stardis-output.c @@ -463,7 +463,7 @@ dump_sample_end pos = pt.data.itfrag.fragment.P; d__ = sdis_data_get(data); id = d__->desc_id; - CHK(DESC_IS_T(descs[id].type) || DESC_IS_H(descs[id].type)); + CHK(DESC_IS_T(descs+id) || DESC_IS_H(descs+id)); break; } case SDIS_VERTEX: @@ -546,7 +546,7 @@ dump_sample data = sdis_interface_get_data(pt.data.itfrag.intface); d__ = sdis_data_get(data); desc_id = d__->desc_id; - CHK(DESC_IS_T(descs[desc_id].type) || DESC_IS_H(descs[desc_id].type)); + CHK(DESC_IS_T(descs+desc_id) || DESC_IS_H(descs+desc_id)); header.id = desc_id; header.at_initial = 0; break; @@ -1066,7 +1066,7 @@ dump_boundaries_at_the_end_of_vtk ERR(sg3d_geometry_get_unique_triangle_properties(stardis->geometry.sg3d, t, descr)); if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY - && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type)) + && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE])) /* Descriptions are numbered from 1 in the log (so the 1+ below) */ fprintf(stream, "%u\n", 1 + descr[SG3D_INTFACE]); else fprintf(stream, "%u\n", SG3D_UNSPECIFIED_PROPERTY); @@ -1271,7 +1271,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk if(descr[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY) description_get_medium_id(descriptions + descr[SG3D_FRONT], &fmid); else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY - && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type)) + && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE])) { description_get_medium_id(descriptions + descr[SG3D_INTFACE], &fmid); } @@ -1279,7 +1279,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk if(descr[SENC3D_BACK] != SG3D_UNSPECIFIED_PROPERTY) description_get_medium_id(descriptions + descr[SENC3D_BACK], &bmid); else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY - && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type)) + && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE])) { description_get_medium_id(descriptions + descr[SG3D_INTFACE], &bmid); } @@ -1291,7 +1291,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk if(descr[SG3D_FRONT] != SG3D_UNSPECIFIED_PROPERTY) description_get_medium_id(descriptions + descr[SG3D_FRONT], &mid); else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY - && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type)) + && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE])) { description_get_medium_id(descriptions + descr[SG3D_INTFACE], &mid); } @@ -1302,7 +1302,7 @@ dump_enclosure_related_stuff_at_the_end_of_vtk if(descr[SENC3D_BACK] != SG3D_UNSPECIFIED_PROPERTY) description_get_medium_id(descriptions + descr[SENC3D_BACK], &mid); else if(descr[SG3D_INTFACE] != SG3D_UNSPECIFIED_PROPERTY - && DESC_IS_BOUNDARY(descriptions[descr[SG3D_INTFACE]].type)) + && DESC_IS_BOUNDARY(descriptions+descr[SG3D_INTFACE])) { description_get_medium_id(descriptions + descr[SG3D_INTFACE], &mid); } diff --git a/src/stardis-output.h b/src/stardis-output.h @@ -39,50 +39,50 @@ struct dump_path_context { struct stardis* stardis; }; -extern res_T +res_T dump_path (const struct sdis_heat_path* path, void* context); -extern res_T +res_T print_sample (struct sdis_green_path* path, void* ctx); -extern res_T +res_T dump_vtk_image (const struct sdis_estimator_buffer* buf, FILE* stream); -extern res_T +res_T dump_ht_image (const struct sdis_estimator_buffer* buf, FILE* stream); -extern res_T +res_T dump_green_ascii (struct sdis_green_function* green, const struct stardis* stardis, FILE* stream); -extern res_T +res_T dump_green_bin (struct sdis_green_function* green, const struct stardis* stardis, FILE* stream); -extern res_T +res_T dump_paths_end (struct sdis_green_function* green, const struct stardis* stardis, FILE* stream); -extern res_T +res_T dump_enclosure_related_stuff_at_the_end_of_vtk (struct stardis* stardis, FILE* stream); -extern res_T +res_T print_computation_time (struct sdis_estimator* estimator, /* Can be NULL */ struct stardis* stardis, @@ -91,39 +91,39 @@ print_computation_time struct time* computation_end, struct time* output_end); /* Can be NULL */ -extern res_T +res_T print_single_MC_result (struct sdis_estimator* estimator, struct stardis* stardis, FILE* stream); -extern void +void dump_map (const struct stardis* stardis, const struct darray_estimators* estimators, FILE* stream); -extern res_T +res_T dump_boundaries_at_the_end_of_vtk (const struct stardis* stardis, FILE* stream); -extern res_T +res_T dump_compute_region_at_the_end_of_vtk (struct stardis* stardis, FILE* stream); -extern res_T +res_T dump_model_as_c_chunks (struct stardis* stardis, FILE* stream); -extern res_T +res_T write_random_generator_state (struct sdis_estimator* estimator, FILE* stream); -extern res_T +res_T read_random_generator_state (struct ssp_rng* state, FILE* stream); diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -16,8 +16,17 @@ #define _POSIX_C_SOURCE 200809L /* strdup */ #include "stardis-parsing.h" #include "stardis-app.h" +#include "stardis-description.h" +#include "stardis-hbound-prog.h" +#include "stardis-tbound-prog.h" +#include "stardis-fbound-prog.h" +#include "stardis-sfconnect-prog.h" +#include "stardis-ssconnect-prog.h" +#include "stardis-fluid-prog.h" +#include "stardis-fluid.h" +#include "stardis-solid-prog.h" +#include "stardis-solid.h" #include "stardis-default.h" -#include "stardis-version.h" #include <rsys/cstr.h> #include <rsys/double2.h> @@ -26,7 +35,6 @@ #include <rsys/logger.h> #include <rsys/library.h> -#include <getopt.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> @@ -42,23 +50,7 @@ /******************************************************************************* * Local Functions ******************************************************************************/ - -void -add_geom_ctx_indices - (const unsigned itri, - unsigned ids[3], - void* context) -{ - const struct add_geom_ctx* ctx = context; - const unsigned* trg; - int i; - ASSERT(ids && ctx); - ASSERT(itri < ctx->stl_desc.triangles_count); - trg = ctx->stl_desc.indices + 3 * itri; - for(i = 0; i < 3; i++) ids[i] = trg[i]; -} - -void +static void add_geom_ctx_properties (const unsigned itri, unsigned prop[3], @@ -72,20 +64,6 @@ add_geom_ctx_properties for(i = 0; i < SG3D_PROP_TYPES_COUNT__; i++) prop[i] = ctx->properties[i]; } -void -add_geom_ctx_position - (const unsigned ivert, - double pos[3], - void* context) -{ - const struct add_geom_ctx* ctx = context; - const float* v; - ASSERT(pos && ctx); - ASSERT(ivert < ctx->stl_desc.vertices_count); - v = ctx->stl_desc.vertices + 3 * ivert; - d3_set_f3(pos, v); -} - static res_T add_geom_keep_degenerated (const unsigned itri, @@ -94,7 +72,6 @@ add_geom_keep_degenerated { const struct add_geom_ctx* ctx = context; struct darray_uint* degenerated; - ASSERT(abort && ctx && ctx->custom); (void)abort; ASSERT(itri < ctx->stl_desc.triangles_count); degenerated = ctx->custom; @@ -248,6 +225,34 @@ error: /******************************************************************************* * Public Functions ******************************************************************************/ +void +add_geom_ctx_position + (const unsigned ivert, + double pos[3], + void* context) +{ + const struct add_geom_ctx* ctx = context; + const float* v; + ASSERT(pos && ctx); + ASSERT(ivert < ctx->stl_desc.vertices_count); + v = ctx->stl_desc.vertices + 3 * ivert; + d3_set_f3(pos, v); +} + +void +add_geom_ctx_indices + (const unsigned itri, + unsigned ids[3], + void* context) +{ + const struct add_geom_ctx* ctx = context; + const unsigned* trg; + int i; + ASSERT(ids && ctx); + ASSERT(itri < ctx->stl_desc.triangles_count); + trg = ctx->stl_desc.indices + 3 * itri; + for(i = 0; i < 3; i++) ids[i] = trg[i]; +} static res_T description_set_name @@ -259,9 +264,11 @@ description_set_name double foo; const char* keywords[] = { "AUTO", "BACK", "BOTH", "FLUID", "FLUID_PROG", "FRONT", "F_BOUNDARY_FOR_SOLID", - "H_BOUNDARY_FOR_FLUID", "H_BOUNDARY_FOR_SOLID", "SCALE", "SOLID", - "SOLID_FLUID_CONNECTION", "SOLID_SOLID_CONNECTION", "TRAD", - "T_BOUNDARY_FOR_SOLID", "UNKNOWN" }; + "F_BOUNDARY_FOR_SOLID_PROG", "H_BOUNDARY_FOR_FLUID", "H_BOUNDARY_FOR_FLUID_PROG", + "H_BOUNDARY_FOR_SOLID", "H_BOUNDARY_FOR_SOLID_PROG", "SCALE", "SOLID", "SOLID_PROG", + "SOLID_FLUID_CONNECTION", "SOLID_FLUID_CONNECTION_PROG", "SOLID_SOLID_CONNECTION", + "SOLID_SOLID_CONNECTION_PROG", "TRAD", "T_BOUNDARY_FOR_SOLID", + "T_BOUNDARY_FOR_SOLID_PROG", "UNKNOWN" }; int i; ASSERT(name && tk); @@ -375,12 +382,13 @@ process_h if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "hc"); + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Convection coefficient"); res = cstr_to_double(tk, &h_boundary->hc); if(res != RES_OK || h_boundary->hc < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid hc: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, + "Invalid Convection coefficient: %s\n", tk); if(res == RES_OK) res = RES_BAD_ARG; goto end; } @@ -400,6 +408,7 @@ process_h ERR(get_dummy_solid_id(stardis, &h_boundary->mat_id)); else { struct fluid* fluid = NULL; + ASSERT(type == DESC_BOUND_H_FOR_SOLID); ERR(init_fluid(stardis->allocator, &fluid)); fluid->fluid_id = allocate_stardis_medium_id(stardis); h_boundary->mat_id = fluid->fluid_id; @@ -425,6 +434,203 @@ error: goto end; } +/* H_BOUNDARY_FOR_SOLID_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] + * H_BOUNDARY_FOR_FLUID_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] */ +static res_T +process_h_prog + (struct stardis* stardis, + const enum description_type type, + char** tok_ctx) +{ + char* tk = NULL; + struct description* desc; + const char* lib_name; + struct str tmp; + size_t sz; + struct h_boundary_prog* h_boundary_prog; + res_T res = RES_OK; + + ASSERT(stardis && tok_ctx); + + stardis->counts.fmed_count++; + + str_init(stardis->allocator, &tmp); + sz = darray_descriptions_size_get(&stardis->descriptions); + ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); + desc = darray_descriptions_data_get(&stardis->descriptions) + sz; + ERR(init_h_boundary_prog(stardis->allocator, &desc->d.h_boundary_prog)); + h_boundary_prog = desc->d.h_boundary_prog; + desc->type = type; + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed h boundary name"); + ERR(description_set_name(stardis, &h_boundary_prog->name, tk)); + if(find_description_by_name(stardis, &h_boundary_prog->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", tk); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); + ERR(str_set(&h_boundary_prog->prog_name, tk)); + lib_name = tk; + + ASSERT(sz <= UINT_MAX); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + + /* store the end of line as args for custom init */ + if(tok_ctx) { + ERR(str_set(&h_boundary_prog->args, *tok_ctx)); + } + /* get the user-defined functions from the library */ + h_boundary_prog->lib = library_open(lib_name); + if(!h_boundary_prog->lib) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open library: %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->create + = library_get_symbol(h_boundary_prog->lib, "create_h_boundary_data"); + if(!h_boundary_prog->create) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'create_h_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->init + = library_get_symbol(h_boundary_prog->lib, "init_h_boundary_data"); + if(!h_boundary_prog->init) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'init_h_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->release + = library_get_symbol(h_boundary_prog->lib, "release_h_boundary_data"); + if(!h_boundary_prog->release) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'release_h_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->ref_temp + = library_get_symbol(h_boundary_prog->lib, "reference_temperature"); + if(!h_boundary_prog->ref_temp) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'reference_temperature()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->emissivity + = library_get_symbol(h_boundary_prog->lib, "emissivity"); + if(!h_boundary_prog->emissivity) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'emissivity()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->alpha + = library_get_symbol(h_boundary_prog->lib, "specular_fraction"); + if(!h_boundary_prog->alpha) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'specular_fraction()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->hc + = library_get_symbol(h_boundary_prog->lib, "convection_coefficient"); + if(!h_boundary_prog->hc) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'convection_coefficient()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&h_boundary_prog->hmax + = library_get_symbol(h_boundary_prog->lib, "max_convection_coefficient"); + if(!h_boundary_prog->hmax) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'max_convection_coefficient()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + if(type == DESC_BOUND_H_FOR_FLUID_PROG) { + *(void**)&h_boundary_prog->boundary_temp + = library_get_symbol(h_boundary_prog->lib, "boundary_temperature"); + if(!h_boundary_prog->boundary_temp) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'boundary_temperature()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + } else { + ASSERT(type == DESC_BOUND_H_FOR_SOLID_PROG); + *(void**)&h_boundary_prog->fluid_temp + = library_get_symbol(h_boundary_prog->lib, "fluid_temperature"); + if(!h_boundary_prog->fluid_temp) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'fluid_temperature()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + } + *(void**)&h_boundary_prog->t_range + = library_get_symbol(h_boundary_prog->lib, "t_range"); + if(!h_boundary_prog->t_range) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 't_range()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + /* create and init custom data */ + h_boundary_prog->prog_data = h_boundary_prog->create(); + if(!h_boundary_prog->prog_data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create h_boundary_prog data %s\n", str_cget(&h_boundary_prog->name)); + res = RES_BAD_ARG; + goto error; + } + /* duplicate args to allow init() to modify them */ + ERR(str_copy(&tmp, &h_boundary_prog->args)); + if(STARDIS_SUCCESS != + h_boundary_prog->init(h_boundary_prog->prog_data, str_get(&tmp))) + { + logger_print(stardis->logger, LOG_ERROR, + "Cannot init h_boundary_prog data %s\n", str_cget(&h_boundary_prog->name)); + res = RES_BAD_ARG; + goto error; + } + + h_boundary_prog->t_range(h_boundary_prog->prog_data, stardis->t_range); + + /* create the media behind the interface */ + if(type == DESC_BOUND_H_FOR_FLUID_PROG) { + ERR(get_dummy_solid_id(stardis, &h_boundary_prog->mat_id)); + } else { + struct fluid_prog* fluid_prog = NULL; + ASSERT(type == DESC_BOUND_H_FOR_SOLID_PROG); + ERR(init_fluid_prog(stardis->allocator, &fluid_prog)); + fluid_prog->fluid_id = allocate_stardis_medium_id(stardis); + h_boundary_prog->mat_id = fluid_prog->fluid_id; + h_boundary_prog->possible_external_fluid = fluid_prog; + fluid_prog->desc_id = (unsigned)sz; + fluid_prog->temp = h_boundary_prog->fluid_temp; + fluid_prog->is_outside = 1; + fluid_prog->prog_data = h_boundary_prog->prog_data; + /* fluid_prog->release is NULL to avoid deleting shared prog_data */ + ERR(create_solver_external_fluid_prog(stardis, fluid_prog)); + logger_print(stardis->logger, LOG_OUTPUT, + "External programmed fluid created (it is medium %u)\n", + fluid_prog->fluid_id); + } + +end: + str_release(&tmp); + return res; +error: + goto end; +} + /* T_BOUNDARY_FOR_SOLID Name T STL_filenames */ static res_T process_t @@ -480,6 +686,130 @@ error: goto end; } +/* T_BOUNDARY_FOR_SOLID_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] */ +static res_T +process_t_prog + (struct stardis* stardis, + char** tok_ctx) +{ + char* tk = NULL; + struct description* desc; + const char* lib_name; + struct str tmp; + size_t sz; + struct t_boundary_prog* t_boundary_prog; + res_T res = RES_OK; + + ASSERT(stardis && tok_ctx); + + stardis->counts.fmed_count++; + + str_init(stardis->allocator, &tmp); + sz = darray_descriptions_size_get(&stardis->descriptions); + ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); + desc = darray_descriptions_data_get(&stardis->descriptions) + sz; + ERR(init_t_boundary_prog(stardis->allocator, &desc->d.t_boundary_prog)); + t_boundary_prog = desc->d.t_boundary_prog; + desc->type = DESC_BOUND_T_FOR_SOLID_PROG; + + ERR(get_dummy_fluid_id(stardis, &t_boundary_prog->mat_id)); + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed t boundary name"); + ERR(description_set_name(stardis, &t_boundary_prog->name, tk)); + if(find_description_by_name(stardis, &t_boundary_prog->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", tk); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); + ERR(str_set(&t_boundary_prog->prog_name, tk)); + lib_name = tk; + + ASSERT(sz <= UINT_MAX); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + + /* store the end of line as args for custom init */ + if(tok_ctx) { + ERR(str_set(&t_boundary_prog->args, *tok_ctx)); + } + /* get the user-defined functions from the library */ + t_boundary_prog->lib = library_open(lib_name); + if(!t_boundary_prog->lib) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open library: %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&t_boundary_prog->create + = library_get_symbol(t_boundary_prog->lib, "create_t_boundary_data"); + if(!t_boundary_prog->create) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'create_t_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&t_boundary_prog->init + = library_get_symbol(t_boundary_prog->lib, "init_t_boundary_data"); + if(!t_boundary_prog->init) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'init_t_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&t_boundary_prog->release + = library_get_symbol(t_boundary_prog->lib, "release_t_boundary_data"); + if(!t_boundary_prog->release) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'release_t_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&t_boundary_prog->temperature + = library_get_symbol(t_boundary_prog->lib, "boundary_temperature"); + if(!t_boundary_prog->temperature) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'boundary_temperature()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&t_boundary_prog->t_range + = library_get_symbol(t_boundary_prog->lib, "t_range"); + if(!t_boundary_prog->t_range) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 't_range()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + /* create and init custom data */ + t_boundary_prog->prog_data = t_boundary_prog->create(); + if(!t_boundary_prog->prog_data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create t_boundary_prog data %s\n", str_cget(&t_boundary_prog->name)); + res = RES_BAD_ARG; + goto error; + } + /* duplicate args to allow init() to modify them */ + ERR(str_copy(&tmp, &t_boundary_prog->args)); + if(STARDIS_SUCCESS != + t_boundary_prog->init(t_boundary_prog->prog_data, str_get(&tmp))) + { + logger_print(stardis->logger, LOG_ERROR, + "Cannot init t_boundary_prog data %s\n", str_cget(&t_boundary_prog->name)); + res = RES_BAD_ARG; + goto error; + } + + t_boundary_prog->t_range(t_boundary_prog->prog_data, stardis->t_range); + +end: + str_release(&tmp); + return res; +error: + goto end; +} + /* F_BOUNDARY_FOR_SOLID Name F STL_filenames */ static res_T process_flx @@ -541,21 +871,135 @@ error: goto end; } -/* SOLID_FLUID_CONNECTION Name ref_temperature emissivity specular_fraction hc STL_filenames */ +/* F_BOUNDARY_FOR_SOLID_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] */ static res_T -process_sfc +process_flx_prog (struct stardis* stardis, char** tok_ctx) { char* tk = NULL; struct description* desc; + const char* lib_name; + struct str tmp; size_t sz; - struct solid_fluid_connect* sf_connect; + struct f_boundary_prog* f_boundary_prog; res_T res = RES_OK; ASSERT(stardis && tok_ctx); - stardis->counts.sfconnect_count++; + stardis->counts.fmed_count++; + + str_init(stardis->allocator, &tmp); + sz = darray_descriptions_size_get(&stardis->descriptions); + ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); + desc = darray_descriptions_data_get(&stardis->descriptions) + sz; + ERR(init_f_boundary_prog(stardis->allocator, &desc->d.f_boundary_prog)); + f_boundary_prog = desc->d.f_boundary_prog; + desc->type = DESC_BOUND_F_FOR_SOLID_PROG; + + ERR(get_dummy_fluid_id(stardis, &f_boundary_prog->mat_id)); + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed t boundary name"); + ERR(description_set_name(stardis, &f_boundary_prog->name, tk)); + if(find_description_by_name(stardis, &f_boundary_prog->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", tk); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); + ERR(str_set(&f_boundary_prog->prog_name, tk)); + lib_name = tk; + + ASSERT(sz <= UINT_MAX); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + + /* store the end of line as args for custom init */ + if(tok_ctx) { + ERR(str_set(&f_boundary_prog->args, *tok_ctx)); + } + /* get the user-defined functions from the library */ + f_boundary_prog->lib = library_open(lib_name); + if(!f_boundary_prog->lib) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open library: %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&f_boundary_prog->create + = library_get_symbol(f_boundary_prog->lib, "create_f_boundary_data"); + if(!f_boundary_prog->create) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'create_f_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&f_boundary_prog->init + = library_get_symbol(f_boundary_prog->lib, "init_f_boundary_data"); + if(!f_boundary_prog->init) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'init_f_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&f_boundary_prog->release + = library_get_symbol(f_boundary_prog->lib, "release_f_boundary_data"); + if(!f_boundary_prog->release) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'release_f_boundary_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&f_boundary_prog->flux + = library_get_symbol(f_boundary_prog->lib, "boundary_flux"); + if(!f_boundary_prog->flux) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'boundary_flux()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + /* create and init custom data */ + f_boundary_prog->prog_data = f_boundary_prog->create(); + if(!f_boundary_prog->prog_data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create f_boundary_prog data %s\n", str_cget(&f_boundary_prog->name)); + res = RES_BAD_ARG; + goto error; + } + /* duplicate args to allow init() to modify them */ + ERR(str_copy(&tmp, &f_boundary_prog->args)); + if(STARDIS_SUCCESS != + f_boundary_prog->init(f_boundary_prog->prog_data, str_get(&tmp))) + { + logger_print(stardis->logger, LOG_ERROR, + "Cannot init f_boundary_prog data %s\n", str_cget(&f_boundary_prog->name)); + res = RES_BAD_ARG; + goto error; + } + +end: + str_release(&tmp); + return res; +error: + goto end; +} + +/* SOLID_FLUID_CONNECTION Name ref_temperature emissivity specular_fraction hc STL_filenames */ +static res_T +process_sfc + (struct stardis* stardis, + char** tok_ctx) +{ + char* tk = NULL; + struct description* desc; + size_t sz; + struct solid_fluid_connect* sf_connect; + res_T res = RES_OK; + + ASSERT(stardis && tok_ctx); + + stardis->counts.sfconnect_count++; sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); @@ -569,7 +1013,7 @@ process_sfc * we continue the trend to ensure connection ID is OK */ sf_connect->connection_id = allocate_stardis_medium_id(stardis); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid fluid connection name"); + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid-fluid connection name"); ERR(description_set_name(stardis, &sf_connect->name, tk)); if(find_description_by_name(stardis, &sf_connect->name, desc)) { logger_print(stardis->logger, LOG_ERROR, @@ -610,20 +1054,176 @@ process_sfc if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "hc"); + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "Convection coefficient"); res = cstr_to_double(tk, &sf_connect->hc); if(res != RES_OK || sf_connect->hc < 0) { - logger_print(stardis->logger, LOG_ERROR, "Invalid hc: %s\n", tk); + logger_print(stardis->logger, LOG_ERROR, + "Invalid Convection coefficient: %s\n", tk); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + + ASSERT(sz <= UINT_MAX); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + +end: + return res; +error: + goto end; +} + +/* SOLID_FLUID_CONNECTION_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] */ +static res_T +process_sfc_prog + (struct stardis* stardis, + char** tok_ctx) +{ + char* tk = NULL; + struct description* desc; + const char* lib_name; + struct str tmp; + size_t sz; + struct solid_fluid_connect_prog* sf_connect_prog; + res_T res = RES_OK; + + ASSERT(stardis && tok_ctx); + + stardis->counts.sfconnect_count++; + + str_init(stardis->allocator, &tmp); + sz = darray_descriptions_size_get(&stardis->descriptions); + ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); + desc = darray_descriptions_data_get(&stardis->descriptions) + sz; + ERR(init_sf_connect_prog(stardis->allocator, &desc->d.sf_connect_prog)); + sf_connect_prog = desc->d.sf_connect_prog; + desc->type = DESC_SOLID_FLUID_CONNECT_PROG; + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), + "programmed solid-fluid connection name"); + ERR(description_set_name(stardis, &sf_connect_prog->name, tk)); + if(find_description_by_name(stardis, &sf_connect_prog->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", tk); if(res == RES_OK) res = RES_BAD_ARG; goto end; } + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); + ERR(str_set(&sf_connect_prog->prog_name, tk)); + lib_name = tk; + ASSERT(sz <= UINT_MAX); ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + /* store the end of line as args for custom init */ + if(tok_ctx) { + ERR(str_set(&sf_connect_prog->args, *tok_ctx)); + } + /* get the user-defined functions from the library */ + sf_connect_prog->lib = library_open(lib_name); + if(!sf_connect_prog->lib) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open library: %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->create + = library_get_symbol(sf_connect_prog->lib, "create_sf_connect_data"); + if(!sf_connect_prog->create) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'create_sf_connect_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->init + = library_get_symbol(sf_connect_prog->lib, "init_sf_connect_data"); + if(!sf_connect_prog->init) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'init_sf_connect_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->release + = library_get_symbol(sf_connect_prog->lib, "release_sf_connect_data"); + if(!sf_connect_prog->release) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'release_sf_connect_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->ref_temp + = library_get_symbol(sf_connect_prog->lib, "reference_temperature"); + if(!sf_connect_prog->ref_temp) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'reference_temperature()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->emissivity + = library_get_symbol(sf_connect_prog->lib, "emissivity"); + if(!sf_connect_prog->emissivity) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'emissivity()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->alpha + = library_get_symbol(sf_connect_prog->lib, "specular_fraction"); + if(!sf_connect_prog->alpha) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'specular_fraction()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->hc + = library_get_symbol(sf_connect_prog->lib, "convection_coefficient"); + if(!sf_connect_prog->hc) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'convection_coefficient()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->hmax + = library_get_symbol(sf_connect_prog->lib, "max_convection_coefficient"); + if(!sf_connect_prog->hmax) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'max_convection_coefficient()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&sf_connect_prog->t_range + = library_get_symbol(sf_connect_prog->lib, "t_range"); + if(!sf_connect_prog->t_range) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 't_range()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + /* create and init custom data */ + sf_connect_prog->prog_data = sf_connect_prog->create(); + if(!sf_connect_prog->prog_data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create sf_connect_prog data %s\n", str_cget(&sf_connect_prog->name)); + res = RES_BAD_ARG; + goto error; + } + /* duplicate args to allow init() to modify them */ + ERR(str_copy(&tmp, &sf_connect_prog->args)); + if(STARDIS_SUCCESS != + sf_connect_prog->init(sf_connect_prog->prog_data, str_get(&tmp))) + { + logger_print(stardis->logger, LOG_ERROR, + "Cannot init sf_connect_prog data %s\n", str_cget(&sf_connect_prog->name)); + res = RES_BAD_ARG; + goto error; + } + + sf_connect_prog->t_range(sf_connect_prog->prog_data, stardis->t_range); + end: + str_release(&tmp); return res; error: goto end; @@ -657,7 +1257,7 @@ process_ssc * we continue the trend to ensure connection ID is OK */ ss_connect->connection_id = allocate_stardis_medium_id(stardis); - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid solid connection name"); + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "solid-solid connection name"); ERR(description_set_name(stardis, &ss_connect->name, tk)); if(find_description_by_name(stardis, &ss_connect->name, desc)) { logger_print(stardis->logger, LOG_ERROR, @@ -691,6 +1291,119 @@ error: goto end; } +/* SOLID_SOLID_CONNECTION_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] */ +static res_T +process_ssc_prog + (struct stardis* stardis, + char** tok_ctx) +{ + char* tk = NULL; + struct description* desc; + const char* lib_name; + struct str tmp; + size_t sz; + struct solid_solid_connect_prog* ss_connect_prog; + res_T res = RES_OK; + + ASSERT(stardis && tok_ctx); + + stardis->counts.sfconnect_count++; + + str_init(stardis->allocator, &tmp); + sz = darray_descriptions_size_get(&stardis->descriptions); + ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); + desc = darray_descriptions_data_get(&stardis->descriptions) + sz; + ERR(init_ss_connect_prog(stardis->allocator, &desc->d.ss_connect_prog)); + ss_connect_prog = desc->d.ss_connect_prog; + desc->type = DESC_SOLID_SOLID_CONNECT_PROG; + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), + "programmed solid-solid connection name"); + ERR(description_set_name(stardis, &ss_connect_prog->name, tk)); + if(find_description_by_name(stardis, &ss_connect_prog->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", tk); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); + ERR(str_set(&ss_connect_prog->prog_name, tk)); + lib_name = tk; + + ASSERT(sz <= UINT_MAX); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, tok_ctx)); + + /* store the end of line as args for custom init */ + if(tok_ctx) { + ERR(str_set(&ss_connect_prog->args, *tok_ctx)); + } + /* get the user-defined functions from the library */ + ss_connect_prog->lib = library_open(lib_name); + if(!ss_connect_prog->lib) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open library: %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&ss_connect_prog->create + = library_get_symbol(ss_connect_prog->lib, "create_ss_connect_data"); + if(!ss_connect_prog->create) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'create_ss_connect_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&ss_connect_prog->init + = library_get_symbol(ss_connect_prog->lib, "init_ss_connect_data"); + if(!ss_connect_prog->init) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'init_ss_connect_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&ss_connect_prog->release + = library_get_symbol(ss_connect_prog->lib, "release_ss_connect_data"); + if(!ss_connect_prog->release) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'release_ss_connect_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&ss_connect_prog->tcr + = library_get_symbol(ss_connect_prog->lib, "thermal_contact_resistance"); + if(!ss_connect_prog->tcr) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'thermal_contact_resistance()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + /* create and init custom data */ + ss_connect_prog->prog_data = ss_connect_prog->create(); + if(!ss_connect_prog->prog_data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create ss_connect_prog data %s\n", str_cget(&ss_connect_prog->name)); + res = RES_BAD_ARG; + goto error; + } + /* duplicate args to allow init() to modify them */ + ERR(str_copy(&tmp, &ss_connect_prog->args)); + if(STARDIS_SUCCESS != + ss_connect_prog->init(ss_connect_prog->prog_data, str_get(&tmp))) + { + logger_print(stardis->logger, LOG_ERROR, + "Cannot init ss_connect_prog data %s\n", str_cget(&ss_connect_prog->name)); + res = RES_BAD_ARG; + goto error; + } + +end: + str_release(&tmp); + return res; +error: + goto end; +} + static res_T read_imposed_temperature (struct stardis* stardis, @@ -886,6 +1599,171 @@ error: goto end; } +/* SOLID_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] */ +static res_T +process_solid_prog + (struct stardis* stardis, + char** tok_ctx) +{ + char* tk = NULL; + struct description* desc; + const char* lib_name; + struct str tmp; + size_t sz; + struct solid_prog* solid_prog; + res_T res = RES_OK; + + ASSERT(stardis && tok_ctx); + + stardis->counts.fmed_count++; + + str_init(stardis->allocator, &tmp); + sz = darray_descriptions_size_get(&stardis->descriptions); + ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); + desc = darray_descriptions_data_get(&stardis->descriptions) + sz; + ERR(init_solid_prog(stardis->allocator, &desc->d.solid_prog)); + solid_prog = desc->d.solid_prog; + desc->type = DESC_MAT_SOLID_PROG; + solid_prog->solid_id = allocate_stardis_medium_id(stardis); + ASSERT(sz <= UINT_MAX); + solid_prog->desc_id = (unsigned)sz; + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed solid name"); + ERR(description_set_name(stardis, &solid_prog->name, tk)); + if(find_description_by_name(stardis, &solid_prog->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", tk); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "program name"); + ERR(str_set(&solid_prog->prog_name, tk)); + lib_name = tk; + + ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); + + /* store the end of line as args for custom init */ + if(tok_ctx) { + ERR(str_set(&solid_prog->args, *tok_ctx)); + } + /* get the user-defined functions from the library */ + solid_prog->lib = library_open(lib_name); + if(!solid_prog->lib) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open library: %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->create + = library_get_symbol(solid_prog->lib, "create_solid_data"); + if(!solid_prog->create) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'create_solid_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->init + = library_get_symbol(solid_prog->lib, "init_solid_data"); + if(!solid_prog->init) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'init_solid_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->release + = library_get_symbol(solid_prog->lib, "release_solid_data"); + if(!solid_prog->release) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'release_solid_data' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->lambda + = library_get_symbol(solid_prog->lib, "conductivity"); + if(!solid_prog->lambda) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'conductivity()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->rho + = library_get_symbol(solid_prog->lib, "volumic_mass"); + if(!solid_prog->rho) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'volumic_mass()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->cp + = library_get_symbol(solid_prog->lib, "calorific_capacity"); + if(!solid_prog->cp) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'calorific_capacity()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->delta + = library_get_symbol(solid_prog->lib, "delta_solid"); + if(!solid_prog->delta) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'delta_solid()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->temp + = library_get_symbol(solid_prog->lib, "temperature"); + if(!solid_prog->temp) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'temperature()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->vpower + = library_get_symbol(solid_prog->lib, "volumic_power"); + if(!solid_prog->vpower) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'volumic_power()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&solid_prog->t_range + = library_get_symbol(solid_prog->lib, "t_range"); + if(!solid_prog->t_range) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 't_range()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + /* create and init custom data */ + solid_prog->prog_data = solid_prog->create(); + if(!solid_prog->prog_data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create solid_prog data %s\n", str_cget(&solid_prog->name)); + res = RES_BAD_ARG; + goto error; + } + /* duplicate args to allow init() to modify them */ + ERR(str_copy(&tmp, &solid_prog->args)); + if(STARDIS_SUCCESS != solid_prog->init(solid_prog->prog_data, str_get(&tmp))) + { + logger_print(stardis->logger, LOG_ERROR, + "Cannot init solid_prog data %s\n", str_cget(&solid_prog->name)); + res = RES_BAD_ARG; + goto error; + } + + solid_prog->t_range(solid_prog->prog_data, stardis->t_range); + + ERR(create_solver_solid_prog(stardis, solid_prog)); + +end: + str_release(&tmp); + return res; +error: + goto end; +} + /* FLUID Name rho cp Tinit Timposed STL_filenames */ static res_T process_fluid @@ -995,6 +1873,7 @@ process_fluid_prog stardis->counts.fmed_count++; + str_init(stardis->allocator, &tmp); sz = darray_descriptions_size_get(&stardis->descriptions); ERR(darray_descriptions_resize(&stardis->descriptions, sz + 1)); desc = darray_descriptions_data_get(&stardis->descriptions) + sz; @@ -1005,7 +1884,7 @@ process_fluid_prog ASSERT(sz <= UINT_MAX); fluid_prog->desc_id = (unsigned)sz; - CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "fluid name"); + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "programmed fluid name"); ERR(description_set_name(stardis, &fluid_prog->name, tk)); if(find_description_by_name(stardis, &fluid_prog->name, desc)) { logger_print(stardis->logger, LOG_ERROR, @@ -1024,7 +1903,7 @@ process_fluid_prog if(tok_ctx) { ERR(str_set(&fluid_prog->args, *tok_ctx)); } - + /* get the user-defined functions from the library */ fluid_prog->lib = library_open(lib_name); if(!fluid_prog->lib) { logger_print(stardis->logger, LOG_ERROR, @@ -1040,13 +1919,6 @@ process_fluid_prog res = RES_BAD_ARG; goto error; } - fluid_prog->prog_data = fluid_prog->create(); - if(!fluid_prog->prog_data) { - logger_print(stardis->logger, LOG_ERROR, - "Cannot create fluid data %s\n", str_cget(&fluid_prog->name)); - res = RES_BAD_ARG; - goto error; - } *(void**)&fluid_prog->init = library_get_symbol(fluid_prog->lib, "init_fluid_data"); if(!fluid_prog->init) { @@ -1055,15 +1927,6 @@ process_fluid_prog res = RES_BAD_ARG; goto error; } - /* duplicate args to allow init() to modify them */ - str_init(stardis->allocator, &tmp); - ERR(str_copy(&tmp, &fluid_prog->args)); - if(fluid_prog->init(fluid_prog->prog_data, str_get(&tmp))) { - logger_print(stardis->logger, LOG_ERROR, - "Cannot init fluid_prog data %s\n", str_cget(&fluid_prog->name)); - res = RES_BAD_ARG; - goto error; - } *(void**)&fluid_prog->release = library_get_symbol(fluid_prog->lib, "release_fluid_data"); if(!fluid_prog->release) { @@ -1072,14 +1935,6 @@ process_fluid_prog res = RES_BAD_ARG; goto error; } - *(void**)&fluid_prog->cp - = library_get_symbol(fluid_prog->lib, "calorific_capacity"); - if(!fluid_prog->cp) { - logger_print(stardis->logger, LOG_ERROR, - "Cannot find function 'calorific_capacity()' in lib %s\n", lib_name); - res = RES_BAD_ARG; - goto error; - } *(void**)&fluid_prog->rho = library_get_symbol(fluid_prog->lib, "volumic_mass"); if(!fluid_prog->rho) { @@ -1088,6 +1943,14 @@ process_fluid_prog res = RES_BAD_ARG; goto error; } + *(void**)&fluid_prog->cp + = library_get_symbol(fluid_prog->lib, "calorific_capacity"); + if(!fluid_prog->cp) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'calorific_capacity()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } *(void**)&fluid_prog->temp = library_get_symbol(fluid_prog->lib, "temperature"); if(!fluid_prog->temp) { @@ -1096,10 +1959,38 @@ process_fluid_prog res = RES_BAD_ARG; goto error; } + *(void**)&fluid_prog->t_range + = library_get_symbol(fluid_prog->lib, "t_range"); + if(!fluid_prog->t_range) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 't_range()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + /* create and init custom data */ + fluid_prog->prog_data = fluid_prog->create(); + if(!fluid_prog->prog_data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create fluid_prog data %s\n", str_cget(&fluid_prog->name)); + res = RES_BAD_ARG; + goto error; + } + /* duplicate args to allow init() to modify them */ + ERR(str_copy(&tmp, &fluid_prog->args)); + if(STARDIS_SUCCESS != fluid_prog->init(fluid_prog->prog_data, str_get(&tmp))) + { + logger_print(stardis->logger, LOG_ERROR, + "Cannot init fluid_prog data %s\n", str_cget(&fluid_prog->name)); + res = RES_BAD_ARG; + goto error; + } + + fluid_prog->t_range(fluid_prog->prog_data, stardis->t_range); ERR(create_solver_fluid_prog(stardis, fluid_prog)); end: + str_release(&tmp); return res; error: goto end; @@ -1215,18 +2106,32 @@ process_model_line if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_SOLID")) ERR(process_h(stardis, DESC_BOUND_H_FOR_SOLID, &tok_ctx)); + else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_SOLID_PROG")) + ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_SOLID_PROG, &tok_ctx)); else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_FLUID")) ERR(process_h(stardis, DESC_BOUND_H_FOR_FLUID, &tok_ctx)); + else if(0 == strcasecmp(tk, "H_BOUNDARY_FOR_FLUID_PROG")) + ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_FLUID_PROG, &tok_ctx)); else if(0 == strcasecmp(tk, "T_BOUNDARY_FOR_SOLID")) ERR(process_t(stardis, &tok_ctx)); + else if(0 == strcasecmp(tk, "T_BOUNDARY_FOR_SOLID_PROG")) + ERR(process_t_prog(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "F_BOUNDARY_FOR_SOLID")) ERR(process_flx(stardis, &tok_ctx)); + else if(0 == strcasecmp(tk, "F_BOUNDARY_FOR_SOLID_PROG")) + ERR(process_flx_prog(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "SOLID_FLUID_CONNECTION")) ERR(process_sfc(stardis, &tok_ctx)); + else if(0 == strcasecmp(tk, "SOLID_FLUID_CONNECTION_PROG")) + ERR(process_sfc_prog(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "SOLID_SOLID_CONNECTION")) ERR(process_ssc(stardis, &tok_ctx)); + else if(0 == strcasecmp(tk, "SOLID_SOLID_CONNECTION_PROG")) + ERR(process_ssc_prog(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "SOLID")) ERR(process_solid(stardis, &tok_ctx)); + else if(0 == strcasecmp(tk, "SOLID_PROG")) + ERR(process_solid_prog(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "FLUID")) ERR(process_fluid(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "FLUID_PROG")) diff --git a/src/stardis-parsing.h b/src/stardis-parsing.h @@ -23,11 +23,8 @@ #include <star/sstl.h> -struct camera; struct logger; -struct mem_allocator; struct stardis; -struct dummies; /* Utility macros */ #define CHK_TOK(x, Name) if((tk = (x)) == NULL) {\ @@ -46,36 +43,30 @@ struct add_geom_ctx { /* Possible callbacks for sg3d_geometry_add calls * when void* context is a struct add_geom_ctx */ -extern LOCAL_SYM void +void add_geom_ctx_indices (const unsigned itri, unsigned ids[3], void* context); -extern LOCAL_SYM void -add_geom_ctx_properties - (const unsigned itri, - unsigned prop[3], - void* context); - -extern LOCAL_SYM void +void add_geom_ctx_position (const unsigned ivert, double pos[3], void* context); -extern LOCAL_SYM res_T +res_T process_model_line (const char* file_name, char* line, struct stardis* stardis); -extern LOCAL_SYM res_T +res_T get_dummy_solid_id (struct stardis* stardis, unsigned* id); -extern LOCAL_SYM res_T +res_T get_dummy_fluid_id (struct stardis* stardis, unsigned* id); diff --git a/src/stardis-prog.h b/src/stardis-prog.h @@ -14,18 +14,31 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef STARDIS_PROG_COMMON_H__ -#define STARDIS_PROG_COMMON_H__ +#ifndef STARDIS_PROG_H__ +#define STARDIS_PROG_H__ -enum stardis_return_codes { +enum stardis_return_code { STARDIS_SUCCESS, STARDIS_FAILURE }; -struct walk_vertex { +struct stardis_walk_vertex { double P[3]; /* World space position */ double time; /* "Time" of the vertex */ }; +enum stardis_side { + FRONT, + BACK +}; + +struct stardis_interface_fragment { + double P[3]; /* World space position */ + double Ng[3]; /* Normalized world space geometry normal at the interface */ + double uv[2]; /* Parametric coordinates of the interface */ + double time; /* Current time */ + enum stardis_side side; +}; + #endif diff --git a/src/stardis-sfconnect-prog.c b/src/stardis-sfconnect-prog.c @@ -0,0 +1,99 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "stardis-app.h" +#include "stardis-sfconnect-prog.h" +#include "stardis-prog.h" +#include "stardis-intface.h" + +#include <rsys/rsys.h> +#include <rsys/mem_allocator.h> +#include <rsys/str.h> + +#include <sdis.h> + +#include <limits.h> + +/******************************************************************************* + * Public Functions + ******************************************************************************/ +res_T +init_sf_connect_prog + (struct mem_allocator* allocator, + struct solid_fluid_connect_prog** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_init(allocator, &(*dst)->prog_name); + str_init(allocator, &(*dst)->args); + str_initialized = 1; + (*dst)->connection_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) { + str_release(&(*dst)->name); + str_release(&(*dst)->prog_name); + str_release(&(*dst)->args); + } + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_sf_connect_prog + (struct solid_fluid_connect_prog* connect, + struct mem_allocator* allocator) +{ + ASSERT(connect && allocator); + str_release(&connect->name); + str_release(&connect->prog_name); + str_release(&connect->args); + if(connect->prog_data) + connect->release(connect->prog_data); + MEM_RM(allocator, connect); +} + +res_T +str_print_sf_connect_prog + (struct str* str, + const struct solid_fluid_connect_prog* connect) +{ + res_T res = RES_OK; + ASSERT(str && connect); + ERR(str_append_printf(str, + "programmed Solid-Fluid connection '%s': lib='%s', args=[%s]", + str_cget(&connect->name), str_cget(&connect->prog_name), + str_cget(&connect->args))); +end: + return res; +error: + goto end; +} + +double +sf_connect_prog_get_hmax + (const struct solid_fluid_connect_prog* connect) +{ + return connect->hmax(connect->prog_data); +} + diff --git a/src/stardis-sfconnect-prog.h b/src/stardis-sfconnect-prog.h @@ -0,0 +1,76 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SDIS_SF_CONNECT_PROG_H +#define SDIS_SF_CONNECT_PROG_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +#include "stardis-prog.h" + +struct stardis; +struct mem_allocator; +struct sdis_rwalk_vertex; + +/******************************************************************************* + * Solid-Fluid prog data + ******************************************************************************/ +struct solid_fluid_connect_prog { + void* prog_data; /* result of the init_fluid() call */ + struct str name; + struct str prog_name; + struct str args; + int is_outside; /* the fluid is used for a boundary */ + unsigned desc_id; /* id of the boundary; meaningful if is_outside */ + unsigned connection_id; + /* lib handle and function ptrs */ + void* lib; + void* (*create)(); + enum stardis_return_code (*init)(void*, const char*); + void (*release)(void*); + double (*ref_temp)(const struct sdis_interface_fragment*, void*); + double (*emissivity)(const struct sdis_interface_fragment*, void*); + double (*alpha)(const struct sdis_interface_fragment*, void*); + double (*hc)(const struct sdis_interface_fragment*, void*); + double (*hmax)(void*); + double* (*t_range)(void*, double trange[2]); +}; + +res_T +create_solver_sf_connect_prog + (struct stardis* stardis, + const struct solid_fluid_connect_prog* connect); + +res_T +init_sf_connect_prog + (struct mem_allocator* allocator, + struct solid_fluid_connect_prog** dst); + +void +release_sf_connect_prog + (struct solid_fluid_connect_prog* connect, + struct mem_allocator* allocator); + +res_T +str_print_sf_connect_prog + (struct str* str, + const struct solid_fluid_connect_prog* connect); + +double +sf_connect_prog_get_hmax + (const struct solid_fluid_connect_prog* connect); + +#endif diff --git a/src/stardis-solid-prog.c b/src/stardis-solid-prog.c @@ -0,0 +1,181 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "stardis-solid-prog.h" +#include "stardis-prog.h" +#include "stardis-compute.h" +#include "stardis-app.h" + +#include <rsys/mem_allocator.h> + +#include <sdis.h> + +#include <limits.h> + +/******************************************************************************* + * Local Functions + ******************************************************************************/ + +static double +solid_prog_get_thermal_conductivity + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct solid_prog* const* solid_props = sdis_data_cget(data); + return (*solid_props)->lambda(vtx, (*solid_props)->prog_data); +} + +static double +solid_prog_get_volumic_mass + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct solid_prog* const* solid_props = sdis_data_cget(data); + return (*solid_props)->rho(vtx, (*solid_props)->prog_data); +} + +static double +solid_prog_get_calorific_capacity + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct solid_prog* const* solid_props = sdis_data_cget(data); + return (*solid_props)->cp(vtx, (*solid_props)->prog_data); +} + +static double +solid_prog_get_delta_solid + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct solid_prog* const* solid_props = sdis_data_cget(data); + return (*solid_props)->delta(vtx, (*solid_props)->prog_data); +} + +static double +solid_prog_get_volumic_power + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct solid_prog* const* solid_props = sdis_data_cget(data); + return (*solid_props)->vpower(vtx, (*solid_props)->prog_data); +} + +static double +solid_prog_get_temperature + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct solid_prog* const* solid_props = sdis_data_cget(data); + return (*solid_props)->temp(vtx, (*solid_props)->prog_data); +} + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +res_T +create_solver_solid_prog + (struct stardis* stardis, + const struct solid_prog* solid_props) +{ + res_T res = RES_OK; + struct sdis_solid_shader solid_shader = SDIS_SOLID_SHADER_NULL; + struct sdis_data* data = NULL; + const struct solid_prog** props; + + ASSERT(stardis && solid_props); + solid_shader.calorific_capacity = solid_prog_get_calorific_capacity; + solid_shader.thermal_conductivity = solid_prog_get_thermal_conductivity; + solid_shader.volumic_mass = solid_prog_get_volumic_mass; + solid_shader.delta_solid = solid_prog_get_delta_solid; + solid_shader.volumic_power = solid_prog_get_volumic_power; + solid_shader.temperature = solid_prog_get_temperature; + ERR(sdis_data_create(stardis->dev, sizeof(struct solid_prog*), + ALIGNOF(struct solid_prog*), NULL, &data)); + + props = sdis_data_get(data); /* Fetch the allocated memory space */ + *props = solid_props; + if(solid_props->solid_id >= darray_media_ptr_size_get(&stardis->media)) { + ERR(darray_media_ptr_resize(&stardis->media, solid_props->solid_id + 1)); + } + ASSERT(!darray_media_ptr_data_get(&stardis->media)[solid_props->solid_id]); + ERR(sdis_solid_create(stardis->dev, &solid_shader, data, + darray_media_ptr_data_get(&stardis->media) + solid_props->solid_id)); + +end: + if(data) SDIS(data_ref_put(data)); + return res; +error: + goto end; +} + +res_T +init_solid_prog(struct mem_allocator* allocator, struct solid_prog** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_init(allocator, &(*dst)->prog_name); + str_init(allocator, &(*dst)->args); + str_initialized = 1; + (*dst)->desc_id = UINT_MAX; + (*dst)->solid_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) { + str_release(&(*dst)->name); + str_release(&(*dst)->prog_name); + str_release(&(*dst)->args); + } + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_solid_prog + (struct solid_prog* solid, + struct mem_allocator* allocator) +{ + ASSERT(solid && allocator); + str_release(&solid->name); + str_release(&solid->prog_name); + str_release(&solid->args); + + if(solid->prog_data) + solid->release(solid->prog_data); + MEM_RM(allocator, solid); +} + +res_T +str_print_solid_prog(struct str* str, const struct solid_prog* f) +{ + res_T res = RES_OK; + ASSERT(str && f); + STR_APPEND_PRINTF(str, "programmed solid '%s': lib='%s', args=[%s]", + ARG3( str_cget(&f->name), str_cget(&f->prog_name), str_cget(&f->args) ) ); + STR_APPEND_PRINTF(str, " (it is medium %u)", ARG1( f->solid_id ) ); +end: + return res; +error: + goto end; +} diff --git a/src/stardis-solid-prog.h b/src/stardis-solid-prog.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SDIS_SOLID_PROG_H +#define SDIS_SOLID_PROG_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +#include "stardis-prog.h" + +struct stardis; +struct sdis_rwalk_vertex; +struct mem_allocator; + +/******************************************************************************* + * Solid prog data + ******************************************************************************/ +struct solid_prog { + void* prog_data; /* result of the init_solid() call */ + struct str name; + struct str prog_name; + struct str args; + int is_outside; /* the solid is used for a boundary */ + unsigned desc_id; /* id of the boundary; meaningful if is_outside */ + unsigned solid_id; + /* lib handle and function ptrs */ + void* lib; + void* (*create)(); + enum stardis_return_code (*init)(void*, const char*); + void (*release)(void*); + double (*lambda)(const struct sdis_rwalk_vertex*, void*); + double (*rho)(const struct sdis_rwalk_vertex*, void*); + double (*cp)(const struct sdis_rwalk_vertex*, void*); + double (*delta)(const struct sdis_rwalk_vertex*, void*); + double (*temp)(const struct sdis_rwalk_vertex*, void*); + double (*vpower)(const struct sdis_rwalk_vertex*, void*); + double* (*t_range)(void*, double trange[2]); +}; + +res_T +create_solver_solid_prog + (struct stardis* stardis, + const struct solid_prog* solid_props); + +res_T +init_solid_prog + (struct mem_allocator* allocator, + struct solid_prog** dst); + +void +release_solid_prog + (struct solid_prog* solid, + struct mem_allocator* allocator); + +res_T +str_print_solid_prog + (struct str* str, + const struct solid_prog* s); + +#endif diff --git a/src/stardis-solid.h b/src/stardis-solid.h @@ -41,18 +41,18 @@ struct solid { unsigned solid_id; }; -LOCAL_SYM res_T +res_T init_solid(struct mem_allocator* allocator, struct solid** dst); -LOCAL_SYM void +void release_solid (struct solid* desc, struct mem_allocator* allocator); -LOCAL_SYM res_T +res_T str_print_solid(struct str* str, const struct solid* solid); -LOCAL_SYM res_T +res_T create_solver_solid (struct stardis* stardis, const struct solid* solid_props); diff --git a/src/stardis-ssconnect-prog.c b/src/stardis-ssconnect-prog.c @@ -0,0 +1,92 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "stardis-app.h" +#include "stardis-ssconnect-prog.h" +#include "stardis-prog.h" +#include "stardis-intface.h" + +#include <rsys/rsys.h> +#include <rsys/mem_allocator.h> +#include <rsys/str.h> + +#include <sdis.h> + +#include <limits.h> + +/******************************************************************************* + * Public Functions + ******************************************************************************/ +res_T +init_ss_connect_prog + (struct mem_allocator* allocator, + struct solid_solid_connect_prog** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_init(allocator, &(*dst)->prog_name); + str_init(allocator, &(*dst)->args); + str_initialized = 1; + (*dst)->connection_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) { + str_release(&(*dst)->name); + str_release(&(*dst)->prog_name); + str_release(&(*dst)->args); + } + (*dst)->connection_id = UINT_MAX; + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_ss_connect_prog + (struct solid_solid_connect_prog* connect, + struct mem_allocator* allocator) +{ + ASSERT(connect && allocator); + str_release(&connect->name); + str_release(&connect->prog_name); + str_release(&connect->args); + if(connect->prog_data) + connect->release(connect->prog_data); + MEM_RM(allocator, connect); +} + +res_T +str_print_ss_connect_prog + (struct str* str, + const struct solid_solid_connect_prog* connect) +{ + res_T res = RES_OK; + ASSERT(str && connect); + ERR(str_append_printf(str, + "programmed Solid-Solid connection '%s': lib='%s', args=[%s]", + str_cget(&connect->name), str_cget(&connect->prog_name), + str_cget(&connect->args))); +end: + return res; +error: + goto end; +} diff --git a/src/stardis-ssconnect-prog.h b/src/stardis-ssconnect-prog.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SDIS_SS_CONNECT_PROG_H +#define SDIS_SS_CONNECT_PROG_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +#include "stardis-prog.h" + +struct stardis; +struct mem_allocator; +struct sdis_rwalk_vertex; + +/******************************************************************************* + * Solid-Solid prog data + ******************************************************************************/ +struct solid_solid_connect_prog { + void* prog_data; /* result of the init_sf_connect() call */ + struct str name; + struct str prog_name; + struct str args; + /* lib handle and function ptrs */ + void* lib; + double (*tcr)(const struct sdis_interface_fragment*, void*); + void* (*create)(); + enum stardis_return_code (*init)(void*, const char*); + void (*release)(void*); + unsigned connection_id; +}; + +res_T +create_solver_ss_connect_prog + (struct stardis* stardis, + const struct solid_solid_connect_prog* connect); + +res_T +init_ss_connect_prog + (struct mem_allocator* allocator, + struct solid_solid_connect_prog** dst); + +void +release_ss_connect_prog + (struct solid_solid_connect_prog* connect, + struct mem_allocator* allocator); + +res_T +str_print_ss_connect_prog + (struct str* str, + const struct solid_solid_connect_prog* connect); + +#endif + diff --git a/src/stardis-tbound-prog.c b/src/stardis-tbound-prog.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "stardis-app.h" +#include "stardis-tbound-prog.h" +#include "stardis-prog.h" +#include "stardis-intface.h" + +#include <rsys/rsys.h> +#include <rsys/mem_allocator.h> +#include <rsys/str.h> + +#include <sdis.h> + +#include <limits.h> + +/******************************************************************************* + * Public Functions + ******************************************************************************/ +res_T +init_t_boundary_prog + (struct mem_allocator* allocator, + struct t_boundary_prog** dst) +{ + res_T res = RES_OK; + int str_initialized = 0; + ASSERT(allocator && dst && *dst == NULL); + *dst = MEM_CALLOC(allocator, 1, sizeof(**dst)); + if(! *dst) { + res = RES_MEM_ERR; + goto error; + } + str_init(allocator, &(*dst)->name); + str_init(allocator, &(*dst)->prog_name); + str_init(allocator, &(*dst)->args); + str_initialized = 1; + (*dst)->mat_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) { + str_release(&(*dst)->name); + str_release(&(*dst)->prog_name); + str_release(&(*dst)->args); + } + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_t_boundary_prog + (struct t_boundary_prog* bound, + struct mem_allocator* allocator) +{ + ASSERT(bound && allocator); + str_release(&bound->name); + str_release(&bound->prog_name); + str_release(&bound->args); + if(bound->prog_data) + bound->release(bound->prog_data); + MEM_RM(allocator, bound); +} + +res_T +str_print_t_boundary_prog + (struct str* str, + const struct t_boundary_prog* b) +{ + res_T res = RES_OK; + ASSERT(str && b); + ERR(str_append_printf(str, + "programmed T boundary for solid '%s': lib='%s', args=[%s] " + "(using medium %u as external medium)", + str_cget(&b->name), str_cget(&b->prog_name), str_cget(&b->args), + b->mat_id)); +end: + return res; +error: + goto end; +} + diff --git a/src/stardis-tbound-prog.h b/src/stardis-tbound-prog.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2018-2021 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SDIS_TBOUND_PROG_H +#define SDIS_TBOUND_PROG_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +#include "stardis-prog.h" + +struct stardis; +struct mem_allocator; +struct fluid_prog; +struct description; + +struct sdis_interface_fragment; +struct sdis_rwalk_vertex; +struct sdis_data; + +/******************************************************************************* + * T boundary prog data + ******************************************************************************/ +struct t_boundary_prog { + void* prog_data; /* result of the init_t_prog() call */ + struct str name; + struct str prog_name; + struct str args; + /* lib handle and function ptrs */ + void* lib; + void* (*create)(); + enum stardis_return_code (*init)(void*, const char*); + void (*release)(void*); + double (*temperature)(const struct sdis_interface_fragment*, void*); + double* (*t_range)(void*, double trange[2]); + unsigned mat_id; +}; + +res_T +init_t_boundary_prog + (struct mem_allocator* allocator, + struct t_boundary_prog** dst); + +void +release_t_boundary_prog + (struct t_boundary_prog* bound, + struct mem_allocator* allocator); + +res_T +str_print_t_boundary_prog + (struct str* str, + const struct t_boundary_prog* b); + +#endif +