commit 6c37b660c75f4f06a754884eab603f0da98fc6f2
parent e5b8bf90704f6afe9cfa8e27f0257cb969d9300d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 27 Feb 2024 15:16:26 +0100
Add external source support
Currently, only one external source with constant parameters is
supported. But data structures and functions have been designed with all
types of external source in mind. Spherical sources with programmable
properties should be easy to handle, but so should totally different
sources (e.g. directional sources) if the solver provides them.
Note that while everything is written down to the solver, this new
feature has not yet been tested.
Diffstat:
6 files changed, 259 insertions(+), 0 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/src/stardis-app.c b/src/stardis-app.c
@@ -281,6 +281,9 @@ stardis_init
stardis->verbose = args->verbose;
darray_media_ptr_init(stardis->allocator, &stardis->media);
+ /* Init the external source */
+ extern_source_init(&stardis->extsrc);
+
/* If a dump is expected, we won't process any computation */
is_for_compute =
(stardis->mode & COMPUTE_MODES) && !(stardis->mode & MODE_DUMP_MODEL);
@@ -508,6 +511,7 @@ stardis_init
scn_args.trad.temperature = stardis->trad;
scn_args.trad.reference = stardis->trad_ref;
d2_set(scn_args.t_range, stardis->t_range);
+ scn_args.source = stardis->extsrc.sdis_src;
scn_args.context = &create_context;
res = sdis_scene_create(stardis->dev, &scn_args, &stardis->sdis_scn);
if(res != RES_OK) {
@@ -576,6 +580,7 @@ stardis_release
release_solid(stardis->dummies.stardis_solid, stardis->allocator);
}
darray_probe_boundary_release(&stardis->probe_boundary_list);
+ extern_source_release(&stardis->extsrc);
}
unsigned
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,7 @@ struct stardis {
int mpi_rank;
struct darray_probe_boundary probe_boundary_list;
+ struct extern_source extsrc;
};
unsigned
diff --git a/src/stardis-extern-source.c b/src/stardis-extern-source.c
@@ -0,0 +1,119 @@
+/* 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 extern_source* src = NULL;
+ ASSERT(pos);
+ (void)time;
+
+ src = sdis_data_cget(data);
+ ASSERT(src->type == EXTERN_SOURCE_SPHERE);
+
+ pos[0] = src->data.sphere.position[0];
+ pos[1] = src->data.sphere.position[1];
+ pos[2] = src->data.sphere.position[2];
+}
+
+static double
+sphere_get_power(const double time, struct sdis_data* data)
+{
+ const struct extern_source* src = NULL;
+ (void)time;
+
+ src = sdis_data_cget(data);
+ ASSERT(src->type == EXTERN_SOURCE_SPHERE);
+
+ return src->data.sphere.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 extern_source*),
+ ALIGNOF(struct extern_source*), NULL, &data);
+ if(res != RES_OK) goto error;
+ *((struct extern_source**)sdis_data_get(data)) = src;
+
+ /* 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;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+void
+extern_source_release(struct extern_source* src)
+{
+ ASSERT(src);
+ 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;
+ 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,66 @@
+/* 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;
+
+enum source_type {
+ EXTERN_SOURCE_SPHERE,
+ 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__;
+
+/* Interface of an external source */
+struct extern_source {
+ enum source_type type;
+ union {
+ struct spherical_source sphere;
+ } 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__;
+
+static INLINE void
+extern_source_init(struct extern_source* src)
+{
+ ASSERT(src);
+ *src = EXTERN_SOURCE_NULL;
+}
+
+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-parsing.c b/src/stardis-parsing.c
@@ -2070,6 +2070,70 @@ 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;
+ }
+
+ 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;
+ }
+
+ stardis->extsrc.type = EXTERN_SOURCE_SPHERE;
+
+ res = extern_source_create_solver_source(&stardis->extsrc, stardis);
+ if(res != RES_OK) goto error;
+
+exit:
+ return res;
+error:
+ 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 +2215,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, "SPHERICAL_SOURCE"))
+ ERR(process_spherical_source(stardis, pwordexp));
else {
logger_print(stardis->logger, LOG_ERROR,
"Unknown description type: %s\n", arg);