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:
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);