commit e381e777826b313d3580461dfd5b4d2648cbc3e6
parent b886d9c03a3a53fb4066a2b5a131a078b50f20a3
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 8 Apr 2024 18:38:12 +0200
Start implementing an unsteady test
Add a library that defines spatio-temporal boundary conditions from the
unsteady profile. And start implementing a test that defines a super
shape with spatio-temporal Dirichlet conditions controlled by this
library. The command line to be executed and the validation of its
output remain to be done.
The makefile is updated to automate the construction of the libraries
without making them a dependency of the tests that use them. They should
be a dependency of these tests if they were necessary to their
construction, but these tests use them as data in the Stardis file they
generate.
Diffstat:
3 files changed, 488 insertions(+), 20 deletions(-)
diff --git a/Makefile b/Makefile
@@ -18,10 +18,18 @@
include config.mk
-TESTS = sadist_probe_boundary sadist_external_flux
+TESTS =\
+ sadist_external_flux\
+ sadist_probe_boundary\
+ sadist_unsteady
+
+LIBS =\
+ libsadist_spherical_source.so\
+ libsadist_trilinear_profile.so\
+ libsadist_unsteady_profile.so\
# Default target
-default: .config $(TESTS)
+default: .config $(TESTS) $(LIBS)
.config:
@if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \
@@ -33,9 +41,9 @@ default: .config $(TESTS)
clean:
rm -f .config src/*.o src/*.d
rm -f ground.stl sphere.stl sshape.stl wall.stl probes.txt scene.txt
- rm -f libsadist_trilinear_profile.so libsadist_spherical_source.so $(TESTS)
+ rm -f $(TESTS) $(LIBS)
-test: $(TESTS)
+test: $(TESTS) $(LIBS)
@$(SHELL) make.sh check sadist_probe_boundary ./sadist_probe_boundary
@$(SHELL) make.sh check sadist_probe_boundary_list ./sadist_probe_boundary -p4
@$(SHELL) make.sh check sadist_external_flux ./sadist_external_flux
@@ -43,6 +51,13 @@ test: $(TESTS)
################################################################################
# Libraries
################################################################################
+src/sadist_lib_spherical_source.o: config.mk src/sadist_lib_spherical_source.c
+ $(CC) $(CFLAGS_SO) $(RSYS_CFLAGS) -c $(@:.o=.c) -o $@
+
+libsadist_spherical_source.so: config.mk src/sadist_lib_spherical_source.o
+ $(CC) $(CFLAGS_SO) $(RSYS_CFLAGS) -o $@ src/sadist_lib_spherical_source.o \
+ $(LDFLAGS_SO) $(RSYS_LIBS)
+
src/sadist_lib_trilinear_profile.o:\
config.mk\
src/sadist.h\
@@ -53,37 +68,44 @@ libsadist_trilinear_profile.so: src/sadist_lib_trilinear_profile.o
$(CC) $(CFLAGS_SO) $(RSYS_CFLAGS) -o $@ src/sadist_lib_trilinear_profile.o \
$(LDFLAGS_SO) $(RSYS_LIBS)
-src/sadist_lib_spherical_source.o: config.mk src/sadist_lib_spherical_source.c
+src/sadist_lib_unsteady_profile.o:\
+ config.mk\
+ src/sadist.h\
+ src/sadist_lib_unsteady_profile.c
$(CC) $(CFLAGS_SO) $(RSYS_CFLAGS) -c $(@:.o=.c) -o $@
-libsadist_spherical_source.so: config.mk src/sadist_lib_spherical_source.o
- $(CC) $(CFLAGS_SO) $(RSYS_CFLAGS) -o $@ src/sadist_lib_spherical_source.o \
- $(LDFLAGS_SO) $(RSYS_LIBS)
+libsadist_unsteady_profile.so: src/sadist_lib_unsteady_profile.o
+ $(CC) $(CFLAGS_SO) $(RSYS_CFLAGS) -o $@ src/sadist_lib_unsteady_profile.o \
+ $(LDFLAGS_SO) $(RSYS_LIBS) -lm
################################################################################
# Tests
################################################################################
+src/sadist_external_flux.o:\
+ config.mk\
+ src/sadist.h\
+ src/sadist_external_flux.c
+ $(CC) $(CFLAGS_EXE) -c $(@:.o=.c) -o $@
+
+sadist_external_flux: config.mk src/sadist_external_flux.o
+ $(CC) $(CFLAGS_EXE) -o $@ src/$@.o $(LDFLAGS_EXE) $(RSYS_LIBS) -lm
+
src/sadist_probe_boundary.o:\
config.mk\
src/sadist.h\
src/sadist_probe_boundary.c
$(CC) $(CFLAGS_EXE) $(S3DUT_CFLAGS) $(RSYS_CFLAGS) -c $(@:.o=.c) -o $@
-sadist_probe_boundary:\
- config.mk\
- src/sadist_probe_boundary.o\
- libsadist_trilinear_profile.so
+sadist_probe_boundary: config.mk src/sadist_probe_boundary.o
$(CC) $(CFLAGS_EXE) $(S3DUT_CFLAGS) $(RSYS_CFLAGS) -o $@ src/$@.o \
$(LDFLAGS_EXE) $(S3DUT_LIBS) $(RSYS_LIBS) -lm
-src/sadist_external_flux.o:\
+src/sadist_unsteady.o:\
config.mk\
src/sadist.h\
- src/sadist_external_flux.c
- $(CC) $(CFLAGS_EXE) -c $(@:.o=.c) -o $@
+ src/sadist_unsteady.c
+ $(CC) $(CFLAGS_EXE) $(S3DUT_CFLAGS) $(RSYS_CFLAGS) -c $(@:.o=.c) -o $@
-sadist_external_flux:\
- config.mk\
- src/sadist_external_flux.o\
- libsadist_spherical_source.so
- $(CC) $(CFLAGS_EXE) -o $@ src/$@.o $(LDFLAGS_EXE) $(RSYS_LIBS) -lm
+sadist_unsteady: config.mk src/sadist_unsteady.o
+ $(CC) $(CFLAGS_EXE) $(S3DUT_CFLAGS) $(RSYS_CFLAGS) -o $@ src/$@.o \
+ $(LDFLAGS_EXE) $(S3DUT_LIBS) $(RSYS_LIBS) -lm
diff --git a/src/sadist_lib_unsteady_profile.c b/src/sadist_lib_unsteady_profile.c
@@ -0,0 +1,284 @@
+/* Copyright (C) 2024 |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 "sadist.h"
+
+#include <stardis/stardis-prog-properties.h>
+
+#include <rsys/cstr.h>
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+
+#include <stdarg.h> /* va_list */
+#include <getopt.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+print_usage(FILE* stream, const char* name)
+{
+ fprintf(stream,
+"usage: %s [-h] [-k kx,ky,kz] [-m lambda,rho,cp] [-p A,B1,B2]\n", name);
+}
+
+static res_T
+parse_periodicities(struct sadist_unsteady_profile* profile, const char* str)
+{
+ double vec[3] = {0, 0, 0};
+ size_t len = 0;
+ res_T res = RES_OK;
+ ASSERT(profile && str);
+
+ res = cstr_to_list_double(str, ',', vec, &len, 3);
+ if(res == RES_OK && len != 3) res = RES_BAD_ARG;
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "%s:%d: unable to parse the periodicity parmeters `%s' -- %s\n",
+ __FILE__, __LINE__, str, res_to_cstr(res));
+ goto error;
+ }
+
+ profile->kx = vec[0];
+ profile->ky = vec[1];
+ profile->kz = vec[2];
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_medium_properties
+ (struct sadist_unsteady_profile* profile,
+ const char* str)
+{
+ double vec[3] = {0, 0, 0};
+ size_t len = 0;
+ res_T res = RES_OK;
+ ASSERT(profile && str);
+
+ res = cstr_to_list_double(str, ',', vec, &len, 3);
+ if(res == RES_OK && len != 3) res = RES_BAD_ARG;
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "%s:%d: unable to parse the medium properties `%s' -- %s\n",
+ __FILE__, __LINE__, str, res_to_cstr(res));
+ goto error;
+ }
+
+ if(vec[0] <= 0) { /* Lambda */
+ fprintf(stderr,
+ "%s:%d: invalid thermal conductivity %g. It cannot be negative or null\n",
+ __FILE__, __LINE__, vec[0]);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(vec[1] <= 0) { /* rho */
+ fprintf(stderr,
+ "%s:%d: invalid volumic mass %g. It cannot be negative or null\n",
+ __FILE__, __LINE__, vec[1]);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(vec[2] <= 0) { /* cp */
+ fprintf(stderr,
+ "%s:%d: invalid calorific capacity%g. It cannot be negative or null\n",
+ __FILE__, __LINE__, vec[2]);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ profile->lambda = vec[0];
+ profile->rho = vec[1];
+ profile->cp = vec[2];
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_scale_factors
+ (struct sadist_unsteady_profile* profile,
+ const char* str)
+{
+ double vec[3] = {0, 0, 0};
+ size_t len = 0;
+ res_T res = RES_OK;
+ ASSERT(profile && str);
+
+ res = cstr_to_list_double(str, ',', vec, &len, 3);
+ if(res == RES_OK && len != 3) res = RES_BAD_ARG;
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "%s:%d: unable to parse the scale factors `%s' -- %s\n",
+ __FILE__, __LINE__, str, res_to_cstr(res));
+ goto error;
+ }
+
+ if(vec[0] < 0 || vec[1] < 0 || vec[2] < 0) {
+ fprintf(stderr,
+ "%s:%d: invalid scale factors `%s'. They cannot be negative\n",
+ __FILE__, __LINE__, str);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ profile->A = vec[0];
+ profile->B1 = vec[1];
+ profile->B2 = vec[2];
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_args
+ (const struct stardis_description_create_context* ctx,
+ struct sadist_unsteady_profile* profile,
+ int argc,
+ char* argv[])
+{
+ int opt;
+ res_T res = RES_OK;
+ ASSERT(ctx && profile);
+
+ optind = 1;
+ while((opt = getopt(argc, argv, "hk:m:p:")) != -1) {
+ switch(opt) {
+ case 'h':
+ print_usage(stdout, ctx->name);
+ break;
+ case 'k':
+ res = parse_periodicities(profile, optarg);
+ if(res != RES_OK) goto error;
+ break;
+ case 'm':
+ res = parse_medium_properties(profile, optarg);
+ if(res != RES_OK) goto error;
+ break;
+ case 'p':
+ res = parse_scale_factors(profile, optarg);
+ if(res != RES_OK) goto error;
+ break;
+ default: res = RES_BAD_ARG; break;
+ }
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+/*******************************************************************************
+ * Legal notices
+ ******************************************************************************/
+const char*
+get_copyright_notice(void* data)
+{
+ (void)data; /* Avoid "unused variable" warnings */
+ return "Copyright (C) 2024 |Méso|Star> (contact@meso-star.com)";
+}
+
+const char*
+get_license_short(void* data)
+{
+ (void)data; /* Avoid "unused variable" warnings */
+ return "GNU GPL version 3 or later <http://www.gnu.org/licenses/>";
+}
+
+const char*
+get_license_text(void* data)
+{
+ (void)data; /* Avoid "unused variable" warnings */
+ return
+ "This is free software released under the GPL v3+ license: GNU GPL\n"
+ "version 3 or later. You are welcome to redistribute it under certain\n"
+ "conditions; refer to <http://www.gnu.org/licenses/> for details.";
+}
+
+
+/*******************************************************************************
+ * Create data
+ ******************************************************************************/
+void*
+stardis_create_data
+ (const struct stardis_description_create_context* ctx,
+ void* libdata,
+ size_t argc,
+ char* argv[])
+{
+ struct sadist_unsteady_profile* profile = NULL;
+ res_T res = RES_OK;
+ (void)libdata;
+
+ profile = mem_alloc(sizeof(*profile));
+ if(!profile) {
+ fprintf(stderr, "%s:%d: error allocating the unsteady profile.\n",
+ __FILE__, __LINE__);
+ goto error;
+ }
+
+ *profile = SADIST_UNSTEADY_PROFILE_NULL;
+
+ res = parse_args(ctx, profile, (int)argc, argv);
+ if(res != RES_OK) goto error;
+
+exit:
+ return profile;
+error:
+ if(profile) {
+ mem_rm(profile);
+ profile = NULL;
+ }
+ goto exit;
+}
+
+void
+stardis_release_data(void* data)
+{
+ ASSERT(data);
+ mem_rm(data);
+}
+
+/*******************************************************************************
+ * Boundary condition
+ ******************************************************************************/
+double
+stardis_boundary_temperature
+ (const struct stardis_interface_fragment* frag,
+ void* data)
+{
+ ASSERT(frag && data);
+ return sadist_unsteady_profile_temperature(data, frag->P, frag->time);
+}
+
+double*
+stardis_t_range(void* data, double range[2])
+{
+ ASSERT(data && range);
+ (void)data;
+ range[0] = -INF;
+ range[1] = INF;
+ return range;
+}
diff --git a/src/sadist_unsteady.c b/src/sadist_unsteady.c
@@ -0,0 +1,162 @@
+/* Copyright (C) 2024 |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 "sadist.h"
+
+#include <star/s3dut.h>
+
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+
+#include <string.h> /* strerror */
+#include <errno.h>
+
+/*
+ * The system is an unsteady-state temperature profile, meaning that at any
+ * point, at any: time, we can analytically calculate the temperature. We
+ * immerse in this temperature field a supershape representing a solid in which
+ * we want to evaluate the temperature by Monte Carlo at a given position and
+ * observation time. On the Monte Carlo side, the temperature of the supershape
+ * is unknown. Only the boundary temperature is fixed at the temperature of the
+ * unsteady trilinear profile mentioned above. Monte Carlo would then have to
+ * find the temperature defined by the unsteady profile.
+ *
+ * T(z) /\ <-- T(x,y,z,t)
+ * | T(y) ___/ \___
+ * |/ \ . T=? /
+ * o--- T(x) /_ __ _\
+ * \/ \/
+ */
+
+#define FILENAME_SSHAPE "sshape.stl"
+#define FILENAME_SCENE "scene.txt"
+
+#define LAMBDA 0.1 /* [W/(m.K)] */
+#define RHO 25.0 /* [kg/m^3] */
+#define CP 2.0 /* [J/K/kg)] */
+#define DELTA 1.0/20.0 /* [m/fp_to_meter] */
+
+/* Parameters of the unsteady profile */
+#define UPROF_A 0.0
+#define UPROF_B1 10.0
+#define UPROF_B2 1000.0
+#define UPROF_K (PI/4.0)
+
+#define NREALISATIONS 100000
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+setup_sshape(FILE* stream)
+{
+ struct s3dut_mesh* sshape = NULL;
+ struct s3dut_mesh_data sshape_data;
+ struct s3dut_super_formula f0 = S3DUT_SUPER_FORMULA_NULL;
+ struct s3dut_super_formula f1 = S3DUT_SUPER_FORMULA_NULL;
+ const double radius = 2;
+ const unsigned nslices = 256;
+
+ f0.A = 1.5; f0.B = 1; f0.M = 11.0; f0.N0 = 1; f0.N1 = 1; f0.N2 = 2.0;
+ f1.A = 1.0; f1.B = 2; f1.M = 3.6; f1.N0 = 1; f1.N1 = 2; f1.N2 = 0.7;
+ S3DUT(create_super_shape(NULL, &f0, &f1, radius, nslices, nslices/2, &sshape));
+ S3DUT(mesh_get_data(sshape, &sshape_data));
+
+ sadist_write_stl(stream, sshape_data.positions, sshape_data.nvertices,
+ sshape_data.indices, sshape_data.nprimitives);
+
+ S3DUT(mesh_ref_put(sshape));
+}
+
+static void
+setup_scene
+ (FILE* fp,
+ const char* sshape,
+ struct sadist_unsteady_profile* profile)
+{
+ ASSERT(sshape && profile);
+
+ fprintf(fp, "PROGRAM unsteady_profile libsadist-unsteady-profile.so\n");
+ fprintf(fp, "SOLID SuperShape %g %g %g %g 0 UNKNOWN 0 BACK %s\n",
+ LAMBDA, RHO, CP, DELTA, sshape);
+
+ fprintf(fp, "T_BOUNDARY_FOR_SOLID_PROG Dirichlet unsteady_profile %s", sshape);
+ fprintf(fp, " PROG_PARAMS dummy -p %g,%g,%g -k %g,%g,%g -m %g,%g,%g\n",
+ UPROF_A, UPROF_B1, UPROF_B2, UPROF_K, UPROF_K, UPROF_K, LAMBDA, RHO, CP);
+
+ profile->A = UPROF_A;
+ profile->B1 = UPROF_B1;
+ profile->B2 = UPROF_B2;
+ profile->kx = UPROF_K;
+ profile->ky = UPROF_K;
+ profile->kz = UPROF_K;
+ profile->lambda = LAMBDA;
+ profile->rho = RHO;
+ profile->cp = CP;
+}
+
+static int
+init(struct sadist_unsteady_profile* profile)
+{
+ FILE* fp_sshape = NULL;
+ FILE* fp_scene = NULL;
+ int err = 0;
+
+ if((fp_sshape = fopen(FILENAME_SSHAPE, "w")) == NULL) {
+ fprintf(stderr, "Error opening the `"FILENAME_SSHAPE"' file -- %s\n",
+ strerror(errno));
+ err = errno;
+ goto error;
+ }
+
+ if((fp_scene = fopen(FILENAME_SCENE, "w")) == NULL) {
+ fprintf(stderr, "Error opening the `"FILENAME_SCENE"' file -- %s\n",
+ strerror(errno));
+ err = errno;
+ goto error;
+ }
+
+ setup_sshape(fp_sshape);
+ setup_scene(fp_scene, FILENAME_SSHAPE, profile);
+
+exit:
+ if(fp_sshape && fclose(fp_sshape)) { perror("fclose"); if(!err) err = errno; }
+ if(fp_scene && fclose(fp_scene)) { perror("fclose"); if(!err) err = errno; }
+ return err;
+error:
+ goto exit;
+}
+
+/*******************************************************************************
+ * The test
+ ******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct sadist_unsteady_profile profile = SADIST_UNSTEADY_PROFILE_NULL;
+ int err = 0;
+ (void)argc, (void)argv;
+
+ if((err = init(&profile))) goto error;
+
+exit:
+ if(mem_allocated_size() != 0) {
+ fprintf(stderr, "Memory leaks: %lu bytes\n", mem_allocated_size());
+ if(!err) err = -1;
+ }
+ return err;
+error:
+ goto exit;
+}