commit ad678ad41e1cf824b476f282eef66fe1e23e3abb
parent df905225f1ae87e37154761916e6bbedad739919
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 19 Jun 2024 10:23:28 +0200
Allows the caller to define their own solid path sampling
This commit adds the sampling_path functor to the solid shader data
structure, allowing the user to take charge of the sampling strategy for
a solid path. In this way, the solver no longer samples it using its
internal algorithms, but calls this user-supplied function.
It's a simple way of achieving external coupling: the solver samples the
other transfer types, solves the coupling physics and then hands over to
the user to solve, by Monte Carlo, his solid physics.
In detail, the sampling function profile has as arguments the scene, an
RNG and a path, whose data type reflects the rwalk internal data
structure used when sampling a coupled path. On the return, the internal
random walk will be updated from the sampled path in order to continue
the Monte Carlo realisation.
Diffstat:
5 files changed, 137 insertions(+), 49 deletions(-)
diff --git a/src/sdis.h b/src/sdis.h
@@ -220,6 +220,40 @@ struct sdis_scene_find_closest_point_args {
static const struct sdis_scene_find_closest_point_args
SDIS_SCENE_FIND_CLOSEST_POINT_ARGS_NULL = SDIS_SCENE_FIND_CLOSEST_POINT_ARGS_NULL__;
+/* A sampled path */
+struct sdis_path {
+ struct sdis_rwalk_vertex vtx; /* Current position and time */
+
+ /* Surface intersection. When defined, the path is on a border */
+ struct s2d_hit hit_2d;
+ struct s3d_hit hit_3d;
+
+ double elapsed_time; /* Time elapsed along the path */
+ double weight; /* Monte Carlo weight update along the path */
+
+ /* Define whether the path has reached a boundary condition in time/space */
+ int at_limit;
+};
+#define SDIS_PATH_NULL__ { \
+ SDIS_RWALK_VERTEX_NULL__, \
+ S2D_HIT_NULL__, \
+ S3D_HIT_NULL__, \
+ 0, /* Elapsed time */ \
+ 0, /* MC weight */ \
+ 0 /* At limit */ \
+}
+static const struct sdis_path SDIS_PATH_NULL = SDIS_PATH_NULL__;
+
+/* Type of functor used by the user to write the way in which the path is
+ * sampled. So it's no longer Stardis that samples the path, but the user
+ * through his own function. */
+typedef res_T
+(*sdis_sample_path_T)
+ (struct sdis_scene* scn,
+ struct ssp_rng* rng,
+ struct sdis_path* path,
+ struct sdis_data* data);
+
/*******************************************************************************
* Estimation data types
******************************************************************************/
@@ -294,12 +328,16 @@ struct sdis_solid_shader {
* This getter is always called at time >= t0 (see below). */
sdis_medium_getter_T temperature;
+ /* Function to be used to sample the path through the solid. If not defined,
+ * let stardis sample a conductive path */
+ sdis_sample_path_T sample_path;
+
/* The time until the initial condition is maintained for this solid.
* Can be negative or set to +/- infinity to simulate a system that is always
* in the initial state or never reaches it, respectively. */
double t0;
};
-#define SDIS_SOLID_SHADER_NULL__ {NULL, NULL, NULL, NULL, NULL, NULL, 0}
+#define SDIS_SOLID_SHADER_NULL__ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0}
static const struct sdis_solid_shader SDIS_SOLID_SHADER_NULL =
SDIS_SOLID_SHADER_NULL__;
diff --git a/src/sdis_heat_path_conductive.c b/src/sdis_heat_path_conductive.c
@@ -13,10 +13,10 @@
* 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 "sdis_heat_path.h"
-#include "sdis_heat_path_conductive_c.h"
#include "sdis_log.h"
+#include "sdis_heat_path_conductive_c.h"
#include "sdis_medium_c.h"
+#include "sdis_scene_c.h"
/*******************************************************************************
* Local function
@@ -71,54 +71,12 @@ error:
goto exit;
}
-res_T
-conductive_path_2d
- (struct sdis_scene* scn,
- struct rwalk_context* ctx,
- struct rwalk* rwalk,
- struct ssp_rng* rng,
- struct temperature* T)
-{
- res_T res = RES_OK;
- ASSERT(ctx);
-
- switch(ctx->diff_algo) {
- case SDIS_DIFFUSION_DELTA_SPHERE:
- res = conductive_path_delta_sphere_2d(scn, ctx, rwalk, rng, T);
- break;
- case SDIS_DIFFUSION_WOS:
- res = conductive_path_wos_2d(scn, ctx, rwalk, rng, T);
- break;
- default: FATAL("Unreachable code.\n"); break;
- }
- return res;
-}
-
-res_T
-conductive_path_3d
- (struct sdis_scene* scn,
- struct rwalk_context* ctx,
- struct rwalk* rwalk,
- struct ssp_rng* rng,
- struct temperature* T)
-{
- res_T res = RES_OK;
- ASSERT(ctx);
-
- switch(ctx->diff_algo) {
- case SDIS_DIFFUSION_DELTA_SPHERE:
- res = conductive_path_delta_sphere_3d(scn, ctx, rwalk, rng, T);
- break;
- case SDIS_DIFFUSION_WOS:
- res = conductive_path_wos_3d(scn, ctx, rwalk, rng, T);
- break;
- default: FATAL("Unreachable code.\n"); break;
- }
- return res;
-}
-
/* Generate the conductive path functions */
#define SDIS_XD_DIMENSION 2
+#include "sdis_heat_path_conductive_Xd.h"
+#define SDIS_XD_DIMENSION 3
+#include "sdis_heat_path_conductive_Xd.h"
+#define SDIS_XD_DIMENSION 2
#include "sdis_heat_path_conductive_delta_sphere_Xd.h"
#define SDIS_XD_DIMENSION 3
#include "sdis_heat_path_conductive_delta_sphere_Xd.h"
diff --git a/src/sdis_heat_path_conductive_Xd.h b/src/sdis_heat_path_conductive_Xd.h
@@ -0,0 +1,89 @@
+/* Copyright (C) 2016-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 "sdis.h"
+#include "sdis_heat_path.h"
+#include "sdis_heat_path_conductive_c.h"
+#include "sdis_log.h"
+#include "sdis_medium_c.h"
+#include "sdis_scene_c.h"
+
+#include <rsys/cstr.h>
+
+#include "sdis_Xd_begin.h"
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+XD(conductive_path)
+ (struct sdis_scene* scn,
+ struct rwalk_context* ctx,
+ struct rwalk* rwalk,
+ struct ssp_rng* rng,
+ struct temperature* T)
+{
+ struct sdis_medium* mdm = NULL;
+ unsigned enc_id = ENCLOSURE_ID_NULL;
+ res_T res = RES_OK;
+ ASSERT(ctx && rwalk);
+
+ res = scene_get_enclosure_id_in_closed_boundaries(scn, rwalk->vtx.P, &enc_id);
+ if(res != RES_OK) goto error;
+ res = scene_get_enclosure_medium(scn, scene_get_enclosure(scn, enc_id), &mdm);
+ if(res != RES_OK) goto error;
+ ASSERT(sdis_medium_get_type(mdm) == SDIS_SOLID);
+
+ if(mdm->shader.solid.sample_path == NULL) {
+ switch(ctx->diff_algo) {
+ case SDIS_DIFFUSION_DELTA_SPHERE:
+ res = XD(conductive_path_delta_sphere)(scn, ctx, rwalk, rng, T);
+ break;
+ case SDIS_DIFFUSION_WOS:
+ res = XD(conductive_path_wos)(scn, ctx, rwalk, rng, T);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ if(res != RES_OK) goto error;
+
+ /* The caller defined a custom function to sample the solid path */
+ } else {
+ struct sdis_path path = SDIS_PATH_NULL;
+ path.vtx = rwalk->vtx;
+ res = mdm->shader.solid.sample_path(scn, rng, &path, mdm->data);
+
+ if(res != RES_OK) {
+ log_err(scn->dev,
+ "%s: error in customized sampling of a conductive path "
+ "from pos=("FORMAT_VECX") -- %s\n",
+ FUNC_NAME, SPLITX(rwalk->vtx.P), res_to_cstr(res));
+ goto error;
+ }
+
+ /* Update the Monte Carlo realisation from the returned sampled path */
+ rwalk->vtx = path.vtx;
+ rwalk->XD(hit) = path.XD(hit);
+ rwalk->elapsed_time += path.elapsed_time;
+ T->value += path.weight;
+ T->done = path.at_limit;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+#include "sdis_Xd_end.h"
diff --git a/src/sdis_log.h b/src/sdis_log.h
@@ -28,6 +28,8 @@
#define MSG_ERROR_PREFIX_PLAIN_TEXT "stardis-solver (error): "
#define MSG_WARNING_PREFIX_PLAIN_TEXT "stardis-solver (warning): "
+struct sdis_device;
+
extern LOCAL_SYM res_T
setup_log_default
(struct sdis_device* dev);
diff --git a/src/test_sdis_utils.h b/src/test_sdis_utils.h
@@ -195,6 +195,7 @@ static const struct sdis_solid_shader DUMMY_SOLID_SHADER = {
dummy_medium_getter, /* Delta */
dummy_medium_getter, /* Volumic power */
dummy_medium_getter, /* Temperature */
+ NULL, /* sample path */
0 /* Initial time */
};