stardis

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

commit 12b4baed7d0dd73b11b2dc16c84f8b142f56f159
parent 9d1152d78345c0db8905fa2c1bf6ecee66f106f0
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 23 Dec 2021 17:49:01 +0100

Add first programmable description (fluid_prog)

Diffstat:
Mcmake/CMakeLists.txt | 7+++++++
Msrc/stardis-app.h | 23++++++++++++++++++++++-
Msrc/stardis-compute.c | 36++++++++++++++++++++++++++----------
Msrc/stardis-intface.c | 20++++++++++++++++++--
Msrc/stardis-parsing.c | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Asrc/stardis-prog-common.h | 31+++++++++++++++++++++++++++++++
Asrc/stardis-prog.c | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/stardis-prog.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 467 insertions(+), 24 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -126,8 +126,12 @@ set(SDIS_FILES_SRC stardis-main.c stardis-output.c stardis-parsing.c + stardis-prog.c stardis-solid.c) +set(SDIS_FILES_INC_API + stardis-prog-common.h) + set(SDIS_FILES_INC stardis-app.h stardis-args.h @@ -137,6 +141,7 @@ set(SDIS_FILES_INC stardis-intface.h stardis-output.h stardis-parsing.h + stardis-prog.h stardis-solid.h stardis-version.h.in) @@ -145,6 +150,7 @@ set(SDIS_FILES_DOC COPYING README.md) # Prepend each file by `SDIS_SOURCE_DIR' rcmake_prepend_path(SDIS_FILES_SRC ${SDIS_SOURCE_DIR}) rcmake_prepend_path(SDIS_FILES_INC ${SDIS_SOURCE_DIR}) +rcmake_prepend_path(SDIS_FILES_INC_API ${SDIS_SOURCE_DIR}) rcmake_prepend_path(SDIS_FILES_DOC ${PROJECT_SOURCE_DIR}/../) add_executable(stardis @@ -171,6 +177,7 @@ install(TARGETS stardis LIBRARY DESTINATION lib RUNTIME DESTINATION bin) +install(FILES ${SDIS_FILES_INC_API} DESTINATION include/) install(FILES ${SDIS_FILES_DOC} DESTINATION share/doc/stardis) rcmake_copy_runtime_libraries(stardis) diff --git a/src/stardis-app.h b/src/stardis-app.h @@ -21,6 +21,7 @@ #include "stardis-default.h" #include "stardis-solid.h" #include "stardis-fluid.h" +#include "stardis-prog.h" #include <star/sstl.h> #include <star/sg3d.h> @@ -98,6 +99,7 @@ enum properties_conflict_t { 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, @@ -114,10 +116,16 @@ enum description_type { ((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) \ - ((D) == DESC_MAT_SOLID || (D) == DESC_MAT_FLUID) + (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* @@ -198,6 +206,7 @@ error: /******************************************************************************/ struct fluid; +struct fluid_prog; struct solid; struct t_boundary; struct f_boundary; @@ -209,6 +218,7 @@ 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; @@ -549,6 +559,9 @@ release_description 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); @@ -587,6 +600,9 @@ str_print_description 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; @@ -622,6 +638,8 @@ get_description_name 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: @@ -651,6 +669,9 @@ description_get_medium_id 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; diff --git a/src/stardis-compute.c b/src/stardis-compute.c @@ -245,7 +245,7 @@ check_probe_conform_to_type logger_print(stardis->logger, LOG_WARNING, "Could not determine the medium probe is in.\n"); } else { - if(filter_ctx.desc->type == DESC_MAT_SOLID) { + if(DESC_IS_SOLID(filter_ctx.desc->type)) { struct solid* solid = filter_ctx.desc->d.solid; ASSERT(solid->delta < INF); logger_print(stardis->logger, LOG_OUTPUT, @@ -272,9 +272,18 @@ check_probe_conform_to_type filter_ctx.dist / solid->delta); } } else { + ASSERT(DESC_IS_FLUID(filter_ctx.desc->type)); /* TODO: check move length wrt local geometry? */ - logger_print(stardis->logger, LOG_OUTPUT, - "Probe was in fluid '%s'.\n", str_cget(&filter_ctx.desc->d.fluid->name)); + 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)); + } 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)); + } logger_print(stardis->logger, LOG_OUTPUT, "Probe distance from closest boundary was %g.\n", filter_ctx.dist); } @@ -328,9 +337,7 @@ check_probe_conform_to_type res = RES_BAD_ARG; goto error; } - logger_print(stardis->logger, LOG_OUTPUT, - "Probe is in solid '%s'.\n", str_cget(&filter_ctx.desc->d.solid->name)); - if(filter_ctx.desc->type == DESC_MAT_SOLID) { + if(DESC_IS_SOLID(filter_ctx.desc->type)) { struct solid* solid = filter_ctx.desc->d.solid; if(filter_ctx.dist < 0.25 * solid->delta) { logger_print(stardis->logger, LOG_ERROR, @@ -353,11 +360,20 @@ check_probe_conform_to_type filter_ctx.dist / solid->delta); } } else { - logger_print(stardis->logger, LOG_WARNING, - "Probe is in fluid '%s': computing fluid temperature, " - "not using a specific position.\n", - str_cget(&filter_ctx.desc->d.fluid->name)); + ASSERT(DESC_IS_FLUID(filter_ctx.desc->type)); /* 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, + "Probe is in fluid '%s': computing fluid temperature, " + "not using a specific position.\n", + str_cget(&filter_ctx.desc->d.fluid->name)); + } else { + ASSERT(filter_ctx.desc->type == DESC_MAT_FLUID_PROG); + logger_print(stardis->logger, LOG_WARNING, + "Probe is in fluid '%s': computing fluid temperature, " + "not using a specific position.\n", + str_cget(&filter_ctx.desc->d.fluid_prog->name)); + } } } diff --git a/src/stardis-intface.c b/src/stardis-intface.c @@ -172,6 +172,13 @@ create_intface front_med = media[id]; fluid_side_shader = &interface_shader.front; break; + case DESC_MAT_FLUID_PROG: + 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: FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); } @@ -193,6 +200,15 @@ create_intface * fluids and this case lead to an error */ fluid_side_shader = &interface_shader.back; break; + case DESC_MAT_FLUID_PROG: + 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; + break; default: FATAL("error:" STR(__FILE__) ":" STR(__LINE__)": Invalid type.\n"); } @@ -216,12 +232,12 @@ create_intface } if(front_defined) { def_medium = front_med; - fluid_side_shader = (descriptions[fd].type == DESC_MAT_FLUID) + fluid_side_shader = DESC_IS_FLUID(descriptions[fd].type) ? &interface_shader.front : &interface_shader.back; } else { ASSERT(back_defined); def_medium = back_med; - fluid_side_shader = (descriptions[bd].type == DESC_MAT_FLUID) + fluid_side_shader = DESC_IS_FLUID(descriptions[bd].type) ? &interface_shader.back : &interface_shader.front; } interface_props->desc_id = cd; diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -24,6 +24,7 @@ #include <rsys/double3.h> #include <sdis_version.h> #include <rsys/logger.h> +#include <rsys/library.h> #include <getopt.h> #include <stdlib.h> @@ -140,7 +141,7 @@ read_sides_and_files add_geom_ctx.properties[SG3D_INTFACE] = description_id; } else { tk = strtok_r(NULL, " \t", tok_ctx); - if(!tk) { + if(!tk || 0 == strcasecmp(tk, "PROG_PARAMS")) { if(file_count == 0) { /* At least 1 side */ logger_print(stardis->logger, LOG_ERROR, @@ -171,9 +172,9 @@ read_sides_and_files } } tk = strtok_r(NULL, " \t", tok_ctx); - if(!tk) { - if(!descr_is_intface /* Has read a side */ - || !file_count) /* Need at least 1 file */ + if(!tk || 0 == strcasecmp(tk, "PROG_PARAMS")) { + if(!descr_is_intface /* Has read a side specifier */ + || !file_count) /* Need at least 1 file name */ { logger_print(stardis->logger, LOG_ERROR, "Invalid data (missing token 'file name')\n"); @@ -257,7 +258,7 @@ description_set_name res_T res = RES_OK; double foo; const char* keywords[] = { - "AUTO", "BACK", "BOTH", "FLUID", "FRONT", "F_BOUNDARY_FOR_SOLID", + "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" }; @@ -405,8 +406,7 @@ process_h h_boundary->possible_external_fluid = fluid; ASSERT(sz <= UINT_MAX); fluid->desc_id = (unsigned)sz; - fluid->imposed_temperature - = h_boundary->imposed_temperature; + fluid->imposed_temperature = h_boundary->imposed_temperature; fluid->is_outside = 1; fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); ERR(create_solver_fluid(stardis, fluid)); @@ -790,7 +790,6 @@ process_solid ERR(init_solid(stardis->allocator, &desc->d.solid)); solid = desc->d.solid; desc->type = DESC_MAT_SOLID; - solid->solid_id = allocate_stardis_medium_id(stardis); solid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); solid->is_outside = 0; @@ -879,7 +878,6 @@ process_solid /* Actual solid creation is defered until geometry is read to allow * enclosure shape VS delta analysis (and auto delta computation) */ - ASSERT(sz <= UINT_MAX); ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); end: @@ -910,9 +908,7 @@ process_fluid ERR(init_fluid(stardis->allocator, &desc->d.fluid)); fluid = desc->d.fluid; desc->type = DESC_MAT_FLUID; - fluid->fluid_id = allocate_stardis_medium_id(stardis); - fluid->is_outside = 0; fluid->is_green = stardis->mode & (MODE_BIN_GREEN | MODE_GREEN); ASSERT(sz <= UINT_MAX); fluid->desc_id = (unsigned)sz; @@ -973,9 +969,136 @@ process_fluid ERR(create_solver_fluid(stardis, fluid)); + ERR(read_sides_and_files(stardis, 0, (unsigned)sz, tok_ctx)); + +end: + return res; +error: + goto end; +} + +/* FLUID_PROG Name Prog_filename STL_filenames [PROG_PARAMS ...] */ +static res_T +process_fluid_prog + (struct stardis* stardis, + char** tok_ctx) +{ + char* tk = NULL; + struct description* desc; + const char* lib_name; + struct str tmp; + size_t sz; + struct fluid_prog* fluid_prog; + res_T res = RES_OK; + + ASSERT(stardis && tok_ctx); + + 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_fluid_prog(stardis->allocator, &desc->d.fluid_prog)); + fluid_prog = desc->d.fluid_prog; + desc->type = DESC_MAT_FLUID_PROG; + fluid_prog->fluid_id = allocate_stardis_medium_id(stardis); ASSERT(sz <= UINT_MAX); + fluid_prog->desc_id = (unsigned)sz; + + CHK_TOK(strtok_r(NULL, " \t", tok_ctx), "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, + "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(&fluid_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(&fluid_prog->args, *tok_ctx)); + } + + fluid_prog->lib = library_open(lib_name); + if(!fluid_prog->lib) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot open library: %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + *(void**)&fluid_prog->create + = library_get_symbol(fluid_prog->lib, "create_fluid_data"); + if(!fluid_prog->create) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'create_fluid_data' in lib %s\n", lib_name); + 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) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'init_fluid_data' in lib %s\n", lib_name); + 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) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'release_fluid_data' in lib %s\n", lib_name); + 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) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'volumic_mass()' 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) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot find function 'temperature()' in lib %s\n", lib_name); + res = RES_BAD_ARG; + goto error; + } + + ERR(create_solver_fluid_prog(stardis, fluid_prog)); + end: return res; error: @@ -1106,6 +1229,8 @@ process_model_line ERR(process_solid(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "FLUID")) ERR(process_fluid(stardis, &tok_ctx)); + else if(0 == strcasecmp(tk, "FLUID_PROG")) + ERR(process_fluid_prog(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "SCALE")) ERR(process_scale(stardis, &tok_ctx)); else if(0 == strcasecmp(tk, "TRAD")) diff --git a/src/stardis-prog-common.h b/src/stardis-prog-common.h @@ -0,0 +1,31 @@ + +/* 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 Lesser 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 + * Lesser General Public License for more details. + * + * 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__ + +enum stardis_return_codes { + STARDIS_SUCCESS, + STARDIS_FAILURE +}; + +struct walk_vertex { + double P[3]; /* World space position */ + double time; /* "Time" of the vertex */ +}; + +#endif + diff --git a/src/stardis-prog.c b/src/stardis-prog.c @@ -0,0 +1,162 @@ +/* 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-prog.h" +#include "stardis-compute.h" +#include "stardis-app.h" + +#include <rsys/library.h> +#include <rsys/logger.h> + +#include <sdis.h> + +#include <limits.h> + +/******************************************************************************* + * Local Functions + ******************************************************************************/ + +static double +fluid_prog_get_calorific_capacity + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct fluid_prog* const* fluid_props = sdis_data_cget(data); + return (*fluid_props)->cp(vtx, (*fluid_props)->prog_data); +} + +static double +fluid_prog_get_volumic_mass + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct fluid_prog* const* fluid_props = sdis_data_cget(data); + return (*fluid_props)->rho(vtx, (*fluid_props)->prog_data); +} + +static double +fluid_prog_get_temperature + (const struct sdis_rwalk_vertex* vtx, + struct sdis_data* data) +{ + const struct fluid_prog* const* fluid_props = sdis_data_cget(data); + return (*fluid_props)->temp(vtx, (*fluid_props)->prog_data); +} + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +res_T +create_solver_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; + 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)); + 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)->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: + 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_fluid_prog + (struct fluid_prog* fluid, + struct mem_allocator* allocator) +{ + ASSERT(fluid && allocator); + str_release(&fluid->name); + str_release(&fluid->prog_name); + str_release(&fluid->args); + + if(fluid->prog_data) { + fluid->release(fluid->prog_data); + fluid->prog_data = NULL; + } + MEM_RM(allocator, fluid); +} + +res_T +str_print_fluid_prog(struct str* str, const struct fluid_prog* f) +{ + res_T res = RES_OK; + ASSERT(str && f); + STR_APPEND_PRINTF(str, "programmed fluid '%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->fluid_id ) ); +end: + return res; +error: + goto end; +} diff --git a/src/stardis-prog.h b/src/stardis-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_PROG_H +#define SDIS_PROG_H + +#include <sdis.h> + +#include <rsys/rsys.h> +#include <rsys/str.h> + +struct stardis; + +/******************************************************************************* + * 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; + 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 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*); + void (*release)(void*); +}; + +res_T +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); + +LOCAL_SYM 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); + +#endif