commit 0afe189976e87820a4fb025e062d5ec44d73cd40
parent 283f5c19e00c813cffee60dc4940ad5684ca3474
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 13 Dec 2018 17:36:50 +0100
Allow to define a t0 value by medium
t0 is the time until the initial condition is maintained for this medium
Diffstat:
6 files changed, 128 insertions(+), 54 deletions(-)
diff --git a/src/sdis.h b/src/sdis.h
@@ -151,11 +151,15 @@ struct sdis_solid_shader {
* submitted position and time */
sdis_medium_getter_T volumic_power; /* In W.m^-3 */
- /* Initial condition. A temperature < 0 means that the temperature is
- * unknown for the submitted random walk vertex. */
+ /* Initial/limit condition. A temperature < 0 means that the temperature is
+ * unknown for the submitted random walk vertex.
+ * This getter is always called at time >= t0 (see below). */
sdis_medium_getter_T temperature;
+ /* The time until the initial condition is maintained for this solid;
+ * can neither be negative nor infinity, default is 0. */
+ double t0;
};
-#define SDIS_SOLID_SHADER_NULL__ {NULL, NULL, NULL, NULL, NULL, NULL}
+#define SDIS_SOLID_SHADER_NULL__ {NULL, NULL, NULL, NULL, NULL, NULL, 0}
static const struct sdis_solid_shader SDIS_SOLID_SHADER_NULL =
SDIS_SOLID_SHADER_NULL__;
@@ -165,11 +169,15 @@ struct sdis_fluid_shader {
sdis_medium_getter_T calorific_capacity; /* In J.K^-1.kg^-1 */
sdis_medium_getter_T volumic_mass; /* In kg.m^-3 */
- /* Initial condition. A temperature < 0 means that the temperature is
- * unknown for the submitted position and time. */
+ /* Initial/limit condition. A temperature < 0 means that the temperature is
+ * unknown for the submitted random walk vertex.
+ * This getter is always called at time >= t0 (see below). */
sdis_medium_getter_T temperature;
+ /* The time until the initial condition is maintained for this fluid;
+ * can neither be negative nor infinity, default is 0. */
+ double t0;
};
-#define SDIS_FLUID_SHADER_NULL__ {NULL, NULL, NULL}
+#define SDIS_FLUID_SHADER_NULL__ {NULL, NULL, NULL, 0}
static const struct sdis_fluid_shader SDIS_FLUID_SHADER_NULL =
SDIS_FLUID_SHADER_NULL__;
diff --git a/src/sdis_medium.c b/src/sdis_medium.c
@@ -28,7 +28,8 @@ check_fluid_shader(const struct sdis_fluid_shader* shader)
ASSERT(shader);
return shader->calorific_capacity
&& shader->volumic_mass
- && shader->temperature;
+ && shader->temperature
+ && 0 <= shader->t0 && shader->t0 < INF;
}
static int
@@ -39,7 +40,8 @@ check_solid_shader(const struct sdis_solid_shader* shader)
&& shader->thermal_conductivity
&& shader->volumic_mass
&& shader->delta_solid
- && shader->temperature;
+ && shader->temperature
+ && 0 <= shader->t0 && shader->t0 < INF;
}
static res_T
diff --git a/src/sdis_medium_c.h b/src/sdis_medium_c.h
@@ -18,6 +18,8 @@
#include "sdis.h"
+#include <rsys/math.h>
+
struct sdis_medium {
enum sdis_medium_type type;
union {
@@ -63,9 +65,19 @@ fluid_get_temperature
(const struct sdis_medium* mdm, const struct sdis_rwalk_vertex* vtx)
{
ASSERT(mdm && mdm->type == SDIS_FLUID);
+ ASSERT(vtx->time >= mdm->shader.fluid.t0);
return mdm->shader.fluid.temperature(vtx, mdm->data);
}
+static INLINE double
+ fluid_get_t0
+(const struct sdis_medium* mdm)
+{
+ ASSERT(mdm && mdm->type == SDIS_FLUID);
+ ASSERT(0 <= mdm->shader.fluid.t0 && mdm->shader.fluid.t0 < INF);
+ return mdm->shader.fluid.t0;
+}
+
/*******************************************************************************
* Solid local functions
******************************************************************************/
@@ -116,8 +128,18 @@ solid_get_temperature
(const struct sdis_medium* mdm, const struct sdis_rwalk_vertex* vtx)
{
ASSERT(mdm && mdm->type == SDIS_SOLID);
+ ASSERT(vtx->time >= mdm->shader.solid.t0);
return mdm->shader.solid.temperature(vtx, mdm->data);
}
+static INLINE double
+ solid_get_t0
+(const struct sdis_medium* mdm)
+{
+ ASSERT(mdm && mdm->type == SDIS_SOLID);
+ ASSERT(0 <= mdm->shader.solid.t0 && mdm->shader.solid.t0 < INF);
+ return mdm->shader.solid.t0;
+}
+
#endif /* SDIS_MEDIUM_C_H */
diff --git a/src/sdis_solve_Xd.h b/src/sdis_solve_Xd.h
@@ -606,12 +606,12 @@ XD(fluid_temperature)
return RES_BAD_ARG;
}
- /* The hc upper bound can be 0 is h is uniformly 0. In that case the result
+ /* The hc upper bound can be 0 if h is uniformly 0. In that case the result
* is the initial condition. */
if(enc->hc_upper_bound == 0) {
/* Cannot be in the fluid without starting there. */
ASSERT(SXD_HIT_NONE(&rwalk->hit));
- rwalk->vtx.time = 0;
+ rwalk->vtx.time = fluid_get_t0(rwalk->mdm);
tmp = fluid_get_temperature(rwalk->mdm, &rwalk->vtx);
if(tmp >= 0) {
T->value += tmp;
@@ -621,8 +621,8 @@ XD(fluid_temperature)
/* At t=0, the initial condition should have been reached. */
log_err(scn->dev,
-"%s: undefined initial condition. "
-"Time is 0 but the temperature remains unknown.\n",
+ "%s: undefined initial condition. "
+ "Time is 0 but the temperature remains unknown.\n",
FUNC_NAME);
return RES_BAD_OP;
}
@@ -655,27 +655,26 @@ XD(fluid_temperature)
/* Sample the time using the upper bound. */
if(rwalk->vtx.time != INF) {
- double mu, tau;
+ double mu, tau, t0;
mu = enc->hc_upper_bound / (rho * cp) * enc->S_over_V;
tau = ssp_ran_exp(rng, mu);
- rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, 0);
- }
-
- /* Check the initial condition. */
- tmp = fluid_get_temperature(rwalk->mdm, &rwalk->vtx);
- if(tmp >= 0) {
- T->value += tmp;
- T->done = 1;
- return RES_OK;
- }
-
- if(rwalk->vtx.time <= 0) {
- /* The initial condition should have been reached. */
- log_err(scn->dev,
-"%s: undefined initial condition. "
-"Time is 0 but the temperature remains unknown.\n",
- FUNC_NAME);
- return RES_BAD_OP;
+ t0 = fluid_get_t0(rwalk->mdm);
+ rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0);
+ if(rwalk->vtx.time == t0) {
+ /* Check the initial condition. */
+ tmp = fluid_get_temperature(rwalk->mdm, &rwalk->vtx);
+ if(tmp >= 0) {
+ T->value += tmp;
+ T->done = 1;
+ return RES_OK;
+ }
+ /* The initial condition should have been reached. */
+ log_err(scn->dev,
+ "%s: undefined initial condition. "
+ "Time is %g but the temperature remains unknown.\n",
+ FUNC_NAME, t0);
+ return RES_BAD_OP;
+ }
}
/* Uniformly sample the enclosure. */
@@ -1330,27 +1329,26 @@ XD(solid_temperature)
/* Sample the time */
if(rwalk->vtx.time != INF) {
- double tau, mu;
+ double tau, mu, t0;
mu = (2*DIM*lambda) / (rho*cp*delta*fp_to_meter*delta*fp_to_meter);
tau = ssp_ran_exp(rng, mu);
- rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, 0);
- }
-
- /* Check the initial condition */
- tmp = solid_get_temperature(mdm, &rwalk->vtx);
- if(tmp >= 0) {
- T->value += tmp;
- T->done = 1;
- return RES_OK;
- }
-
- if(rwalk->vtx.time <= 0) {
- /* The initial condition should have been reached */
- log_err(scn->dev,
- "%s: undefined initial condition. "
- "The time is null but the temperature remains unknown.\n",
- FUNC_NAME);
- return RES_BAD_OP;
+ t0 = 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;
+ return RES_OK;
+ }
+ /* The initial condition should have been reached */
+ log_err(scn->dev,
+ "%s: undefined initial condition. "
+ "The time is %f but the temperature remains unknown.\n",
+ FUNC_NAME, t0);
+ return RES_BAD_OP;
+ }
}
/* Define if the random walk hits something along dir0 */
@@ -1483,18 +1481,46 @@ XD(probe_realisation)
struct rwalk_context ctx;
struct XD(rwalk) rwalk = XD(RWALK_NULL);
struct XD(temperature) T = XD(TEMPERATURE_NULL);
+ double (*get_initial_temperature)
+ (const struct sdis_medium* mdm, const struct sdis_rwalk_vertex* vtx);
+ double t0;
res_T res = RES_OK;
ASSERT(medium && position && fp_to_meter > 0 && weight);
switch(medium->type) {
- case SDIS_FLUID: T.func = XD(fluid_temperature); break;
- case SDIS_SOLID: T.func = XD(solid_temperature); break;
+ case SDIS_FLUID:
+ T.func = XD(fluid_temperature);
+ get_initial_temperature = fluid_get_temperature;
+ t0 = fluid_get_t0(medium);
+ break;
+ case SDIS_SOLID:
+ T.func = XD(solid_temperature);
+ get_initial_temperature = solid_get_temperature;
+ t0 = solid_get_t0(medium);
+ break;
default: FATAL("Unreachable code\n"); break;
}
dX(set)(rwalk.vtx.P, position);
/* Sample a time */
rwalk.vtx.time = sample_time(time_range, rng);
+ if(t0 >= rwalk.vtx.time) {
+ double tmp;
+ /* Check the initial condition. */
+ rwalk.vtx.time = t0;
+ tmp = get_initial_temperature(medium, &rwalk.vtx);
+ if(tmp >= 0) {
+ *weight = tmp;
+ return RES_OK;
+ }
+ /* The initial condition should have been reached */
+ log_err(scn->dev,
+ "%s: undefined initial condition. "
+ "The time is %f but the temperature remains unknown.\n",
+ FUNC_NAME, t0);
+ return RES_BAD_OP;
+ }
+
rwalk.hit = SXD_HIT_NULL;
rwalk.mdm = medium;
diff --git a/src/test_sdis_medium.c b/src/test_sdis_medium.c
@@ -16,6 +16,8 @@
#include "sdis.h"
#include "test_sdis_utils.h"
+#include <rsys/math.h>
+
int
main(int argc, char** argv)
{
@@ -61,6 +63,12 @@ main(int argc, char** argv)
BA(sdis_fluid_create(dev, &fluid_shader, NULL, &fluid));
fluid_shader.temperature = DUMMY_FLUID_SHADER.temperature;
+ fluid_shader.t0 = -1;
+ BA(sdis_fluid_create(dev, &fluid_shader, NULL, &solid));
+ fluid_shader.t0 = INF;
+ BA(sdis_fluid_create(dev, &fluid_shader, NULL, &solid));
+ fluid_shader.t0 = DUMMY_FLUID_SHADER.t0;
+
BA(sdis_fluid_create(dev, &SDIS_FLUID_SHADER_NULL, NULL, &fluid));
OK(sdis_data_create(dev, 4, 16, NULL, &data));
@@ -97,6 +105,12 @@ main(int argc, char** argv)
BA(sdis_solid_create(dev, &solid_shader, NULL, &solid));
solid_shader.temperature = DUMMY_SOLID_SHADER.temperature;
+ solid_shader.t0 = -1;
+ BA(sdis_solid_create(dev, &solid_shader, NULL, &solid));
+ solid_shader.t0 = INF;
+ BA(sdis_solid_create(dev, &solid_shader, NULL, &solid));
+ solid_shader.t0 = DUMMY_SOLID_SHADER.t0;
+
OK(sdis_device_ref_put(dev));
check_memory_allocator(&allocator);
diff --git a/src/test_sdis_utils.h b/src/test_sdis_utils.h
@@ -168,13 +168,15 @@ static const struct sdis_solid_shader DUMMY_SOLID_SHADER = {
dummy_medium_getter,
dummy_medium_getter,
dummy_medium_getter,
- dummy_medium_getter
+ dummy_medium_getter,
+ 0
};
static const struct sdis_fluid_shader DUMMY_FLUID_SHADER = {
dummy_medium_getter,
dummy_medium_getter,
- dummy_medium_getter
+ dummy_medium_getter,
+ 0
};