commit 592109d9f7f7c323dacb21112662aeb750940cbf
parent c4696a306e1d50ccd05093ee1985e4e64e3044b6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 5 Mar 2024 16:31:02 +0100
Merge branch 'feature_external_source' into develop
Diffstat:
12 files changed, 560 insertions(+), 18 deletions(-)
diff --git a/Makefile b/Makefile
@@ -32,6 +32,7 @@ SRC =\
src/stardis-compute.c\
src/stardis-compute-probe-boundary.c\
src/stardis-description.c\
+ src/stardis-extern-source.c\
src/stardis-fluid.c\
src/stardis-fluid-prog.c\
src/stardis-fbound.c\
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 February 19, 2024
+.Dd February 27, 2024
.Dt STARDIS-INPUT 5
.Os
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -128,18 +128,11 @@ The file format is as follows:
.It Ta \& \& | Ta Ao Va boundary-condition Ac Op Ao Va comment Ac
.It Ta \& \& | Ta Ao Va scaling Ac Op Ao Va comment Ac
# At most once
-.It Ta \& \& | Ta Ao Va rad-temps Ac Op Ao Va comment Ac
-# At most once
.It \ Ta Ta
.It Ao Va comment Ac Ta ::= Ta Li # Vt string
.It Ao Va program Ac Ta ::= Ta Li PROGRAM Ao Va prog-name Ac Ao Va lib-path Ac Op Ao Va args Ac
.It Ao Va scaling Ac Ta ::= Ta Li SCALE Vt real
# Geometry scaling in ]0, INF)
-.It \ Ta Ta
-.It Ao Va rad-temps Ac Ta ::= Ta Li TRAD Ao Va temp Ac Ao Va Tref Ac
-# Radiative temperatures
-.It Ao Va temp Ac Ta ::= Ta Vt real No # Temperature > 0 [K]
-.It Ao Va Tref Ac Ta ::= Ta Vt real No # Reference temperature > 0 [K]
.El
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Ss Media
@@ -220,6 +213,8 @@ 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 ext-source Ac No # \&At most once
.It \ Ta Ta
.\" Dirichlet
.It Ao Va dirichlet Ac Ta ::= Ta Ao Va dirichlet-const Ac | Ao Va dirichlet-prog Ac
@@ -259,8 +254,25 @@ that changes at
.It Ao Va robin-neumann-prog Ac Ta ::= Ta Li HF_BOUNDARY_FOR_SOLID_PROG Ao Va bound-name Ac \e
.It Ta Ta Ao Va prog-desc Ac
.It \ Ta Ta
-.It Ao Va flux Ac Ta ::= Ta Vt real No # [W/m^2]
+.\" Radiative temperature
+.It Ao Va rad-temp Ac Ta ::= Ta Li TRAD Ao Va temp Ac Ao Va Tref Ac
+# Radiative temperatures
+.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
+.It Ao Va ext-source-const Ac Ta ::= Ta Li SPHERICAL_SOURCE Ao Va radius Ac Ao Va position Ac \e
+.It Ta Ta Ao Va power Ac
+.It Ao Va ext-source-prog Ac Ta ::= Ta Li SPHERICAL_SOURCE_PROG Ao Va radius Ac \e
+.It Ta Ta Ao Va prog-name Ac Op Li PROG_PARAMS Op Ao Va args Ac
+.It \ Ta Ta
+.\" Miscellaneous
+.It Ao Va temp Ac Ta ::= Ta Vt real No # Temperature > 0 [K]
+.It Ao Va Tref Ac Ta ::= Ta Vt real No # Reference temperature > 0 [K]
.It Ao Va outside-temp Ac Ta ::= Ta Vt real No # Temperature > 0 [K]
+.It Ao Va flux Ac Ta ::= Ta Vt real No # [W/m^2]
+.It Ao Va power Ac Ta ::= Ta Vt real No # [W]
+.It Ao Va position Ac Ta ::= Ta Vt real real real
+.It Ao Va radius Ac Ta ::= Ta Vt real
.El
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Ss Miscellaneous
@@ -336,7 +348,7 @@ and its volumic power is
.Ar 2.5 No W/m^3 .
The boundary properties are
.No emissivity= Ns Ar 0 ,
-.No specular-fraction= Ns Ar 0,
+.No specular-fraction= Ns Ar 0 ,
.No hc= Ns Ar 10 No W/m^2/K
and
.No external-temperature= Ns Ar 100 No K .
diff --git a/doc/stardis.1.in b/doc/stardis.1.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 January 31, 2024
+.Dd February 26, 2024
.Dt STARDIS 1
.Os
.Sh NAME
@@ -20,7 +20,7 @@
.Nd statistical solving of coupled thermal systems
.Sh SYNOPSIS
.Nm
-.Op Fl eghv
+.Op Fl eghiv
.Op Fl D Ar path_type , Ns Ar files_name_prefix
.Op Fl d Ar file_base_name
.Op Fl F Pa surface Ns Op , Ns Ar time Ns Op , Ns Ar time
@@ -186,6 +186,10 @@ and cannot be used in conjunction with option
.Fl D .
.It Fl h
Output short help and exit.
+.It Fl i
+Disable internal radiative exchanges.
+External radiative exchanges are still processed, i.e. the external
+source.
.It Fl L Pa interface_probes
Defines a set of interface probes for which
.Nm
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -283,6 +283,8 @@ stardis_init
stardis->next_medium_id = 0;
stardis->undefined_medium_behind_boundary_id = SENC3D_UNSPECIFIED_MEDIUM;
stardis->verbose = args->verbose;
+ stardis->extsrc = EXTERN_SOURCE_NULL;
+ stardis->disable_intrad = args->disable_intrad;
darray_media_ptr_init(stardis->allocator, &stardis->media);
/* If a dump is expected, we won't process any computation */
@@ -511,8 +513,19 @@ stardis_init
scn_args.fp_to_meter = stardis->scale_factor;
scn_args.trad.temperature = stardis->trad;
scn_args.trad.reference = stardis->trad_ref;
- d2_set(scn_args.t_range, stardis->t_range);
+ scn_args.t_range[0] = stardis->t_range[0];
+ scn_args.t_range[1] = stardis->t_range[1];
+ scn_args.source = stardis->extsrc.sdis_src;
scn_args.context = &create_context;
+
+ /* Setting Tmax to 0 is a way of setting the radiative coefficient to 0, and
+ * thus setting the probability of evolving in a radiative random walk to
+ * zero. */
+ if(stardis->disable_intrad) {
+ scn_args.t_range[0] = 0;
+ scn_args.t_range[1] = 0;
+ }
+
res = sdis_scene_create(stardis->dev, &scn_args, &stardis->sdis_scn);
if(res != RES_OK) {
logger_print(stardis->logger, LOG_ERROR,
@@ -549,6 +562,9 @@ stardis_release
str_release(&stardis->bin_green_filename);
str_release(&stardis->end_paths_filename);
str_release(&stardis->chunks_prefix);
+
+ extern_source_release(&stardis->extsrc);
+
/* release non-PROGRAM descritions first */
FOR_EACH(i, 0, darray_descriptions_size_get(&stardis->descriptions)) {
struct description* d = darray_descriptions_data_get(&stardis->descriptions) +i;
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -18,6 +18,7 @@
#include "stardis-args.h"
#include "stardis-description.h"
+#include "stardis-extern-source.h"
#include <star/sg3d.h>
@@ -241,6 +242,8 @@ struct stardis {
int mpi_rank;
struct darray_probe_boundary probe_boundary_list;
+ struct extern_source extsrc;
+ int disable_intrad; /* Disable internal radiative exchanges */
};
unsigned
diff --git a/src/stardis-args.c b/src/stardis-args.c
@@ -428,7 +428,7 @@ void
usage(FILE* stream)
{
#define PRINT(Msg) fprintf(stream, Msg)
- PRINT("stardis [-eghv] [-D path_type,files_name_prefix] [-d file_base_name]\n");
+ PRINT("stardis [-eghiv] [-D path_type,files_name_prefix] [-d file_base_name]\n");
PRINT(" [-F surface[,time[,time]]] [-G green_bin[,green_ascii]]\n");
PRINT(" [-L interface_probes] [-m medium_name[,time[,time]]]\n");
PRINT(" [-n samples_count] [-o picard_order]\n");
@@ -495,7 +495,7 @@ parse_args
{
int opt = 0, n_used = 0, o_used = 0;
size_t len = 0;
- const char option_list[] = "c:d:D:eF:gG:hL:m:M:n:o:p:P:R:s:S:t:vV:x:X:";
+ const char option_list[] = "c:d:D:eF:gG:hiL:m:M:n:o:p:P:R:s:S:t:vV:x:X:";
char buf[128];
struct str keep;
char** line = NULL;
@@ -624,6 +624,10 @@ parse_args
args->mode |= MODE_DUMP_HELP;
break;
+ case 'i':
+ args->disable_intrad = 1;
+ break;
+
case 'L':
if(args->mode & EXCLUSIVE_MODES) {
logger_print(args->logger, LOG_ERROR,
diff --git a/src/stardis-args.h.in b/src/stardis-args.h.in
@@ -142,6 +142,7 @@ struct args {
int mode;
enum dump_path_type dump_paths;
int verbose;
+ int disable_intrad; /* Disable internal radiative exchanges */
struct darray_probe_boundary probe_boundary_list;
};
diff --git a/src/stardis-extern-source.c b/src/stardis-extern-source.c
@@ -0,0 +1,218 @@
+/* Copyright (C) 2018-2023 |Méso|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-extern-source.h"
+
+#include <sdis.h>
+#include <rsys/cstr.h>
+#include <rsys/logger.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+sphere_get_position(const double time, double pos[3], struct sdis_data* data)
+{
+ const struct spherical_source* src = NULL;
+ ASSERT(pos);
+ (void)time;
+
+ src = *((const struct spherical_source* const*)sdis_data_cget(data));
+ pos[0] = src->position[0];
+ pos[1] = src->position[1];
+ pos[2] = src->position[2];
+}
+
+static double
+sphere_get_power(const double time, struct sdis_data* data)
+{
+ const struct spherical_source* src = NULL;
+ (void)time;
+
+ src = *((const struct spherical_source* const*)sdis_data_cget(data));
+ return src->power; /* [W] */
+}
+
+static res_T
+create_solver_source_sphere
+ (struct extern_source* src,
+ struct stardis* stardis)
+{
+ struct sdis_spherical_source_create_args args =
+ SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL;
+ struct sdis_data* data = NULL;
+ res_T res = RES_OK;
+ ASSERT(src && src->type == EXTERN_SOURCE_SPHERE && stardis);
+
+ /* Register with the solver source a pointer to the external source */
+ res = sdis_data_create(stardis->dev, sizeof(struct spherical_source*),
+ ALIGNOF(struct spherical_source*), NULL, &data);
+ if(res != RES_OK) goto error;
+ *((struct spherical_source**)sdis_data_get(data)) = &src->data.sphere;
+
+ /* Create the spherical source */
+ args.position = sphere_get_position;
+ args.power = sphere_get_power;
+ args.data = data;
+ args.radius = src->data.sphere.radius;
+ res = sdis_spherical_source_create(stardis->dev, &args, &src->sdis_src);
+ if(res != RES_OK) goto error;
+
+exit:
+ /* Release the local reference on the data: it is kept by the sdis source */
+ if(data) SDIS(data_ref_put(data));
+ return res;
+error:
+ logger_print(stardis->logger, LOG_ERROR,
+ "Error when creating the external spherical source for the Solver -- %s\n",
+ res_to_cstr(res));
+ goto exit;
+}
+
+static void
+sphere_prog_get_position(const double time, double pos[3], struct sdis_data* data)
+{
+ const struct spherical_source_prog* src = NULL;
+ ASSERT(pos);
+ (void)time;
+
+ src = *((const struct spherical_source_prog* const*)sdis_data_cget(data));
+ src->position(time, pos, src->data);;
+}
+
+static double
+sphere_prog_get_power(const double time, struct sdis_data* data)
+{
+ const struct spherical_source_prog* src = NULL;
+ (void)time;
+
+ src = *((const struct spherical_source_prog* const*)sdis_data_cget(data));
+ return src->power(time, src->data);
+}
+
+static res_T
+create_solver_source_sphere_prog
+ (struct extern_source* src,
+ struct stardis* stardis)
+{
+ struct sdis_spherical_source_create_args args =
+ SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL;
+ struct sdis_data* data = NULL;
+ 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 */
+ res = sdis_data_create(stardis->dev, sizeof(struct spherical_source_prog*),
+ ALIGNOF(struct spherical_source_prog*), NULL, &data);
+ if(res != RES_OK) goto error;
+ *((struct spherical_source_prog**)sdis_data_get(data)) = &src->data.sphere_prog;
+
+ /* Create the spherical source */
+ args.position = sphere_prog_get_position;
+ args.power = sphere_prog_get_power;
+ args.data = data;
+ args.radius = src->data.sphere_prog.radius;
+ res = sdis_spherical_source_create(stardis->dev, &args, &src->sdis_src);
+ if(res != RES_OK) goto error;
+
+exit:
+ /* Release the local reference on the data: it is kept by the sdis source */
+ if(data) SDIS(data_ref_put(data));
+ return res;
+error:
+ logger_print(stardis->logger, LOG_ERROR,
+ "Error when creating the external spherical source for the Solver -- %s\n",
+ res_to_cstr(res));
+ goto exit;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+extern_source_init_sphere
+ (struct mem_allocator* allocator,
+ struct extern_source* src)
+{
+ ASSERT(src);
+ (void)allocator;
+ src->type = EXTERN_SOURCE_SPHERE;
+ src->data.sphere = SPHERICAL_SOURCE_NULL;
+ return RES_OK;
+}
+
+res_T
+extern_source_init_sphere_prog
+ (struct mem_allocator* allocator,
+ struct extern_source* src)
+{
+ ASSERT(src);
+ src->type = EXTERN_SOURCE_SPHERE_PROG;
+ src->data.sphere_prog = SPHERICAL_SOURCE_PROG_NULL;
+ src->data.sphere_prog.allocator = allocator;
+ str_init(allocator, &src->data.sphere_prog.prog_name);
+ return RES_OK;
+}
+
+void
+extern_source_release(struct extern_source* src)
+{
+ ASSERT(src);
+ if(src->type == EXTERN_SOURCE_SPHERE_PROG) {
+ struct spherical_source_prog* src_prog = &src->data.sphere_prog;
+ size_t i;
+
+ if(src_prog->data) {
+ ASSERT(src_prog->release);
+ src_prog->release(src_prog->data);
+ }
+
+ str_release(&src_prog->prog_name);
+ FOR_EACH(i, 0, src_prog->argc) {
+ MEM_RM(src_prog->allocator, src_prog->argv[i]);
+ }
+
+ MEM_RM(src_prog->allocator, src_prog->argv);
+ }
+
+ if(src->sdis_src) SDIS(source_ref_put(src->sdis_src));
+}
+
+res_T
+extern_source_create_solver_source
+ (struct extern_source* src,
+ struct stardis* stardis)
+{
+ res_T res = RES_OK;
+ ASSERT(src);
+
+ switch(src->type) {
+ case EXTERN_SOURCE_SPHERE:
+ res = create_solver_source_sphere(src, stardis);
+ if(res != RES_OK) goto error;
+ break;
+ case EXTERN_SOURCE_SPHERE_PROG:
+ res = create_solver_source_sphere_prog(src, stardis);
+ if(res != RES_OK) goto error;
+ break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/stardis-extern-source.h b/src/stardis-extern-source.h
@@ -0,0 +1,111 @@
+/* Copyright (C) 2018-2023 |Méso|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_EXTERN_SOURCE_H
+#define SDIS_EXTERN_SOURCE_H
+
+#include <rsys/rsys.h>
+
+/* Forward declaration */
+struct stardis;
+struct stardis_description_create_context;
+
+enum source_type {
+ EXTERN_SOURCE_SPHERE,
+ EXTERN_SOURCE_SPHERE_PROG,
+ EXTERN_SOURCE_NONE__
+};
+
+struct spherical_source {
+ double position[3];
+ double radius;
+ double power; /* [W] */
+};
+#define SPHERICAL_SOURCE_NULL__ {{0,0,0}, -1, 0}
+static const struct spherical_source SPHERICAL_SOURCE_NULL =
+ SPHERICAL_SOURCE_NULL__;
+
+struct spherical_source_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;
+
+ double radius; /* Not programmable */
+
+ void*
+ (*create)
+ (const struct stardis_description_create_context*,
+ void* lib_data,
+ size_t argc,
+ char* argv[]);
+
+ void
+ (*release)
+ (void* data);
+
+ double*
+ (*position)
+ (const double time,
+ double position[3],
+ void* data);
+
+ double
+ (*power)
+ (const double time,
+ void* data);
+};
+#define SPHERICAL_SOURCE_PROG_NULL__ \
+ {{0}, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL, NULL}
+static const struct spherical_source_prog SPHERICAL_SOURCE_PROG_NULL=
+ SPHERICAL_SOURCE_PROG_NULL__;
+
+/* Interface of an external source */
+struct extern_source {
+ enum source_type type;
+ union {
+ struct spherical_source sphere;
+ struct spherical_source_prog sphere_prog;
+ } data;
+ struct sdis_source* sdis_src;
+};
+#define EXTERN_SOURCE_NULL__ \
+ {EXTERN_SOURCE_NONE__, {SPHERICAL_SOURCE_NULL__}, NULL}
+static const struct extern_source EXTERN_SOURCE_NULL = EXTERN_SOURCE_NULL__;
+
+extern LOCAL_SYM res_T
+extern_source_init_sphere
+ (struct mem_allocator* allocator,
+ struct extern_source* src);
+
+extern LOCAL_SYM res_T
+extern_source_init_sphere_prog
+ (struct mem_allocator* allocator,
+ struct extern_source* src);
+
+extern LOCAL_SYM void
+extern_source_release
+ (struct extern_source* src);
+
+extern LOCAL_SYM res_T
+extern_source_create_solver_source
+ (struct extern_source* src,
+ struct stardis* stardis);
+
+#endif /* SDIS_EXTERN_SOURCE_H */
diff --git a/src/stardis-intface.c b/src/stardis-intface.c
@@ -632,9 +632,9 @@ create_intface
}
ASSERT(fluid_side_shader);
fluid_side_shader->reference_temperature = interface_get_ref_temperature;
+ fluid_side_shader->specular_fraction = interface_get_alpha;
if(intface->d.sf_connect->emissivity > 0) {
fluid_side_shader->emissivity = interface_get_emissivity;
- fluid_side_shader->specular_fraction = interface_get_alpha;
}
break;
case DESC_SOLID_FLUID_CONNECT_PROG:
diff --git a/src/stardis-parsing.c b/src/stardis-parsing.c
@@ -303,8 +303,8 @@ description_set_name
"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",
- "SOLID_SOLID_CONNECTION_PROG", "TRAD", "T_BOUNDARY_FOR_SOLID",
- "T_BOUNDARY_FOR_SOLID_PROG", "UNKNOWN" };
+ "SOLID_SOLID_CONNECTION_PROG", "SPHERICAL_SOURCE", "SPHERICAL_SOURCE_PROG",
+ "TRAD", "T_BOUNDARY_FOR_SOLID", "T_BOUNDARY_FOR_SOLID_PROG", "UNKNOWN" };
const char* reason = NULL;
size_t i;
ASSERT(name && arg);
@@ -628,6 +628,18 @@ set_argc_argv
goto error;
}
*argc = pwordexp->we_wordc - idx;
+ /* Review: why allocate an extra argument? In fact, it's necessary because
+ * this function is called even if there are no arguments to analyze. In this
+ * case, allocation would fail, as the size to be allocated would be zero.
+ * This +1 therefore guarantees that at least one element will be allocated.
+ * But this could be eliminated by checking that there are no arguments
+ * (argc==0) and, if necessary, returning before any allocation.
+ *
+ * Nevertheless, this extra argument makes sense. It should be the first
+ * argument and contain the program name. In this way, the argument list would
+ * respect the C convention for declaring an argument list. And so, anyone
+ * could use the getopt analysis function without having to declare a dummy
+ * argument as the program's first parameter */
*argv = MEM_CALLOC(allocator, 1 + *argc, sizeof(char *));
if(*argv == NULL) {
res = RES_MEM_ERR;
@@ -2070,6 +2082,142 @@ error:
goto end;
}
+static res_T
+process_spherical_source
+ (struct stardis* stardis,
+ wordexp_t* pwordexp)
+{
+ struct spherical_source* src = NULL;
+ char* arg = NULL;
+ size_t idx = 1;
+ res_T res = RES_OK;
+ ASSERT(stardis && pwordexp);
+
+ src = &stardis->extsrc.data.sphere;
+
+ if(stardis->extsrc.type != EXTERN_SOURCE_NONE__) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Only one external source can be defined\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = extern_source_init_sphere(stardis->allocator, &stardis->extsrc);
+ if(res != RES_OK) goto error;
+
+ CHK_ARG(idx, "radius");
+ res = cstr_to_double(arg, &src->radius);
+ if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG;
+ if(res != RES_OK) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Invalid spherical source radius: %s\n", arg);
+ goto error;
+ }
+
+ #define PARSE_POS(Name, Id) { \
+ CHK_ARG(idx, "position "Name); \
+ res = cstr_to_double(arg, &src->position[Id]); \
+ if(res != RES_OK) { \
+ logger_print(stardis->logger, LOG_ERROR, \
+ "Invalid spherical source "Name" coordinate: %s\n", arg); \
+ goto error; \
+ } \
+ } (void)0
+ PARSE_POS("X", 0);
+ PARSE_POS("Y", 1);
+ PARSE_POS("Z", 2);
+ #undef PARSE_POS
+
+ CHK_ARG(idx, "power");
+ res = cstr_to_double(arg, &src->power);
+ if(res == RES_OK && src->power < 0) res = RES_BAD_ARG;
+ if(res != RES_OK) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Invalid sphercial source power: %s\n", arg);
+ goto error;
+ }
+
+ res = extern_source_create_solver_source(&stardis->extsrc, stardis);
+ if(res != RES_OK) goto error;
+
+exit:
+ return res;
+error:
+ extern_source_release(&stardis->extsrc);
+ stardis->extsrc = EXTERN_SOURCE_NULL;
+ goto exit;
+}
+
+static res_T
+process_spherical_source_prog(struct stardis* stardis, wordexp_t* pwordexp)
+{
+ struct stardis_description_create_context ctx;
+ struct spherical_source_prog* src = NULL;
+ char* lib_name = NULL;
+ char* arg = NULL;
+ size_t idx = 1;
+ res_T res = RES_OK;
+ ASSERT(stardis && pwordexp);
+
+ src = &stardis->extsrc.data.sphere_prog;
+
+ if(stardis->extsrc.type != EXTERN_SOURCE_NONE__) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Only one external source can be defined\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = extern_source_init_sphere_prog(stardis->allocator, &stardis->extsrc);
+ if(res != RES_OK) goto error;
+
+ CHK_ARG(idx, "radius");
+ res = cstr_to_double(arg, &src->radius);
+ if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG;
+ if(res != RES_OK) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Invalid spherical source radius: %s\n", arg);
+ goto error;
+ }
+
+ CHK_ARG(idx, "program name");
+ ERR(str_set(&src->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, &src->argc, &src->argv, pwordexp, idx));
+ ERR(get_prog_common(lib_name, stardis, &src->program, &src->create, &src->release));
+ GET_LIB_SYMBOL(src, position, stardis_spherical_source_position);
+ GET_LIB_SYMBOL(src, power, stardis_spherical_source_power);
+
+ ctx.name = "External spherical source";
+ src->data = src->create(&ctx, src->program->prog_data, src->argc, src->argv);
+ if(!src->data) {
+ logger_print(stardis->logger, LOG_ERROR,
+ "Cannot create data for the external spherical source\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = extern_source_create_solver_source(&stardis->extsrc, stardis);
+ if(res != RES_OK) goto error;
+
+exit:
+ return res;
+error:
+ extern_source_release(&stardis->extsrc);
+ stardis->extsrc = EXTERN_SOURCE_NULL;
+ goto exit;
+}
+
/* Read medium or boundary line; should be one of:
* SOLID Name lambda rho cp delta Tinit Timposed volumic_power STL_sides_filenames
* FLUID Name rho cp Tinit Timposed STL_filenames
@@ -2151,6 +2299,10 @@ process_model_line
ERR(process_scale(stardis, pwordexp));
else if(0 == strcasecmp(arg, "TRAD"))
ERR(process_radiative(stardis, pwordexp));
+ else if(0 == strcasecmp(arg, "SPHERICAL_SOURCE"))
+ ERR(process_spherical_source(stardis, pwordexp));
+ else if(0 == strcasecmp(arg, "SPHERICAL_SOURCE_PROG"))
+ ERR(process_spherical_source_prog(stardis, pwordexp));
else {
logger_print(stardis->logger, LOG_ERROR,
"Unknown description type: %s\n", arg);
diff --git a/src/stardis-prog-properties.h.in b/src/stardis-prog-properties.h.in
@@ -592,6 +592,26 @@ stardis_t_range
(void* data,
double range[2]);
+/******************************************************************************/
+/* Additional mandatory functions for a programmed spherical source */
+/* These functions are used to calculate the external flux at the boundaries. */
+/******************************************************************************/
+
+/* Retrieve the position of the spherical source center.
+ * This function is used to calculate the external flux at the boundaries.
+ * Returns its modified position argument */
+STARDIS_API double*
+stardis_spherical_source_position
+ (const double time, /* [s] */
+ double position[3],
+ void* data);
+
+/* Retrieve the power of the spherical source. */
+STARDIS_API double /* [W] */
+stardis_spherical_source_power
+ (const double time,
+ void* data);
+
#ifdef __cplusplus
} /* extern "C" */
#endif