stardis

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

commit 97b76349f634e049e0d4b42a723802cd21c77bfd
parent d53d73c85ea4d713087edd9c8750d9d13e536a10
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 23 Sep 2022 12:07:24 +0200

Merge branch 'feature-hfbound' into develop

Diffstat:
Mcmake/CMakeLists.txt | 4++++
Mdoc/stardis-input.5.txt | 11+++++++++--
Mdoc/stardis-output.5.txt | 33++++++++++++++++++---------------
Msrc/stardis-app.c | 13+++++++++++++
Msrc/stardis-app.h | 3+++
Msrc/stardis-description.c | 24++++++++++++++++++++++++
Msrc/stardis-description.h | 10++++++++++
Msrc/stardis-hbound.h | 2--
Asrc/stardis-hfbound-prog.c | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-hfbound-prog.h | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-hfbound.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-hfbound.h | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-intface.c | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/stardis-parsing.c | 224++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/stardis-prog-properties.h.in | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 files changed, 788 insertions(+), 21 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -159,6 +159,8 @@ set(SDIS_FILES_SRC stardis-fbound-prog.c stardis-hbound.c stardis-hbound-prog.c + stardis-hfbound.c + stardis-hfbound-prog.c stardis-intface.c stardis-main.c stardis-output.c @@ -186,6 +188,8 @@ set(SDIS_FILES_INC stardis-green-types.h.in stardis-hbound.h stardis-hbound-prog.h + stardis-hfbound.h + stardis-hfbound-prog.h stardis-intface.h stardis-output.h stardis-parsing.h diff --git a/doc/stardis-input.5.txt b/doc/stardis-input.5.txt @@ -102,9 +102,11 @@ _______ | <h-bound-for-solid> | <h-bound-for-fluid> | <f-bound-for-solid> + | <hf-bound-for-solid> | <prog-t-bound-for-solid> | <prog-h-bound-for-solid> | <prog-h-bound-for-fluid> + | <prog-hf-bound-for-fluid> | <prog-f-bound-for-solid> <media-connection> ::= <solid-fluid-connect> @@ -125,11 +127,14 @@ _______ <t-bound-for-solid> ::= "T_BOUNDARY_FOR_SOLID" <bound-name> <temperature> \ <triangles> - <h-bound-for-solid> ::= "H_BOUNDARY_FOR_SOLID" <bound-name> <Tref> <emissivity> \ <specular-fraction> <hc> <outside-temperature> \ <triangles> +<hf-bound-for-solid> ::= "HF_BOUNDARY_FOR_SOLID" <bound-name> <Tref> <emissivity> \ + <specular-fraction> <hc> <outside-temperature> <flux> \ + <triangles> + <h-bound-for-fluid> ::= "H_BOUNDARY_FOR_FLUID" <bound-name> <Tref> <emissivity> \ <specular-fraction> <hc> <outside-temperature> \ <triangles> @@ -151,10 +156,12 @@ _______ <prog-t-bound-for-solid> ::= "T_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \ <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] - <prog-h-bound-for-solid> ::= "H_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \ <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] +<prog-hf-bound-for-solid> ::= "HF_BOUNDARY_FOR_SOLID_PROG" <bound-name> <prog-name> \ + <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] + <prog-h-bound-for-fluid> ::= "H_BOUNDARY_FOR_FLUID_PROG" <bound-name> <prog-name> \ <triangle-sides> [ "PROG_PARAMS" [ <desc-arguments> ] ] diff --git a/doc/stardis-output.5.txt b/doc/stardis-output.5.txt @@ -596,22 +596,25 @@ _______ | "4" # H_BOUNDARY_FOR_SOLID between 2 defined media | "5" # H_BOUNDARY_FOR_SOLID between 2 undefined media | "6" # H_BOUNDARY_FOR_SOLID enclosing a fluid - | "7" # T_BOUNDARY_FOR_SOLID between 2 defined media - | "8" # T_BOUNDARY_FOR_SOLID between 2 undefined media - | "9" # T_BOUNDARY_FOR_SOLID enclosing a fluid - | "10" # F_BOUNDARY_FOR_FLUID between 2 defined media - | "11" # F_BOUNDARY_FOR_FLUID between 2 undefined media - | "12" # F_BOUNDARY_FOR_SOLID enclosing a fluid - | "13" # SOLID_FLUID_CONNECTION between 2 solids - | "14" # SOLID_FLUID_CONNECTION between 2 fluids - | "15" # SOLID_FLUID_CONNECTION used as boundary - | "16" # SOLID_FLUID_CONNECTION between 2 undefined + | "7" # HF_BOUNDARY_FOR_SOLID between 2 defined media + | "8" # HF_BOUNDARY_FOR_SOLID between 2 undefined media + | "9" # HF_BOUNDARY_FOR_SOLID enclosing a fluid + | "10" # T_BOUNDARY_FOR_SOLID between 2 defined media + | "11" # T_BOUNDARY_FOR_SOLID between 2 undefined media + | "12" # T_BOUNDARY_FOR_SOLID enclosing a fluid + | "13" # F_BOUNDARY_FOR_FLUID between 2 defined media + | "14" # F_BOUNDARY_FOR_FLUID between 2 undefined media + | "15" # F_BOUNDARY_FOR_SOLID enclosing a fluid + | "16" # SOLID_FLUID_CONNECTION between 2 solids + | "17" # SOLID_FLUID_CONNECTION between 2 fluids + | "18" # SOLID_FLUID_CONNECTION used as boundary + | "19" # SOLID_FLUID_CONNECTION between 2 undefined # media - | "17" # no connexion between 2 fluids - | "18" # no connexion between a solid and a fluid - | "19" # no boundary around a fluid - | "20" # no boundary around a solid - | "21" # invalid part of a compute surface + | "20" # no connexion between 2 fluids + | "21" # no connexion between a solid and a fluid + | "22" # no boundary around a fluid + | "23" # no boundary around a solid + | "24" # invalid part of a compute surface <trg-prop-conflicts> # #triangles statuses <real3> ::= REAL REAL REAL diff --git a/src/stardis-app.c b/src/stardis-app.c @@ -616,6 +616,19 @@ validate_properties goto end; } break; + case DESC_BOUND_HF_FOR_SOLID: + case DESC_BOUND_HF_FOR_SOLID_PROG: + if(!(solid_count == 1 && fluid_count == 0)) { + if(solid_count + fluid_count == 2) + *properties_conflict_status = BOUND_HF_FOR_SOLID_BETWEEN_2_DEFS; + else if(solid_count + fluid_count == 0) + *properties_conflict_status = BOUND_HF_FOR_SOLID_BETWEEN_2_UNDEFS; + else if(fluid_count == 1) + *properties_conflict_status = BOUND_HF_FOR_SOLID_ENCLOSING_FLUID; + else FATAL("error:" STR(__FILE__) ":" STR(__LINE__)"\n"); + goto end; + } + break; case DESC_BOUND_T_FOR_SOLID: case DESC_BOUND_T_FOR_SOLID_PROG: if(!(solid_count == 1 && fluid_count == 0)) { diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -65,6 +65,9 @@ enum properties_conflict_t { BOUND_H_FOR_SOLID_BETWEEN_2_DEFS, BOUND_H_FOR_SOLID_BETWEEN_2_UNDEFS, BOUND_H_FOR_SOLID_ENCLOSING_FLUID, + BOUND_HF_FOR_SOLID_BETWEEN_2_DEFS, + BOUND_HF_FOR_SOLID_BETWEEN_2_UNDEFS, + BOUND_HF_FOR_SOLID_ENCLOSING_FLUID, BOUND_T_FOR_SOLID_BETWEEN_2_DEFS, BOUND_T_FOR_SOLID_BETWEEN_2_UNDEFS, BOUND_T_FOR_SOLID_ENCLOSING_FLUID, diff --git a/src/stardis-description.c b/src/stardis-description.c @@ -21,6 +21,8 @@ #include "stardis-fluid-prog.h" #include "stardis-hbound.h" #include "stardis-hbound-prog.h" +#include "stardis-hfbound.h" +#include "stardis-hfbound-prog.h" #include "stardis-tbound.h" #include "stardis-tbound-prog.h" #include "stardis-fbound.h" @@ -78,6 +80,12 @@ release_description case DESC_BOUND_H_FOR_FLUID_PROG: release_h_boundary_prog(desc->d.h_boundary_prog, allocator); break; + case DESC_BOUND_HF_FOR_SOLID: + release_hf_boundary(desc->d.hf_boundary, allocator); + break; + case DESC_BOUND_HF_FOR_SOLID_PROG: + release_hf_boundary_prog(desc->d.hf_boundary_prog, allocator); + break; case DESC_BOUND_T_FOR_SOLID: release_t_boundary(desc->d.t_boundary, allocator); break; @@ -147,6 +155,12 @@ str_print_description case DESC_BOUND_H_FOR_FLUID_PROG: ERR(str_print_h_boundary_prog(str, desc)); break; + case DESC_BOUND_HF_FOR_SOLID: + ERR(str_print_hf_boundary(str, desc)); + break; + case DESC_BOUND_HF_FOR_SOLID_PROG: + ERR(str_print_hf_boundary_prog(str, desc)); + break; case DESC_BOUND_F_FOR_SOLID: ERR(str_print_f_boundary(str, desc->d.f_boundary)); break; @@ -201,6 +215,10 @@ get_description_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_HF_FOR_SOLID: + return &desc->d.hf_boundary->name; + case DESC_BOUND_HF_FOR_SOLID_PROG: + return &desc->d.hf_boundary_prog->name; case DESC_BOUND_F_FOR_SOLID: return &desc->d.f_boundary->name; case DESC_BOUND_F_FOR_SOLID_PROG: @@ -247,6 +265,12 @@ description_get_medium_id case DESC_BOUND_H_FOR_FLUID_PROG: *id = desc->d.h_boundary_prog->mat_id; return; + case DESC_BOUND_HF_FOR_SOLID: + *id = desc->d.hf_boundary->mat_id; + return; + case DESC_BOUND_HF_FOR_SOLID_PROG: + *id = desc->d.hf_boundary_prog->mat_id; + return; case DESC_BOUND_T_FOR_SOLID: *id = desc->d.t_boundary->mat_id; return; diff --git a/src/stardis-description.h b/src/stardis-description.h @@ -41,6 +41,8 @@ enum description_type { DESC_MAT_FLUID_PROG, DESC_BOUND_H_FOR_FLUID_PROG, DESC_BOUND_H_FOR_SOLID_PROG, + DESC_BOUND_HF_FOR_SOLID, + DESC_BOUND_HF_FOR_SOLID_PROG, DESC_BOUND_T_FOR_SOLID_PROG, DESC_BOUND_F_FOR_SOLID_PROG, DESC_SOLID_FLUID_CONNECT_PROG, @@ -53,6 +55,9 @@ enum description_type { ((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_HF(D) \ + ((D)->type == DESC_BOUND_HF_FOR_SOLID\ + || (D)->type == DESC_BOUND_HF_FOR_SOLID_PROG) #define DESC_IS_T(D) \ ((D)->type == DESC_BOUND_T_FOR_SOLID \ || (D)->type == DESC_BOUND_T_FOR_SOLID_PROG) @@ -79,6 +84,7 @@ enum description_type { ((D)->type == DESC_MAT_SOLID_PROG || (D)->type == DESC_MAT_FLUID_PROG \ || (D)->type == DESC_BOUND_H_FOR_FLUID_PROG \ || (D)->type == DESC_BOUND_H_FOR_SOLID_PROG \ + || (D)->type == DESC_BOUND_HF_FOR_SOLID_PROG \ || (D)->type == DESC_BOUND_T_FOR_SOLID_PROG \ || (D)->type == DESC_BOUND_F_FOR_SOLID_PROG \ || (D)->type == DESC_SOLID_FLUID_CONNECT_PROG \ @@ -96,6 +102,8 @@ struct f_boundary; struct f_boundary_prog; struct h_boundary; struct h_boundary_prog; +struct hf_boundary; +struct hf_boundary_prog; struct solid_fluid_connect; struct solid_fluid_connect_prog; struct solid_solid_connect; @@ -115,6 +123,8 @@ struct description { struct f_boundary_prog* f_boundary_prog; struct h_boundary* h_boundary; struct h_boundary_prog* h_boundary_prog; + struct hf_boundary* hf_boundary; + struct hf_boundary_prog* hf_boundary_prog; struct solid_fluid_connect* sf_connect; struct solid_fluid_connect_prog* sf_connect_prog; struct solid_solid_connect* ss_connect; diff --git a/src/stardis-hbound.h b/src/stardis-hbound.h @@ -19,8 +19,6 @@ #include <rsys/rsys.h> #include <rsys/str.h> -#include "stardis-prog-properties.h" - struct mem_allocator; struct fluid; struct description; diff --git a/src/stardis-hfbound-prog.c b/src/stardis-hfbound-prog.c @@ -0,0 +1,113 @@ +/* Copyright (C) 2018-2022 |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-hfbound-prog.h" +#include "stardis-fluid-prog.h" +#include "stardis-prog-properties.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_hf_boundary_prog + (struct mem_allocator* allocator, + struct hf_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_initialized = 1; + (*dst)->mat_id = UINT_MAX; +end: + return res; +error: + if(str_initialized) { + str_release(&(*dst)->name); + str_release(&(*dst)->prog_name); + } + if(*dst) MEM_RM(allocator, *dst); + goto end; +} + +void +release_hf_boundary_prog + (struct hf_boundary_prog* bound, + struct mem_allocator* allocator) +{ + size_t i; + ASSERT(bound && allocator); + str_release(&bound->name); + str_release(&bound->prog_name); + if(bound->prog_data) + bound->release(bound->prog_data); + if(bound->possible_external_fluid) + release_fluid_prog(bound->possible_external_fluid, allocator); + for(i = 0; i < bound->argc; i++) MEM_RM(allocator, bound->argv[i]); + MEM_RM(allocator, bound->argv); + /* library_close call is managed at lib_data level */ + MEM_RM(allocator, bound); +} + +res_T +str_print_hf_boundary_prog + (struct str* str, + const struct description* desc) +{ + res_T res = RES_OK; + const struct hf_boundary_prog* b; + ASSERT(str && desc && DESC_IS_HF(desc)); + b = desc->d.hf_boundary_prog; + ERR(str_append_printf(str, + "programmed HF boundary for %s '%s': lib='%s', " + "(using medium %u as external medium)", + (desc->type == DESC_BOUND_HF_FOR_SOLID_PROG ? "solid" : "fluid"), + str_cget(&b->name), str_cget(&b->prog_name), + b->mat_id)); + if(b->argc > 0) { + size_t i; + ERR(str_append_printf(str, ", provided arguments:\n")); + for(i = 0; i < b->argc; i++) { + ERR(str_append_printf(str, (i+1 == b->argc ? "\t%s" : "\t%s\n"), b->argv[i])); + } + } +end: + return res; +error: + goto end; +} + +double +hf_bound_prog_get_hmax + (struct hf_boundary_prog* hf_boundary_props) +{ + return hf_boundary_props->hmax(hf_boundary_props->prog_data); +} diff --git a/src/stardis-hfbound-prog.h b/src/stardis-hfbound-prog.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2018-2022 |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_HFBOUND_PROG_H +#define SDIS_HFBOUND_PROG_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +#include "stardis-prog-properties.h" + +struct mem_allocator; +struct fluid_prog; +struct description; +struct program; + +/******************************************************************************* + * HF boundary prog data + ******************************************************************************/ +struct hf_boundary_prog { + void* prog_data; /* result of the create() call */ + struct str name; + struct str prog_name; + size_t argc; + char** argv; + /* lib handle and function ptrs */ + struct program* program; + void* (*create) + (const struct stardis_description_create_context*, void*, size_t, char**); + void (*release)(void*); + double (*ref_temp)(const struct stardis_interface_fragment*, void*); + double (*emissivity)(const struct stardis_interface_fragment*, void*); + double (*alpha)(const struct stardis_interface_fragment*, void*); + double (*hc)(const struct stardis_interface_fragment*, void*); + double (*hmax)(void*); + double* (*t_range)(void*, double trange[2]); + /* for h for solid */ + double (*boundary_temp)(const struct stardis_interface_fragment*, void*); + double (*flux)(const struct stardis_interface_fragment*, void*); + /* for h for fluid */ + double (*fluid_temp)(const struct stardis_vertex*, void*); + unsigned mat_id; + struct fluid_prog* possible_external_fluid; /* if H for solid */ +}; + +res_T +init_hf_boundary_prog + (struct mem_allocator* allocator, + struct hf_boundary_prog** dst); + +void +release_hf_boundary_prog + (struct hf_boundary_prog* bound, + struct mem_allocator* allocator); + +res_T +str_print_hf_boundary_prog + (struct str* str, + const struct description* bound); + +double +hf_bound_prog_get_hmax + (struct hf_boundary_prog* hf_boundary_props); + +#endif diff --git a/src/stardis-hfbound.c b/src/stardis-hfbound.c @@ -0,0 +1,89 @@ +/* Copyright (C) 2018-2022 |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-hfbound.h" +#include "stardis-fluid.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_hf_boundary + (struct mem_allocator* allocator, + struct hf_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_hf_boundary + (struct hf_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_hf_boundary + (struct str* str, + const struct description* desc) +{ + res_T res = RES_OK; + const struct hf_boundary* b; + ASSERT(str && desc && DESC_IS_HF(desc)); + b = desc->d.hf_boundary; + ERR(str_append_printf(str, + "HF boundary for %s '%s': ref_temperature=%g emissivity=%g specular_fraction=%g " + "hc=%g T=%g flux=%g (using medium %u as external medium)", + (desc->type == DESC_BOUND_HF_FOR_SOLID ? "solid" : "fluid"), + str_cget(&b->name), b->ref_temperature, b->emissivity, + b->specular_fraction, b->hc, b->imposed_temperature, b->imposed_flux, + b->mat_id)); +end: + return res; +error: + goto end; +} diff --git a/src/stardis-hfbound.h b/src/stardis-hfbound.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2018-2022 |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_HFBOUND_H +#define SDIS_HFBOUND_H + +#include <rsys/rsys.h> +#include <rsys/str.h> + +struct mem_allocator; +struct fluid; +struct description; + +/******************************************************************************* + * HF boundary type + ******************************************************************************/ +struct hf_boundary { + struct str name; + double ref_temperature; + double emissivity; + double specular_fraction; + double hc; + double imposed_flux; + double imposed_temperature; + unsigned mat_id; + struct fluid* possible_external_fluid; /* if HF for solid */ +}; + +res_T +init_hf_boundary + (struct mem_allocator* allocator, + struct hf_boundary** dst); + +void +release_hf_boundary + (struct hf_boundary* bound, + struct mem_allocator* allocator); + +res_T +str_print_hf_boundary + (struct str* str, + const struct description* desc); + +#endif diff --git a/src/stardis-intface.c b/src/stardis-intface.c @@ -20,6 +20,8 @@ #include "stardis-solid.h" #include "stardis-hbound.h" #include "stardis-hbound-prog.h" +#include "stardis-hfbound.h" +#include "stardis-hfbound-prog.h" #include "stardis-tbound.h" #include "stardis-tbound-prog.h" #include "stardis-fbound.h" @@ -402,6 +404,44 @@ create_intface fluid_side_shader->specular_fraction = interface_get_alpha; } break; + case DESC_BOUND_HF_FOR_SOLID: + if(!for_fluid) { + if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { + res = RES_BAD_ARG; + goto error; + } + ASSERT(!fluid_side_shader); + fluid_side_shader = + front_defined ? &interface_shader.back : &interface_shader.front; + } + ext_id = intface->d.hf_boundary->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)); + intface_count++; + boundary_count++; + if(front_defined) back_med = media[ext_id]; + else front_med = media[ext_id]; + interface_shader.convection_coef_upper_bound = intface->d.hf_boundary->hc; + interface_props->hc = intface->d.hf_boundary->hc; + interface_props->ref_temperature = intface->d.hf_boundary->ref_temperature; + interface_props->emissivity = intface->d.hf_boundary->emissivity; + interface_props->alpha = intface->d.hf_boundary->specular_fraction; + if(intface->d.hf_boundary->hc > 0) { + interface_shader.convection_coef = interface_get_convection_coef; + } + fluid_side_shader->reference_temperature = interface_get_ref_temperature; + ASSERT(intface->d.hf_boundary->imposed_flux != SDIS_FLUX_NONE); + if(intface->d.hf_boundary->imposed_flux) { + interface_props->imposed_flux = intface->d.hf_boundary->imposed_flux; + interface_shader.front.flux = interface_get_flux; + interface_shader.back.flux = interface_get_flux; + } + if(intface->d.hf_boundary->emissivity > 0) { + fluid_side_shader->emissivity = interface_get_emissivity; + 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; @@ -446,6 +486,38 @@ create_intface interface_props->get_ref_temp = intface->d.h_boundary_prog->ref_temp; interface_props->prog_data = intface->d.h_boundary_prog->prog_data; break; + case DESC_BOUND_HF_FOR_SOLID_PROG: + if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { + res = RES_BAD_ARG; + goto error; + } + ASSERT(!fluid_side_shader); + fluid_side_shader = + front_defined ? &interface_shader.back : &interface_shader.front; + ext_id = intface->d.hf_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++; + intface_count++; + boundary_count++; + if(front_defined) back_med = media[ext_id]; + else front_med = media[ext_id]; + interface_shader.convection_coef_upper_bound + = hf_bound_prog_get_hmax(intface->d.hf_boundary_prog); + ASSERT(interface_shader.convection_coef_upper_bound >= 0); + interface_shader.convection_coef = intface_prog_get_hc; + 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_shader.front.flux = intface_prog_get_flux; + interface_shader.back.flux = intface_prog_get_flux; + interface_props->get_hc = intface->d.hf_boundary_prog->hc; + interface_props->get_emissivity = intface->d.hf_boundary_prog->emissivity; + interface_props->get_alpha = intface->d.hf_boundary_prog->alpha; + interface_props->get_flux = intface->d.hf_boundary_prog->flux; + interface_props->get_ref_temp = intface->d.hf_boundary_prog->ref_temp; + interface_props->prog_data = intface->d.hf_boundary_prog->prog_data; + break; case DESC_BOUND_T_FOR_SOLID: if(sdis_medium_get_type(def_medium) != SDIS_SOLID) { res = RES_BAD_ARG; diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -19,6 +19,8 @@ #include "stardis-description.h" #include "stardis-hbound.h" #include "stardis-hbound-prog.h" +#include "stardis-hfbound.h" +#include "stardis-hfbound-prog.h" #include "stardis-tbound.h" #include "stardis-tbound-prog.h" #include "stardis-fbound.h" @@ -279,6 +281,7 @@ description_set_name const char* keywords[] = { "AUTO", "BACK", "BOTH", "FLUID", "FLUID_PROG", "FRONT", "F_BOUNDARY_FOR_SOLID", "F_BOUNDARY_FOR_SOLID_PROG", "H_BOUNDARY_FOR_FLUID", "H_BOUNDARY_FOR_FLUID_PROG", + "HF_BOUNDARY_FOR_SOLID", "HF_BOUNDARY_FOR_SOLID_PROG", "H_BOUNDARY_FOR_SOLID", "H_BOUNDARY_FOR_SOLID_PROG", "PROGRAM", "PROG_PARAMS", "SCALE", "SOLID", "SOLID_PROG", "SOLID_FLUID_CONNECTION", "SOLID_FLUID_CONNECTION_PROG", "SOLID_SOLID_CONNECTION", @@ -462,6 +465,132 @@ error: goto end; } +/* HF_BOUNDARY_FOR_SOLID Name ref_temperature emissivity specular_fraction hc + * T_env flux STL_filenames */ +static res_T +process_hf + (struct stardis* stardis, + const enum description_type type, + wordexp_t* pwordexp) +{ + char* arg = NULL; + struct description* desc; + size_t sz; + struct hf_boundary* hf_boundary; + size_t idx = 1; + struct fluid* fluid = NULL; + res_T res = RES_OK; + + ASSERT(stardis && pwordexp); + + stardis->counts.hbound_count++; + + 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_hf_boundary(stardis->allocator, &desc->d.hf_boundary)); + hf_boundary = desc->d.hf_boundary; + desc->type = type; + + CHK_ARG(idx, "hf boundary name"); + ERR(description_set_name(stardis, &hf_boundary->name, arg)); + if(find_description_by_name(stardis, &hf_boundary->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + + CHK_ARG(idx, "ref_temperature"); + res = cstr_to_double(arg, &hf_boundary->ref_temperature); + if(res != RES_OK + || hf_boundary->ref_temperature < 0) + { + logger_print(stardis->logger, LOG_ERROR, + "Invalid reference temperature: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + stardis->t_range[0] = MMIN(stardis->t_range[0], hf_boundary->ref_temperature); + stardis->t_range[1] = MMAX(stardis->t_range[1], hf_boundary->ref_temperature); + CHK_ARG(idx, "emissivity"); + res = cstr_to_double(arg, &hf_boundary->emissivity); + if(res != RES_OK + || hf_boundary->emissivity < 0 + || hf_boundary->emissivity > 1) + { + logger_print(stardis->logger, LOG_ERROR, "Invalid emissivity: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + CHK_ARG(idx, "specular fraction"); + res = cstr_to_double(arg, &hf_boundary->specular_fraction); + if(res != RES_OK + || hf_boundary->specular_fraction < 0 + || hf_boundary->specular_fraction > 1) + { + logger_print(stardis->logger, LOG_ERROR, + "Invalid specular fraction: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + CHK_ARG(idx, "convection coefficient"); + res = cstr_to_double(arg, &hf_boundary->hc); + if(res != RES_OK + || hf_boundary->hc < 0) + { + logger_print(stardis->logger, LOG_ERROR, + "Invalid convection coefficient: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + CHK_ARG(idx, "temperature"); + res = cstr_to_double(arg, &hf_boundary->imposed_temperature); + if(res != RES_OK + || hf_boundary->imposed_temperature < 0) + { + logger_print(stardis->logger, LOG_ERROR, "Invalid temperature: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + CHK_ARG(idx, "flux"); + res = cstr_to_double(arg, &hf_boundary->imposed_flux); + if(res != RES_OK + || hf_boundary->imposed_flux == SDIS_FLUX_NONE) { + /* Flux can be < 0 but not undefined */ + logger_print(stardis->logger, LOG_ERROR, + "Invalid flux: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + stardis->t_range[0] = MMIN(stardis->t_range[0], hf_boundary->imposed_temperature); + stardis->t_range[1] = MMAX(stardis->t_range[1], hf_boundary->imposed_temperature); + + ASSERT(type == DESC_BOUND_HF_FOR_SOLID); + ERR(init_fluid(stardis->allocator, &fluid)); + fluid->fluid_id = allocate_stardis_medium_id(stardis); + hf_boundary->mat_id = fluid->fluid_id; + hf_boundary->possible_external_fluid = fluid; + ASSERT(sz <= UINT_MAX); + fluid->desc_id = (unsigned)sz; + fluid->imposed_temperature = hf_boundary->imposed_temperature; + fluid->is_outside = 1; + fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); + ERR(create_solver_fluid(stardis, fluid)); + logger_print(stardis->logger, LOG_OUTPUT, + "External fluid created: T=%g (it is medium %u)\n", + fluid->imposed_temperature, + fluid->fluid_id); + + ASSERT(sz <= UINT_MAX); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); + +end: + return res; +error: + goto end; +} + static res_T set_argc_argv (struct mem_allocator* allocator, @@ -794,6 +923,93 @@ error: goto end; } +/* HF_BOUNDARY_FOR_SOLID_PROG Name ProgName STL_filenames [PROG_PARAMS ...] */ +static res_T +process_hf_prog + (struct stardis* stardis, + const enum description_type type, + wordexp_t* pwordexp) +{ + char* arg = NULL; + struct description* desc; + const char *lib_name, *desc_name; + size_t sz; + struct hf_boundary_prog* hf_boundary_prog; + struct stardis_description_create_context ctx; + struct fluid_prog* fluid_prog = NULL; + size_t idx = 1; + res_T res = RES_OK; + + ASSERT(stardis && pwordexp); + ASSERT(type == DESC_BOUND_HF_FOR_SOLID_PROG); /* No HF prog for fluids */ + + stardis->counts.fmed_count++; + + 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_hf_boundary_prog(stardis->allocator, &desc->d.hf_boundary_prog)); + hf_boundary_prog = desc->d.hf_boundary_prog; + desc->type = type; + + CHK_ARG(idx, "programmed hf boundary name"); + ERR(description_set_name(stardis, &hf_boundary_prog->name, arg)); + if(find_description_by_name(stardis, &hf_boundary_prog->name, desc)) { + logger_print(stardis->logger, LOG_ERROR, + "Name already used: %s\n", arg); + if(res == RES_OK) res = RES_BAD_ARG; + goto end; + } + desc_name = arg; + + CHK_ARG(idx, "program name"); + ERR(str_set(&hf_boundary_prog->prog_name, arg)); + lib_name = arg; + + ASSERT(sz <= UINT_MAX); + ERR(read_sides_and_files(stardis, 1, (unsigned)sz, pwordexp, &idx)); + + /* store the end of line as args for custom init */ + ERR(set_argc_argv(stardis->allocator, &hf_boundary_prog->argc, + &hf_boundary_prog->argv, pwordexp, idx)); + /* get the user-defined functions from the library */ + ERR(get_prog_common(lib_name, stardis, &hf_boundary_prog->program, + &hf_boundary_prog->create, &hf_boundary_prog->release)); + GET_LIB_SYMBOL(hf_boundary_prog, ref_temp, stardis_reference_temperature); + GET_LIB_SYMBOL(hf_boundary_prog, emissivity, stardis_emissivity); + GET_LIB_SYMBOL(hf_boundary_prog, alpha, stardis_specular_fraction); + GET_LIB_SYMBOL(hf_boundary_prog, hc, stardis_convection_coefficient); + GET_LIB_SYMBOL(hf_boundary_prog, hmax, stardis_max_convection_coefficient); + GET_LIB_SYMBOL(hf_boundary_prog, flux, stardis_boundary_flux); + GET_LIB_SYMBOL(hf_boundary_prog, t_range, stardis_t_range); + GET_LIB_SYMBOL(hf_boundary_prog, fluid_temp, stardis_medium_temperature); + /* create and init custom data */ + ctx.name = desc_name; + CREATE_DESC_DATA(hf_boundary_prog); + + hf_boundary_prog->t_range(hf_boundary_prog->prog_data, stardis->t_range); + + /* create the media behind the interface */ + ERR(init_fluid_prog(stardis->allocator, &fluid_prog)); + fluid_prog->fluid_id = allocate_stardis_medium_id(stardis); + hf_boundary_prog->mat_id = fluid_prog->fluid_id; + hf_boundary_prog->possible_external_fluid = fluid_prog; + fluid_prog->desc_id = (unsigned)sz; + fluid_prog->temp = hf_boundary_prog->fluid_temp; + fluid_prog->is_outside = 1; + fluid_prog->prog_data = hf_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: + return res; +error: + goto end; +} + /* T_BOUNDARY_FOR_SOLID Name T STL_filenames */ static res_T process_t @@ -1112,13 +1328,13 @@ process_sfc if(res == RES_OK) res = RES_BAD_ARG; goto end; } - CHK_ARG(idx, "Convection coefficient"); + CHK_ARG(idx, "convection coefficient"); res = cstr_to_double(arg, &sf_connect->hc); if(res != RES_OK || sf_connect->hc < 0) { logger_print(stardis->logger, LOG_ERROR, - "Invalid Convection coefficient: %s\n", arg); + "Invalid convection coefficient: %s\n", arg); if(res == RES_OK) res = RES_BAD_ARG; goto end; } @@ -1879,6 +2095,10 @@ process_model_line ERR(process_h(stardis, DESC_BOUND_H_FOR_SOLID, pwordexp)); else if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_SOLID_PROG")) ERR(process_h_prog(stardis, DESC_BOUND_H_FOR_SOLID_PROG, pwordexp)); + else if(0 == strcasecmp(arg, "HF_BOUNDARY_FOR_SOLID")) + ERR(process_hf(stardis, DESC_BOUND_HF_FOR_SOLID, pwordexp)); + else if(0 == strcasecmp(arg, "HF_BOUNDARY_FOR_SOLID_PROG")) + ERR(process_hf_prog(stardis, DESC_BOUND_HF_FOR_SOLID_PROG, pwordexp)); else if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_FLUID")) ERR(process_h(stardis, DESC_BOUND_H_FOR_FLUID, pwordexp)); else if(0 == strcasecmp(arg, "H_BOUNDARY_FOR_FLUID_PROG")) diff --git a/src/stardis-prog-properties.h.in b/src/stardis-prog-properties.h.in @@ -429,6 +429,84 @@ stardis_t_range (void* data, double range[2]); +/****************************************************************/ +/* Additional mandatory functions for a programmed F+H boundary */ +/****************************************************************/ + +/* Returns the emissivity at a given fragment. + * This functions is called every time a path of the computation reaches + * this boundary. + * data is the pointer returned by stardis_create_data for this boundary. */ +extern double +stardis_emissivity + (const struct stardis_interface_fragment* frag, + void* data); + +/* Returns the specular fraction at a given fragment. + * This functions is called every time a path of the computation reaches + * this boundary. + * data is the pointer returned by stardis_create_data for this boundary. */ +extern double +stardis_specular_fraction + (const struct stardis_interface_fragment* frag, + void* data); + +/* Returns the convection coefficient at a given fragment. + * This functions is called every time a path of the computation reaches + * this boundary. + * data is the pointer returned by stardis_create_data for this boundary. */ +extern double +stardis_convection_coefficient + (const struct stardis_interface_fragment* frag, + void* data); + +/* Returns the flux at the boundary at a given fragment. + * This functions is called every time a path of the computation reaches + * this boundary. + * data is the pointer returned by stardis_create_data for this boundary. */ +extern double +stardis_boundary_flux + (const struct stardis_interface_fragment* frag, + void* data); + +/* Returns the reference temperature at a given fragment. + * This temperature is used as a reference to linearize radiative transfer + * in Picard computations. + * This functions is called every time a path of the computation reaches + * this boundary. + * data is the pointer returned by stardis_create_data for this boundary. */ +extern double +stardis_reference_temperature + (const struct stardis_interface_fragment* frag, + void* data); + +/* Returns the temperature at a given vertex. + * The intent is to return the temperature in an implicit fluid enclosing this + * solid. + * This functions is called at every vertex of every path of the computation + * crossing this fluid. + * data is the pointer returned by stardis_create_data for this boundary. */ +extern double +stardis_medium_temperature + (const struct stardis_vertex* vtx, + void* data); + +/* Returns the upper bound of the convection coefficient accross this boundary. + * This functions is called once when initializing the computation. + * data is the pointer returned by stardis_create_data for this boundary. */ +extern double +stardis_max_convection_coefficient + (void* data); + +/* Computes the expected temperature range for this boundary. + * This functions is called once when initializing the computation. + * data is the pointer returned by stardis_create_data for this boundary. + * Returns its modified range argument. */ +extern double* +stardis_t_range + (void* data, + double range[2]); + /**************************************************************/ /* Additional mandatory functions for a programmed F boundary */ /**************************************************************/