stardis

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

commit 9c57bcaa589037092cdef070230bf7ff4f72796d
parent 0186f7488f98e70ffbe404cdc01757ae52e553cb
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Sat, 13 Apr 2024 12:37:12 +0200

Added support for programmable radiative environment

Add the new TRAD_PROG keyword that configures the radiative_env_prog
data structure written for this purpose. The parsing relies on existing
functions and macros provided by Stardis to parse programmable
properties.

In addition to the usual member variables of a programmable property,
the new radiative_env_prog structure provides function pointers to
user-defined functions that return the temperature and reference
temperature for radiative trajectories that reach infinity along a given
direction.

The stardis-sinput manual page is updated to document this
new functionnality.

Diffstat:
Mdoc/stardis-input.5.in | 10++++++----
Msrc/stardis-extern-source.c | 6+++---
Msrc/stardis-parsing.c | 73++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/stardis-radiative-env.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/stardis-radiative-env.h | 41++++++++++++++++++++++++++++++++++++++++-
5 files changed, 214 insertions(+), 13 deletions(-)

diff --git a/doc/stardis-input.5.in b/doc/stardis-input.5.in @@ -12,7 +12,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. -.Dd April 5, 2024 +.Dd April 13, 2024 .Dt STARDIS-INPUT 5 .Os .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -213,7 +213,7 @@ that changes at .It Ta \& \& | Ta Aq Va robin .It Ta \& \& | Ta Aq Va neumann .It Ta \& \& | Ta Aq Va robin-neumann -.It Ta \& \& | Ta Ao Va rad-temp Ac No # \&At most once +.It Ta \& \& | Ta Ao Va rad-env Ac No # \&At most once .It Ta \& \& | Ta Ao Va ext-source Ac No # \&At most once .It \ Ta Ta .\" Dirichlet @@ -255,8 +255,10 @@ that changes at .It Ta Ta Ao Va prog-desc Ac .It \ Ta Ta .\" Radiative temperature -.It Ao Va rad-temp Ac Ta ::= Ta Li TRAD Ao Va temp Ac Ao Va Tref Ac -# Radiative temperatures +.It Ao Va rad-env Ac Ta ::= Ta Ao Va rad-env-const Ac | Ao Va rad-env-prog Ac +.It Ao Va rad-env-const Ac Ta ::= Ta Li TRAD Ao Va temp Ac Ao Va Tref Ac +.It Ao Va rad-env-prog Ac Ta ::= Ta Li TRAD_PROG Ao Va prog-name Ac \e +.It Ta Ta Op Li PROG_PARAMS Op Ao Va args Ac .It \ Ta Ta .\" External source .It Ao Va ext-source Ac Ta ::= Ta Ao Va ext-source-const Ac | Ao Va ext-source-prog Ac diff --git a/src/stardis-extern-source.c b/src/stardis-extern-source.c @@ -77,7 +77,7 @@ exit: return res; error: logger_print(stardis->logger, LOG_ERROR, - "Error when creating the external spherical source for the Solver -- %s\n", + "Error when creating the external spherical source for the solver -- %s\n", res_to_cstr(res)); goto exit; } @@ -114,7 +114,7 @@ create_solver_source_sphere_prog res_T res = RES_OK; ASSERT(src && src->type == EXTERN_SOURCE_SPHERE_PROG && stardis); - /* Register with the solver source a pointer to the external source */ + /* Register a pointer to the external source with the solver source */ res = sdis_data_create(stardis->dev, sizeof(struct spherical_source_prog*), ALIGNOF(struct spherical_source_prog*), NULL, &data); if(res != RES_OK) goto error; @@ -134,7 +134,7 @@ exit: return res; error: logger_print(stardis->logger, LOG_ERROR, - "Error when creating the external spherical source for the Solver -- %s\n", + "Error when creating the external spherical source for the solver -- %s\n", res_to_cstr(res)); goto exit; } diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c @@ -2021,9 +2021,9 @@ process_radiative if(stardis->radenv_def) { logger_print(stardis->logger, LOG_ERROR, - "TRAD cannot be specified twice\n"); + "Radiative environment cannot be specified twice\n"); res = RES_BAD_ARG; - goto end; + goto error; } res = radiative_env_init_const(stardis->allocator, &stardis->radenv); @@ -2053,10 +2053,75 @@ process_radiative end: return res; error: + radiative_env_release(&stardis->radenv); + stardis->radenv = RADIATIVE_ENV_DEFAULT; goto end; } static res_T +process_radiative_prog(struct stardis* stardis, wordexp_t* pwordexp) +{ + struct stardis_description_create_context ctx; + struct radiative_env_prog* radenv = NULL; + char* lib_name = NULL; + char* arg = NULL; + size_t idx = 1; + res_T res = RES_OK; + + ASSERT(stardis && pwordexp); + + radenv = &stardis->radenv.data.prg; + + if(stardis->radenv_def) { + logger_print(stardis->logger, LOG_ERROR, + "Radiative environment cannot be specified twice\n"); + res = RES_BAD_ARG; + goto error; + } + + res = radiative_env_init_prog(stardis->allocator, &stardis->radenv); + + CHK_ARG(idx, "program name"); + ERR(str_set(&radenv->prog_name, arg)); + lib_name = arg; + + if(idx < pwordexp->we_wordc + && strcasecmp(pwordexp->we_wordv[idx], "PROG_PARAMS")) { + logger_print(stardis->logger, LOG_ERROR, + "Expecting PROG_PARAMS keyword while parsing `%s'.\n", + pwordexp->we_wordv[idx]); + res = RES_BAD_ARG; + goto error; + } + + ERR(set_argc_argv + (stardis->allocator, &radenv->argc, &radenv->argv, pwordexp, idx)); + ERR(get_prog_common + (lib_name, stardis, &radenv->program, &radenv->create, &radenv->release)); + GET_LIB_SYMBOL(radenv, temperature, + stardis_radiative_env_temperature); + GET_LIB_SYMBOL(radenv, reference_temperature, + stardis_radiative_env_reference_temperature); + + ctx.name = "Radiative environment"; + radenv->data = radenv->create + (&ctx, radenv->program->prog_data, radenv->argc, radenv->argv); + if(!radenv->data) { + logger_print(stardis->logger, LOG_ERROR, + "Cannot create data for the radiative environment\n"); + res = RES_UNKNOWN_ERR; + goto error; + } + +exit: + return res; +error: + radiative_env_release(&stardis->radenv); + stardis->radenv = RADIATIVE_ENV_DEFAULT; + goto exit; +} + +static res_T process_spherical_source (struct stardis* stardis, wordexp_t* pwordexp) @@ -2177,7 +2242,7 @@ process_spherical_source_prog(struct stardis* stardis, wordexp_t* pwordexp) if(!src->data) { logger_print(stardis->logger, LOG_ERROR, "Cannot create data for the external spherical source\n"); - res = RES_BAD_ARG; + res = RES_UNKNOWN_ERR; goto error; } @@ -2273,6 +2338,8 @@ process_model_line ERR(process_scale(stardis, pwordexp)); else if(0 == strcasecmp(arg, "TRAD")) ERR(process_radiative(stardis, pwordexp)); + else if(0 == strcasecmp(arg, "TRAD_PROG")) + ERR(process_radiative_prog(stardis, pwordexp)); else if(0 == strcasecmp(arg, "SPHERICAL_SOURCE")) ERR(process_spherical_source(stardis, pwordexp)); else if(0 == strcasecmp(arg, "SPHERICAL_SOURCE_PROG")) diff --git a/src/stardis-radiative-env.c b/src/stardis-radiative-env.c @@ -17,6 +17,8 @@ #include "stardis-radiative-env.h" #include <sdis.h> +#include <rsys/cstr.h> +#include <rsys/logger.h> /******************************************************************************* * Helper functions @@ -69,6 +71,66 @@ exit: if(data) SDIS(data_ref_put(data)); return res; error: + logger_print(stardis->logger, LOG_ERROR, + "Error when creating the radiative environment for the solver -- %s\n", + res_to_cstr(res)); + goto exit; +} + +static double +radenv_prog_get_temperature + (const struct sdis_radiative_ray* ray, + struct sdis_data* data) +{ + const struct radiative_env_prog* radenv = NULL; + + radenv = *((const struct radiative_env_prog* const*)sdis_data_cget(data)); + return radenv->temperature(ray->dir, radenv->data); +} + +static double +radenv_prog_get_reference_temperature + (const struct sdis_radiative_ray* ray, + struct sdis_data* data) +{ + const struct radiative_env_prog* radenv = NULL; + + radenv = *((const struct radiative_env_prog* const*)sdis_data_cget(data)); + return radenv->reference_temperature(ray->dir, radenv->data); +} + +static res_T +create_radenv_prog + (struct radiative_env* radenv, + struct stardis* stardis) +{ + struct sdis_radiative_env_shader shader = SDIS_RADIATIVE_ENV_SHADER_NULL; + struct sdis_data* data = NULL; + res_T res = RES_OK; + ASSERT(radenv && radenv->type == RADIATIVE_ENV_PROG && stardis); + + /* Register a pointer to the radiative environment with the solver radiative + * environment */ + res = sdis_data_create(stardis->dev, sizeof(struct radiative_env_prog*), + ALIGNOF(struct radiative_env_prog*), NULL, &data); + if(res != RES_OK) goto error; + *((struct radiative_env_prog**)sdis_data_get(data)) = &radenv->data.prg; + + /* Create the radiative environment */ + shader.temperature = radenv_prog_get_temperature; + shader.reference_temperature = radenv_prog_get_reference_temperature; + res = sdis_radiative_env_create + (stardis->dev, &shader, data, &radenv->sdis_radenv); + if(res != RES_OK) goto error; + +exit: + /* Release the local reference on the data: it is kept by the sdis radenv */ + if(data) SDIS(data_ref_put(data)); + return res; +error: + logger_print(stardis->logger, LOG_ERROR, + "Error when creating the radiative environment for the solver -- %s\n", + res_to_cstr(res)); goto exit; } @@ -87,10 +149,40 @@ radiative_env_init_const return RES_OK; } +res_T +radiative_env_init_prog + (struct mem_allocator* allocator, + struct radiative_env* radenv) +{ + ASSERT(radenv); + radenv->type = RADIATIVE_ENV_PROG; + radenv->data.prg = RADIATIVE_ENV_PROG_NULL; + radenv->data.prg.allocator = allocator; + str_init(allocator, &radenv->data.prg.prog_name); + return RES_OK; +} + void radiative_env_release(struct radiative_env* radenv) { ASSERT(radenv); + + if(radenv->type == RADIATIVE_ENV_PROG) { + struct radiative_env_prog* radenv_prog = &radenv->data.prg; + size_t i = 0; + + if(radenv_prog->data) { + ASSERT(radenv_prog->release); + radenv_prog->release(radenv_prog->data); + } + + str_release(&radenv_prog->prog_name); + FOR_EACH(i, 0, radenv_prog->argc) { + MEM_RM(radenv_prog->allocator, radenv_prog->argv[i]); + } + MEM_RM(radenv_prog->allocator, radenv_prog->argv); + } + if(radenv->sdis_radenv) SDIS(radiative_env_ref_put(radenv->sdis_radenv)); radenv->sdis_radenv = NULL; } @@ -109,9 +201,10 @@ radiative_env_create_solver_radiative_env if(res != RES_OK) goto error; break; case RADIATIVE_ENV_PROG: - /* TODO */ + res = create_radenv_prog(radenv, stardis); + if(res != RES_OK) goto error; break; - default: FATAL("Unreachable code.\n"); break; + default: FATAL("Unreachable code\n"); break; } exit: diff --git a/src/stardis-radiative-env.h b/src/stardis-radiative-env.h @@ -38,7 +38,41 @@ struct radiative_env_const { static const struct radiative_env_const RADIATIVE_ENV_CONST_DEFAULT = RADIATIVE_ENV_CONST_DEFAULT__; -struct radiative_env_prog { char dummy; }; /* TODO */ +struct radiative_env_prog { + struct str prog_name; + struct program* program; + void* data; /* Pointer toward the program data */ + struct mem_allocator* allocator; + + /* Input arguments */ + size_t argc; + char** argv; + + void* + (*create) + (const struct stardis_description_create_context* ctx, + void* lib_data, + size_t argc, + char* argv[]); + + void + (*release) + (void* data); + + double + (*temperature) + (const double dir[3], + void* data); + + double + (*reference_temperature) + (const double dir[3], + void* data); +}; +#define RADIATIVE_ENV_PROG_NULL__ \ + {{0}, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL} +static const struct radiative_env_prog RADIATIVE_ENV_PROG_NULL = + RADIATIVE_ENV_PROG_NULL__; struct radiative_env { enum radiative_env_type type; @@ -60,6 +94,11 @@ radiative_env_init_const (struct mem_allocator* allocator, struct radiative_env* radenv); +extern LOCAL_SYM res_T +radiative_env_init_prog + (struct mem_allocator* allocator, + struct radiative_env* radenv); + extern LOCAL_SYM void radiative_env_release (struct radiative_env* radenv);