stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

commit bec3cbe6c9a67e4691370a8a07e3c85b9d7ca194
parent 36cd445d4fc396de04505c2da1f060044839cf99
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  1 Jul 2020 16:48:44 +0200

Add and test the sdis_estimator_accum function

Diffstat:
Msrc/sdis.h | 5+++++
Msrc/sdis_estimator.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/sdis_misc.h | 10++++++++++
Msrc/test_sdis_solve_probe.c | 14++++++++++++++
Msrc/test_sdis_solve_probe2.c | 11+++++++++++
5 files changed, 108 insertions(+), 0 deletions(-)

diff --git a/src/sdis.h b/src/sdis.h @@ -936,6 +936,11 @@ sdis_estimator_get_rng_state * from an estimator buffer */ struct ssp_rng** rng_state); +SDIS_API res_T +sdis_estimator_accum + (struct sdis_estimator* dst, + const struct sdis_estimator* src); + /******************************************************************************* * The green function saves the estimation of the propagator ******************************************************************************/ diff --git a/src/sdis_estimator.c b/src/sdis_estimator.c @@ -207,6 +207,74 @@ sdis_estimator_get_rng_state return RES_OK; } +res_T +sdis_estimator_accum + (struct sdis_estimator* dst, + const struct sdis_estimator* src) +{ + res_T res = RES_OK; + struct sdis_heat_path* dst_paths = NULL; + const struct sdis_heat_path* src_paths = NULL; + size_t ndst_paths = 0; + size_t nsrc_paths = 0; + size_t i; + + if(!dst || !src) { res = RES_BAD_ARG; goto error; } + + if(dst->type != src->type) { + log_err(dst->dev, "%s: estimators are mutually incompatibles.\n", + FUNC_NAME); + res = RES_OK; + goto error; + } + + /* Begin the function by the copy of the registered paths since if an error + * occurs on dynamic array allocation, nothing has to be rewind */ + ndst_paths = darray_heat_path_size_get(&dst->paths); + nsrc_paths = darray_heat_path_size_get(&src->paths); + res = darray_heat_path_resize(&dst->paths, ndst_paths + nsrc_paths); + if(res != RES_OK) { + log_err(dst->dev, + "%s: could not allocate the list of registered paths -- %s.\n", + FUNC_NAME, res_to_cstr(res)); + goto error; + } + dst_paths = darray_heat_path_data_get(&dst->paths); + src_paths = darray_heat_path_cdata_get(&src->paths); + FOR_EACH(i, 0, nsrc_paths) { + res = heat_path_copy(&dst_paths[ndst_paths + i], &src_paths[i]); + ASSERT(res == RES_OK); + } + + switch(dst->type) { + case SDIS_ESTIMATOR_TEMPERATURE: + accum_add(&dst->temperature, &dst->temperature, &src->temperature); + break; + case SDIS_ESTIMATOR_FLUX: + FOR_EACH(i, 0, FLUX_NAMES_COUNT__) { + accum_add(&dst->fluxes[i], &dst->fluxes[i], &src->fluxes[i]); + } + break; + default: FATAL("Unreachable code.\n"); break; + } + + accum_add(&dst->realisation_time, &dst->realisation_time, &src->realisation_time); + dst->nrealisations += src->nrealisations; + dst->nfailures += src->nfailures; + + /* Relese the rng state on the `dst' estimator since nothing can be said onto + * it after the accumulation */ + if(dst->rng) { + SSP(rng_ref_put(dst->rng)); + dst->rng = NULL; + } + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ diff --git a/src/sdis_misc.h b/src/sdis_misc.h @@ -39,6 +39,16 @@ static const struct accum ACCUM_NULL = ACCUM_NULL__; #define BOLTZMANN_CONSTANT 5.6696e-8 /* W/m^2/K^4 */ +static INLINE struct accum* +accum_add(struct accum* dst, const struct accum* a, const struct accum* b) +{ + ASSERT(dst && a && b); + dst->sum = a->sum + b->sum; + dst->sum2 = a->sum2 + b->sum2; + dst->count = a->count + b->count; + return dst; +} + static INLINE void sum_accums (const struct accum accums[], diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c @@ -249,6 +249,7 @@ main(int argc, char** argv) { struct mem_allocator allocator; struct sdis_mc T = SDIS_MC_NULL; + struct sdis_mc T2 = SDIS_MC_NULL; struct sdis_mc F = SDIS_MC_NULL; struct sdis_mc time = SDIS_MC_NULL; struct sdis_device* dev = NULL; @@ -450,6 +451,18 @@ main(int argc, char** argv) OK(sdis_green_function_ref_put(green)); OK(sdis_green_function_ref_put(green)); + OK(sdis_estimator_ref_put(estimator2)); + OK(sdis_estimator_get_rng_state(estimator, &rng_state)); + solve_args.rng_state = rng_state; + OK(sdis_solve_probe(scn, &solve_args, &estimator2)); + + BA(sdis_estimator_accum(NULL, estimator2)); + BA(sdis_estimator_accum(estimator, NULL)); + OK(sdis_estimator_accum(estimator, estimator2)); + + OK(sdis_estimator_get_temperature(estimator, &T2)); + CHK(eq_eps(T2.E, ref, T2.SE)); + OK(sdis_estimator_ref_put(estimator)); OK(sdis_estimator_ref_put(estimator2)); @@ -460,6 +473,7 @@ main(int argc, char** argv) CHK(n == 0); OK(sdis_estimator_ref_put(estimator)); + solve_args.rng_state = NULL; solve_args.nrealisations = N_dump; solve_args.register_paths = SDIS_HEAT_PATH_ALL; diff --git a/src/test_sdis_solve_probe2.c b/src/test_sdis_solve_probe2.c @@ -146,6 +146,7 @@ main(int argc, char** argv) { struct mem_allocator allocator; struct sdis_mc T = SDIS_MC_NULL; + struct sdis_mc T2 = SDIS_MC_NULL; struct sdis_mc time = SDIS_MC_NULL; struct sdis_device* dev = NULL; struct sdis_data* data = NULL; @@ -269,6 +270,16 @@ main(int argc, char** argv) check_green_function(green); check_estimator_eq(estimator, estimator2); + /* Pursue the estimation */ + OK(sdis_estimator_ref_put(estimator2)); + OK(sdis_estimator_get_rng_state(estimator, &solve_args.rng_state)); + solve_args.nrealisations *= 3; + OK(sdis_solve_probe(scn, &solve_args, &estimator2)); + OK(sdis_estimator_accum(estimator, estimator2)); + OK(sdis_estimator_get_temperature(estimator, &T2)); + CHK(eq_eps(T2.E, ref, 3*T2.SE)); + CHK(eq_eps(T2.SE, T.SE*0.5, 1e-4)); + /* Release data */ OK(sdis_estimator_ref_put(estimator)); OK(sdis_estimator_ref_put(estimator2));