commit 24a276b93f621383ca91bcd20becb79abb62e7f7
parent 4dda85dd8502656116bf560dac56e007d63ea8df
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 27 Jul 2020 14:39:09 +0200
Handle "time rewind" in a specific function
Diffstat:
7 files changed, 145 insertions(+), 38 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -71,6 +71,7 @@ set(SDIS_FILES_SRC
sdis_interface.c
sdis_log.c
sdis_medium.c
+ sdis_misc.c
sdis_realisation.c
sdis_scene.c
sdis_solve.c)
@@ -90,6 +91,8 @@ set(SDIS_FILES_INC
sdis_heat_path_radiative_Xd.h
sdis_interface_c.h
sdis_log.h
+ sdis_misc.h
+ sdis_misc_Xd.h
sdis_medium_c.h
sdis_realisation.h
sdis_realisation_Xd.h
diff --git a/src/sdis_heat_path_conductive_Xd.h b/src/sdis_heat_path_conductive_Xd.h
@@ -235,8 +235,6 @@ XD(conductive_path)
do { /* Solid random walk */
struct sXd(hit) hit0, hit1;
double lambda; /* Thermal conductivity */
- double rho; /* Volumic mass */
- double cp; /* Calorific capacity */
double tmp;
double power_factor = 0;
double power;
@@ -244,7 +242,7 @@ XD(conductive_path)
float dir0[DIM], dir1[DIM];
float org[DIM];
- /* Check the limit condition
+ /* Check the limit condition
* REVIEW Rfo: This can be a bug if the random walk comes from a boundary */
tmp = solid_get_temperature(mdm, &rwalk->vtx);
if(tmp >= 0) {
@@ -267,8 +265,6 @@ XD(conductive_path)
/* Fetch solid properties */
delta_solid = (float)solid_get_delta(mdm, &rwalk->vtx);
lambda = solid_get_thermal_conductivity(mdm, &rwalk->vtx);
- rho = solid_get_volumic_mass(mdm, &rwalk->vtx);
- cp = solid_get_calorific_capacity(mdm, &rwalk->vtx);
power = solid_get_volumic_power(mdm, &rwalk->vtx);
if(ctx->green_path && power_ref != power) {
@@ -346,39 +342,12 @@ XD(conductive_path)
green_power_factor += power_factor;
}
- /* Sample the time */
- if(!IS_INF(rwalk->vtx.time)) {
- double tau, mu, t0;
- mu = (2*DIM*lambda) / (rho*cp*delta*fp_to_meter*delta*fp_to_meter);
- tau = ssp_ran_exp(rng, mu);
- t0 = ctx->green_path ? -INF : solid_get_t0(rwalk->mdm);
- rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0);
- if(rwalk->vtx.time == t0) {
- /* Check the initial condition */
- tmp = solid_get_temperature(mdm, &rwalk->vtx);
- if(tmp >= 0) {
- T->value += tmp;
- T->done = 1;
-
- if(ctx->heat_path) {
- struct sdis_heat_vertex* vtx;
- vtx = heat_path_get_last_vertex(ctx->heat_path);
- vtx->time = rwalk->vtx.time;
- vtx->weight = T->value;
- }
- break;
- }
- /* The initial condition should have been reached */
- log_err(scn->dev,
- "%s: undefined initial condition. "
- "The time is %g but the temperature remains unknown.\n",
- FUNC_NAME, t0);
- res = RES_BAD_OP;
- goto error;
- }
- }
+ /* Rewind the time */
+ res = XD(time_rewind)(rwalk->mdm, rng, delta, fp_to_meter, ctx, rwalk, T);
+ if(res != RES_OK) goto error;
+ if(T->done) break; /* Limit condition was reached */
- /* Define if the random walk hits something along dir0 */
+ /* Define if the random walk hits something along dir0 */
if(hit0.distance > delta) {
rwalk->hit = SXD_HIT_NULL;
rwalk->hit_side = SDIS_SIDE_NULL__;
diff --git a/src/sdis_medium_c.h b/src/sdis_medium_c.h
@@ -18,7 +18,9 @@
#include "sdis.h"
+#include <rsys/free_list.h>
#include <rsys/math.h>
+#include <rsys/ref_count.h>
struct sdis_medium {
enum sdis_medium_type type;
diff --git a/src/sdis_misc.c b/src/sdis_misc.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2016-2020 |Meso|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"
+
+/* Generate the generic functions */
+#define SDIS_XD_DIMENSION 2
+#include "sdis_misc_Xd.h"
+#define SDIS_XD_DIMENSION 3
+#include "sdis_misc_Xd.h"
+
diff --git a/src/sdis_misc.h b/src/sdis_misc.h
@@ -134,4 +134,24 @@ register_heat_vertex
return heat_path_add_vertex(path, &heat_vtx);
}
+extern LOCAL_SYM res_T
+time_rewind_2d
+ (const struct sdis_medium* mdm, /* Medium into which the time is rewinded */
+ struct ssp_rng* rng,
+ const double delta,
+ const double fp_to_meter,
+ const struct rwalk_context* ctx,
+ struct rwalk_2d* rwalk,
+ struct temperature_2d* T);
+
+extern LOCAL_SYM res_T
+time_rewind_3d
+ (const struct sdis_medium* mdm, /* Medium into which the time is rewinded */
+ struct ssp_rng* rng,
+ const double delta,
+ const double fp_to_meter,
+ const struct rwalk_context* ctx,
+ struct rwalk_3d* rwalk,
+ struct temperature_3d* T);
+
#endif /* SDIS_MISC_H */
diff --git a/src/sdis_misc_Xd.h b/src/sdis_misc_Xd.h
@@ -0,0 +1,91 @@
+/* Copyright (C) 2016-2020 |Meso|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_heat_path.h"
+#include "sdis_log.h"
+#include "sdis_medium_c.h"
+#include "sdis_misc.h"
+
+#include <star/ssp.h>
+
+#include "sdis_Xd_begin.h"
+
+res_T
+XD(time_rewind)
+ (const struct sdis_medium* mdm,
+ struct ssp_rng* rng,
+ const double delta,
+ const double fp_to_meter,
+ const struct rwalk_context* ctx,
+ struct XD(rwalk)* rwalk,
+ struct XD(temperature)* T)
+{
+ const double delta_in_meter = delta * fp_to_meter;
+ double temperature;
+ double lambda, rho, cp;
+ double tau, mu, t0;
+ res_T res = RES_OK;
+ ASSERT(mdm && rng && delta && fp_to_meter && ctx && rwalk);
+ ASSERT(sdis_medium_get_type(mdm) == SDIS_SOLID);
+ ASSERT(T->done == 0);
+
+ if(IS_INF(rwalk->vtx.time)) goto exit;
+
+ /* Fetch phyisical properties */
+ lambda = solid_get_thermal_conductivity(mdm, &rwalk->vtx);
+ rho = solid_get_volumic_mass(mdm, &rwalk->vtx);
+ cp = solid_get_calorific_capacity(mdm, &rwalk->vtx);
+
+ /* Fetch the limit time */
+ t0 = ctx->green_path ? -INF : solid_get_t0(mdm);
+
+ /* Sample the time to reroll */
+ mu = (2*DIM*lambda)/(rho*cp*delta_in_meter*delta_in_meter);
+ tau = ssp_ran_exp(rng, mu);
+
+ /* Time rewind */
+ rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0);
+
+ /* The path does not reach the limit condition */
+ if(rwalk->vtx.time > t0) goto exit;
+
+ /* Fetch initial temperature */
+ temperature = solid_get_temperature(mdm, &rwalk->vtx);
+ if(temperature < 0) {
+ log_err(mdm->dev, "%s: the path reaches the limit condition by the "
+ "temperature remains unknown.\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* Update temperature */
+ T->value += temperature;
+ T->done = 1;
+
+ if(ctx->heat_path) {
+ /* Update the registered vertex data */
+ struct sdis_heat_vertex* vtx;
+ vtx = heat_path_get_last_vertex(ctx->heat_path);
+ vtx->time = rwalk->vtx.time;
+ vtx->weight = T->value;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+#include "sdis_Xd_end.h"
diff --git a/src/sdis_realisation.h b/src/sdis_realisation.h
@@ -144,4 +144,3 @@ ray_realisation_3d
double* weight);
#endif /* SDIS_REALISATION_H */
-