stardis-solver

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

commit 97b6e62c27c7a9c7d7590612a5c4bb40b2be58a4
parent bb0c8f4c24b48cd1630feffe15b8e5940c69930b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  2 Oct 2020 10:11:35 +0200

Merge branch 'release_0.10.1'

Diffstat:
MREADME.md | 12++++++++++++
Mcmake/CMakeLists.txt | 2+-
Msrc/sdis.h | 16+++++++++-------
Msrc/sdis_Xd_begin.h | 3++-
Msrc/sdis_estimator.c | 10++++++++++
Msrc/sdis_estimator_c.h | 1+
Msrc/sdis_green.c | 8++++++--
Msrc/sdis_green.h | 6++++--
Msrc/sdis_heat_path_boundary_Xd.h | 2+-
Msrc/sdis_heat_path_conductive_Xd.h | 2+-
Msrc/sdis_heat_path_convective_Xd.h | 18++++++++++++------
Msrc/sdis_heat_path_radiative_Xd.h | 3++-
Msrc/sdis_misc_Xd.h | 14++++++++------
Msrc/sdis_scene.c | 2++
Msrc/sdis_solve_boundary_Xd.h | 39+++++++++++++++++++++++++++++++--------
Msrc/sdis_solve_medium_Xd.h | 4++--
Msrc/sdis_solve_probe_Xd.h | 4++--
Msrc/sdis_solve_probe_boundary_Xd.h | 46+++++++++++++++++++++++++++++++++++++---------
Msrc/test_sdis_solve_boundary_flux.c | 26+++++++-------------------
Msrc/test_sdis_solve_probe.c | 3++-
Msrc/test_sdis_solve_probe2.c | 15++++++++-------
Msrc/test_sdis_utils.c | 3++-
Msrc/test_sdis_volumic_power4.c | 2+-
23 files changed, 163 insertions(+), 78 deletions(-)

diff --git a/README.md b/README.md @@ -25,6 +25,18 @@ variable the install directories of its dependencies. ## Release notes +### Version 0.10.1 + +- In green function estimation, the time sent to the user callbacks is no more + the elapsed time from the beginning of the realisation: as in a regular + computation, it is now the observation time. +- Fix the flux computation for boundaries with an imposed flux: it was + previously ignored. The new `sdis_estimator_get_imposed_flux` function + returns this estimated flux component. +- Return an error if the flux is computed at a boundary whose temperature is + known: this configuration is not currently supported. +- Fix build with the CL compiler. + ### Version 0.10 - Add support of green function [de]serialization. The diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -57,7 +57,7 @@ rcmake_append_runtime_dirs(_runtime_dirs ############################################################################### set(VERSION_MAJOR 0) set(VERSION_MINOR 10) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SDIS_FILES_SRC diff --git a/src/sdis.h b/src/sdis.h @@ -940,6 +940,11 @@ sdis_estimator_get_radiative_flux struct sdis_mc* flux); SDIS_API res_T +sdis_estimator_get_imposed_flux + (const struct sdis_estimator* estimator, + struct sdis_mc* flux); + +SDIS_API res_T sdis_estimator_get_total_flux (const struct sdis_estimator* estimator, struct sdis_mc* flux); @@ -1144,11 +1149,8 @@ sdis_compute_power /******************************************************************************* * Green solvers. * - * The caller should ensure that green solvers are invoked on scenes whose data - * do not depend on time. Indeed, on green estimation, the time parameter along - * the random walks registers the relative time spent in the system rather than - * an absolute time. As a consequence, the media/interfaces parameters cannot - * vary in time with respect to an absolute time value. + * Currently only steady computations are supported. As a consequence, the + * observation time is always fixed to infinity. * * In addition, the green solvers assumes that the interface fluxes are * constants in time and space. In the same way the volumic power of the solid @@ -1159,8 +1161,8 @@ sdis_compute_power * definitely registered against the green function as interfaces/media with no * flux/volumic power. * - * If the aforementioned assumptions are not ensured by the caller, the - * behavior of the estimated green function is undefined. + * If these assumptions are not ensured by the caller, the behavior of the + * estimated green function is undefined. ******************************************************************************/ SDIS_API res_T sdis_solve_probe_green_function diff --git a/src/sdis_Xd_begin.h b/src/sdis_Xd_begin.h @@ -95,10 +95,11 @@ struct XD(rwalk) { struct sdis_rwalk_vertex vtx; /* Position and time of the Random walk */ struct sdis_medium* mdm; /* Medium in which the random walk lies */ struct sXd(hit) hit; /* Hit of the random walk */ + double elapsed_time; enum sdis_side hit_side; }; static const struct XD(rwalk) XD(RWALK_NULL) = { - SDIS_RWALK_VERTEX_NULL__, NULL, SXD_HIT_NULL__, SDIS_SIDE_NULL__ + SDIS_RWALK_VERTEX_NULL__, NULL, SXD_HIT_NULL__, 0, SDIS_SIDE_NULL__ }; struct XD(temperature) { diff --git a/src/sdis_estimator.c b/src/sdis_estimator.c @@ -136,6 +136,16 @@ sdis_estimator_get_radiative_flux } res_T +sdis_estimator_get_imposed_flux + (const struct sdis_estimator* estimator, struct sdis_mc* flux) +{ + if(!estimator || !flux || estimator->type != SDIS_ESTIMATOR_FLUX) + return RES_BAD_ARG; + SETUP_MC(flux, &estimator->fluxes[FLUX_IMPOSED]); + return RES_OK; +} + +res_T sdis_estimator_get_total_flux (const struct sdis_estimator* estimator, struct sdis_mc* flux) { diff --git a/src/sdis_estimator_c.h b/src/sdis_estimator_c.h @@ -31,6 +31,7 @@ enum sdis_estimator_type; enum flux_name { FLUX_CONVECTIVE, FLUX_RADIATIVE, + FLUX_IMPOSED, FLUX_TOTAL, FLUX_NAMES_COUNT__ }; diff --git a/src/sdis_green.c b/src/sdis_green.c @@ -1462,7 +1462,8 @@ res_T green_path_set_limit_interface_fragment (struct green_path_handle* handle, struct sdis_interface* interf, - const struct sdis_interface_fragment* frag) + const struct sdis_interface_fragment* frag, + const double elapsed_time) { res_T res = RES_OK; ASSERT(handle && interf && frag); @@ -1470,6 +1471,7 @@ green_path_set_limit_interface_fragment res = ensure_interface_registration(handle->green, interf); if(res != RES_OK) return res; handle->path->limit.fragment = *frag; + handle->path->limit.fragment.time = -elapsed_time; handle->path->limit_id = interface_get_id(interf); handle->path->limit_type = SDIS_FRAGMENT; return RES_OK; @@ -1479,7 +1481,8 @@ res_T green_path_set_limit_vertex (struct green_path_handle* handle, struct sdis_medium* mdm, - const struct sdis_rwalk_vertex* vert) + const struct sdis_rwalk_vertex* vert, + const double elapsed_time) { res_T res = RES_OK; ASSERT(handle && mdm && vert); @@ -1487,6 +1490,7 @@ green_path_set_limit_vertex res = ensure_medium_registration(handle->green, mdm); if(res != RES_OK) return res; handle->path->limit.vertex = *vert; + handle->path->limit.vertex.time = -elapsed_time; handle->path->limit_id = medium_get_id(mdm); handle->path->limit_type = SDIS_VERTEX; return RES_OK; diff --git a/src/sdis_green.h b/src/sdis_green.h @@ -71,13 +71,15 @@ extern LOCAL_SYM res_T green_path_set_limit_interface_fragment (struct green_path_handle* path, struct sdis_interface* interf, - const struct sdis_interface_fragment* fragment); + const struct sdis_interface_fragment* fragment, + const double elapsed_time); extern LOCAL_SYM res_T green_path_set_limit_vertex (struct green_path_handle* path, struct sdis_medium* mdm, - const struct sdis_rwalk_vertex* vertex); + const struct sdis_rwalk_vertex* vertex, + const double elapsed_time); extern LOCAL_SYM res_T green_path_add_power_term diff --git a/src/sdis_heat_path_boundary_Xd.h b/src/sdis_heat_path_boundary_Xd.h @@ -977,7 +977,7 @@ XD(boundary_path) if(ctx->green_path) { res = green_path_set_limit_interface_fragment - (ctx->green_path, interf, &frag); + (ctx->green_path, interf, &frag, rwalk->elapsed_time); if(res != RES_OK) goto error; } if(ctx->heat_path) { diff --git a/src/sdis_heat_path_conductive_Xd.h b/src/sdis_heat_path_conductive_Xd.h @@ -251,7 +251,7 @@ XD(conductive_path) if(ctx->green_path) { res = green_path_set_limit_vertex - (ctx->green_path, rwalk->mdm, &rwalk->vtx); + (ctx->green_path, rwalk->mdm, &rwalk->vtx, rwalk->elapsed_time); if(res != RES_OK) goto error; } diff --git a/src/sdis_heat_path_convective_Xd.h b/src/sdis_heat_path_convective_Xd.h @@ -103,7 +103,8 @@ XD(convective_path) T->done = 1; if(ctx->green_path) { - res = green_path_set_limit_vertex(ctx->green_path, rwalk->mdm, &rwalk->vtx); + res = green_path_set_limit_vertex + (ctx->green_path, rwalk->mdm, &rwalk->vtx, rwalk->elapsed_time); if(res != RES_OK) goto error; } @@ -201,18 +202,23 @@ XD(convective_path) for(;;) { struct sdis_interface_fragment frag; struct sXd(primitive) prim; + double mu, tau, t0; /* Fetch other physical properties. */ cp = fluid_get_calorific_capacity(rwalk->mdm, &rwalk->vtx); rho = fluid_get_volumic_mass(rwalk->mdm, &rwalk->vtx); + t0 = fluid_get_t0(rwalk->mdm); /* Limit time */ /* Sample the time using the upper bound. */ + mu = enc->hc_upper_bound / (rho * cp) * enc->S_over_V; + tau = ssp_ran_exp(rng, mu); + + /* Increment the elapsed time */ + ASSERT(rwalk->vtx.time > t0); + rwalk->elapsed_time += MMIN(tau, rwalk->vtx.time - t0); + if(rwalk->vtx.time != INF) { - double mu, tau, t0; - mu = enc->hc_upper_bound / (rho * cp) * enc->S_over_V; - tau = ssp_ran_exp(rng, mu); - t0 = ctx->green_path ? -INF : fluid_get_t0(rwalk->mdm); - rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0); + rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0); /* Time rewind */ /* Register the new vertex against the heat path */ res = XD(register_heat_vertex_in_fluid)(scn, ctx, rwalk, T->value); diff --git a/src/sdis_heat_path_radiative_Xd.h b/src/sdis_heat_path_radiative_Xd.h @@ -84,7 +84,8 @@ XD(trace_radiative_path) struct sdis_rwalk_vertex vtx; d3_splat(vtx.P, INF); vtx.time = rwalk->vtx.time; - res = green_path_set_limit_vertex(ctx->green_path, rwalk->mdm, &vtx); + res = green_path_set_limit_vertex + (ctx->green_path, rwalk->mdm, &vtx, rwalk->elapsed_time); if(res != RES_OK) goto error; } if(ctx->heat_path) { diff --git a/src/sdis_misc_Xd.h b/src/sdis_misc_Xd.h @@ -41,20 +41,22 @@ XD(time_rewind) ASSERT(sdis_medium_get_type(mdm) == SDIS_SOLID); ASSERT(T->done == 0); - if(IS_INF(rwalk->vtx.time)) goto exit; - - /* Fetch phyisical properties */ + /* Fetch physical 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); + t0 = solid_get_t0(mdm); /* Limit time */ /* Sample the time to reroll */ mu = (2*DIM*lambda)/(rho*cp*delta_in_meter*delta_in_meter); tau = ssp_ran_exp(rng, mu); + /* Increment the elapsed time */ + ASSERT(rwalk->vtx.time > t0); + rwalk->elapsed_time += MMIN(tau, rwalk->vtx.time - t0); + + if(IS_INF(rwalk->vtx.time)) goto exit; /* Steady computation */ + /* Time rewind */ rwalk->vtx.time = MMAX(rwalk->vtx.time - tau, t0); diff --git a/src/sdis_scene.c b/src/sdis_scene.c @@ -31,7 +31,9 @@ #include <float.h> #include <limits.h> +#ifdef COMPILER_GCC #include <sys/mman.h> +#endif /******************************************************************************* * Helper function diff --git a/src/sdis_solve_boundary_Xd.h b/src/sdis_solve_boundary_Xd.h @@ -264,8 +264,8 @@ XD(solve_boundary) } } else { /* Do not take care of the submitted time when registering the green - * function. Simply takes 0 as relative time */ - time = 0; + * function. Only steady systems are supported yet */ + time = INF; res_local = green_function_create_path(greens[ithread], &green_path); if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); @@ -446,6 +446,7 @@ XD(solve_boundary_flux) struct accum* acc_fl = NULL; /* Per thread flux accumulator */ struct accum* acc_fc = NULL; /* Per thread convective flux accumulator */ struct accum* acc_fr = NULL; /* Per thread radiative flux accumulator */ + struct accum* acc_fi = NULL; /* Per thread imposed flux accumulator */ size_t nrealisations = 0; int64_t irealisation; size_t i; @@ -552,6 +553,7 @@ XD(solve_boundary_flux) ALLOC_ACCUMS(acc_fc); ALLOC_ACCUMS(acc_fl); ALLOC_ACCUMS(acc_fr); + ALLOC_ACCUMS(acc_fi); #undef ALLOC_ACCUMS /* Create the estimator */ @@ -570,6 +572,7 @@ XD(solve_boundary_flux) struct accum* acc_flux = &acc_fl[ithread]; struct accum* acc_fcon = &acc_fc[ithread]; struct accum* acc_frad = &acc_fr[ithread]; + struct accum* acc_fimp = &acc_fi[ithread]; struct sXd(primitive) prim; struct sdis_interface_fragment frag = SDIS_INTERFACE_FRAGMENT_NULL; const struct sdis_interface* interf; @@ -578,7 +581,7 @@ XD(solve_boundary_flux) double T_brf[3] = { 0, 0, 0 }; const double Tref = args->reference_temperature; const double Tarad = args->ambient_radiative_temperature; - double epsilon, hc, hr; + double epsilon, hc, hr, imposed_flux, imposed_temp; size_t iprim; double uv[DIM - 1]; float st[DIM - 1]; @@ -624,8 +627,11 @@ XD(solve_boundary_flux) bmd = interface_get_medium(interf, SDIS_BACK); if(!fmd || !bmd || ( !(fmd->type == SDIS_FLUID && bmd->type == SDIS_SOLID) - && !(fmd->type == SDIS_SOLID && bmd->type == SDIS_FLUID))) - { + && !(fmd->type == SDIS_SOLID && bmd->type == SDIS_FLUID))) { + log_err(scn->dev, "%s: Attempt to compute a flux at a %s-%s interface.\n", + FUNC_NAME, + (fmd->type == SDIS_FLUID ? "fluid" : "solid"), + (bmd->type == SDIS_FLUID ? "fluid" : "solid")); ATOMIC_SET(&res, RES_BAD_ARG); continue; } @@ -640,14 +646,22 @@ XD(solve_boundary_flux) /* Fetch interface parameters */ epsilon = interface_side_get_emissivity(interf, &frag); hc = interface_get_convection_coef(interf, &frag); - hr = 4.0 * BOLTZMANN_CONSTANT * Tref * Tref * Tref * epsilon; + frag.side = solid_side; + imposed_flux = interface_side_get_flux(interf, &frag); + imposed_temp = interface_side_get_temperature(interf, &frag); + if(imposed_temp >= 0) { + /* Flux computation on T boundaries is not supported yet */ + log_err(scn->dev, "%s: Attempt to compute a flux at a Dirichlet boundary " + "(not available yet).\n", FUNC_NAME); + ATOMIC_SET(&res, RES_BAD_ARG); + continue; + } /* Fluid, Radiative and Solid temperatures */ flux_mask = 0; if(hr > 0) flux_mask |= FLUX_FLAG_RADIATIVE; if(hc > 0) flux_mask |= FLUX_FLAG_CONVECTIVE; - res_simul = XD(boundary_flux_realisation)(scn, rng, iprim, uv, time, solid_side, args->fp_to_meter, Tarad, Tref, flux_mask, T_brf); @@ -664,7 +678,8 @@ XD(solve_boundary_flux) const double Tfluid = T_brf[2]; const double w_conv = hc * (Tboundary - Tfluid); const double w_rad = hr * (Tboundary - Tradiative); - const double w_total = w_conv + w_rad; + const double w_imp = (imposed_flux != SDIS_FLUX_NONE) ? imposed_flux : 0; + const double w_total = w_conv + w_rad + w_imp; /* Temperature */ acc_temp->sum += Tboundary; acc_temp->sum2 += Tboundary*Tboundary; @@ -685,6 +700,10 @@ XD(solve_boundary_flux) acc_frad->sum += w_rad; acc_frad->sum2 += w_rad*w_rad; ++acc_frad->count; + /* Imposed flux */ + acc_fimp->sum += w_imp; + acc_fimp->sum2 += w_imp*w_imp; + ++acc_fimp->count; } /* Update progress */ @@ -707,10 +726,12 @@ XD(solve_boundary_flux) sum_accums(acc_fc, scn->dev->nthreads, &acc_fc[0]); sum_accums(acc_fr, scn->dev->nthreads, &acc_fr[0]); sum_accums(acc_fl, scn->dev->nthreads, &acc_fl[0]); + sum_accums(acc_fi, scn->dev->nthreads, &acc_fi[0]); ASSERT(acc_tp[0].count == acc_fl[0].count); ASSERT(acc_tp[0].count == acc_ti[0].count); ASSERT(acc_tp[0].count == acc_fr[0].count); ASSERT(acc_tp[0].count == acc_fc[0].count); + ASSERT(acc_tp[0].count == acc_fi[0].count); /* Setup the estimated values */ estimator_setup_realisations_count(estimator, nrealisations, acc_tp[0].count); @@ -718,6 +739,7 @@ XD(solve_boundary_flux) estimator_setup_realisation_time(estimator, acc_ti[0].sum, acc_ti[0].sum2); estimator_setup_flux(estimator, FLUX_CONVECTIVE, acc_fc[0].sum, acc_fc[0].sum2); estimator_setup_flux(estimator, FLUX_RADIATIVE, acc_fr[0].sum, acc_fr[0].sum2); + estimator_setup_flux(estimator, FLUX_IMPOSED, acc_fi[0].sum, acc_fi[0].sum2); estimator_setup_flux(estimator, FLUX_TOTAL, acc_fl[0].sum, acc_fl[0].sum2); res = estimator_save_rng_state(estimator, rng_proxy); @@ -733,6 +755,7 @@ exit: if(acc_fc) MEM_RM(scn->dev->allocator, acc_fc); if(acc_fr) MEM_RM(scn->dev->allocator, acc_fr); if(acc_fl) MEM_RM(scn->dev->allocator, acc_fl); + if(acc_fi) MEM_RM(scn->dev->allocator, acc_fi); if(scene) SXD(scene_ref_put(scene)); if(shape) SXD(shape_ref_put(shape)); if(view) SXD(scene_view_ref_put(view)); diff --git a/src/sdis_solve_medium_Xd.h b/src/sdis_solve_medium_Xd.h @@ -333,8 +333,8 @@ XD(solve_medium) } } else { /* Do not take care of the submitted time when registering the green - * function. Simply takes 0 as relative time */ - time = 0; + * function. Only steady systems are supported yet */ + time = INF; res_local = green_function_create_path(greens[ithread], &green_path); if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); diff --git a/src/sdis_solve_probe_Xd.h b/src/sdis_solve_probe_Xd.h @@ -161,8 +161,8 @@ XD(solve_probe) } } else { /* Do not take care of the submitted time when registering the green - * function. Simply takes 0 as relative time */ - time = 0; + * function. Only steady systems are supported */ + time = INF; res_local = green_function_create_path(greens[ithread], &green_path); if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); diff --git a/src/sdis_solve_probe_boundary_Xd.h b/src/sdis_solve_probe_boundary_Xd.h @@ -196,8 +196,8 @@ XD(solve_probe_boundary) } } else { /* Do not take care of the submitted time when registering the green - * function. Simply takes 0 as relative time */ - time = 0; + * function. Only steady systems are supported */ + time = INF; res_local = green_function_create_path(greens[ithread], &green_path); if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); @@ -346,6 +346,7 @@ XD(solve_probe_boundary_flux) struct accum* acc_fl = NULL; /* Per thread flux accumulator */ struct accum* acc_fc = NULL; /* Per thread convective flux accumulator */ struct accum* acc_fr = NULL; /* Per thread radiative flux accumulator */ + struct accum* acc_fi = NULL; /* Per thread imposed flux accumulator */ size_t nrealisations = 0; int64_t irealisation = 0; size_t i; @@ -393,9 +394,9 @@ XD(solve_probe_boundary_flux) } } else { const double w = CLAMP(1 - args->uv[0] - args->uv[1], 0, 1); - if(args->uv[0] < 0 - || args->uv[1] < 0 - || args->uv[0] > 1 + if(args->uv[0] < 0 + || args->uv[1] < 0 + || args->uv[0] > 1 || args->uv[1] > 1 || !eq_eps(w + args->uv[0] + args->uv[1], 1, 1.e-6)) { log_err(scn->dev, @@ -413,6 +414,11 @@ XD(solve_probe_boundary_flux) if(!fmd || !bmd || ( !(fmd->type == SDIS_FLUID && bmd->type == SDIS_SOLID) && !(fmd->type == SDIS_SOLID && bmd->type == SDIS_FLUID))) { + log_err(scn->dev, + "%s: Attempt to compute a flux at a %s-%s interface.\n", + FUNC_NAME, + (fmd->type == SDIS_FLUID ? "fluid" : "solid"), + (bmd->type == SDIS_FLUID ? "fluid" : "solid")); res = RES_BAD_ARG; goto error; } @@ -449,6 +455,7 @@ XD(solve_probe_boundary_flux) ALLOC_ACCUMS(acc_fc); ALLOC_ACCUMS(acc_fl); ALLOC_ACCUMS(acc_fr); + ALLOC_ACCUMS(acc_fi); #undef ALLOC_ACCUMS /* Prebuild the interface fragment */ @@ -473,7 +480,8 @@ XD(solve_probe_boundary_flux) struct accum* acc_flux = &acc_fl[ithread]; struct accum* acc_fcon = &acc_fc[ithread]; struct accum* acc_frad = &acc_fr[ithread]; - double time, epsilon, hc, hr; + struct accum* acc_fimp = &acc_fi[ithread]; + double time, epsilon, hc, hr, imposed_flux, imposed_temp; int flux_mask = 0; double T_brf[3] = { 0, 0, 0 }; const double Tref = args->reference_temperature; @@ -491,16 +499,27 @@ XD(solve_probe_boundary_flux) /* Compute hr and hc */ frag.time = time; + frag.side = fluid_side; epsilon = interface_side_get_emissivity(interf, &frag); hc = interface_get_convection_coef(interf, &frag); hr = 4.0 * BOLTZMANN_CONSTANT * Tref * Tref * Tref * epsilon; + frag.side = solid_side; + imposed_flux = interface_side_get_flux(interf, &frag); + imposed_temp = interface_side_get_temperature(interf, &frag); + if(imposed_temp >= 0) { + /* Flux computation on T boundaries is not supported yet */ + log_err(scn->dev,"%s: Attempt to compute a flux at a Dirichlet boundary " + "(not available yet).\n", FUNC_NAME); + ATOMIC_SET(&res, RES_BAD_ARG); + continue; + } /* Fluid, Radiative and Solid temperatures */ flux_mask = 0; if(hr > 0) flux_mask |= FLUX_FLAG_RADIATIVE; if(hc > 0) flux_mask |= FLUX_FLAG_CONVECTIVE; - res_simul = XD(boundary_flux_realisation)(scn, rng, args->iprim, args->uv, time, - solid_side, args->fp_to_meter, Tarad, Tref, flux_mask, T_brf); + res_simul = XD(boundary_flux_realisation)(scn, rng, args->iprim, args->uv, + time, solid_side, args->fp_to_meter, Tarad, Tref, flux_mask, T_brf); /* Stop time registration */ time_sub(&t0, time_current(&t1), &t0); @@ -515,7 +534,8 @@ XD(solve_probe_boundary_flux) const double Tfluid = T_brf[2]; const double w_conv = hc * (Tboundary - Tfluid); const double w_rad = hr * (Tboundary - Tradiative); - const double w_total = w_conv + w_rad; + const double w_imp = (imposed_flux != SDIS_FLUX_NONE) ? imposed_flux : 0; + const double w_total = w_conv + w_rad + w_imp; /* Temperature */ acc_temp->sum += Tboundary; acc_temp->sum2 += Tboundary*Tboundary; @@ -536,6 +556,10 @@ XD(solve_probe_boundary_flux) acc_frad->sum += w_rad; acc_frad->sum2 += w_rad*w_rad; ++acc_frad->count; + /* Imposed flux */ + acc_fimp->sum += w_imp; + acc_fimp->sum2 += w_imp*w_imp; + ++acc_fimp->count; } /* Update progress */ @@ -558,10 +582,12 @@ XD(solve_probe_boundary_flux) sum_accums(acc_fc, scn->dev->nthreads, &acc_fc[0]); sum_accums(acc_fr, scn->dev->nthreads, &acc_fr[0]); sum_accums(acc_fl, scn->dev->nthreads, &acc_fl[0]); + sum_accums(acc_fi, scn->dev->nthreads, &acc_fi[0]); ASSERT(acc_tp[0].count == acc_fl[0].count); ASSERT(acc_tp[0].count == acc_ti[0].count); ASSERT(acc_tp[0].count == acc_fr[0].count); ASSERT(acc_tp[0].count == acc_fc[0].count); + ASSERT(acc_tp[0].count == acc_fi[0].count); /* Setup the estimated values */ estimator_setup_realisations_count(estimator, nrealisations, acc_tp[0].count); @@ -569,6 +595,7 @@ XD(solve_probe_boundary_flux) estimator_setup_realisation_time(estimator, acc_ti[0].sum, acc_ti[0].sum2); estimator_setup_flux(estimator, FLUX_CONVECTIVE, acc_fc[0].sum, acc_fc[0].sum2); estimator_setup_flux(estimator, FLUX_RADIATIVE, acc_fr[0].sum, acc_fr[0].sum2); + estimator_setup_flux(estimator, FLUX_IMPOSED, acc_fi[0].sum, acc_fi[0].sum2); estimator_setup_flux(estimator, FLUX_TOTAL, acc_fl[0].sum, acc_fl[0].sum2); res = estimator_save_rng_state(estimator, rng_proxy); @@ -584,6 +611,7 @@ exit: if(acc_fc) MEM_RM(scn->dev->allocator, acc_fc); if(acc_fr) MEM_RM(scn->dev->allocator, acc_fr); if(acc_fl) MEM_RM(scn->dev->allocator, acc_fl); + if(acc_fi) MEM_RM(scn->dev->allocator, acc_fi); if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy)); if(out_estimator) *out_estimator = estimator; return (res_T)res; diff --git a/src/test_sdis_solve_boundary_flux.c b/src/test_sdis_solve_boundary_flux.c @@ -62,7 +62,7 @@ */ #define UNKNOWN_TEMPERATURE -1 -#define N 10000 /* #realisations */ +#define N 100000 /* #realisations */ #define Tf 300.0 #define Tb 0.0 @@ -447,29 +447,17 @@ main(int argc, char** argv) printf("Average values of the right side of the square = "); check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); OK(sdis_estimator_ref_put(estimator)); - - /* Average temperature on the left side of the box */ + + /* Flux computation on Dirichlet boundaries is not available yet. + * Once available, the expected total flux is the same we expect on the right + * side (as the other sides are adiabatic). */ prims[0] = 2; prims[1] = 3; - - analyticT = Tb; - analyticCF = H * (analyticT - Tf); - analyticRF = Hrad * (analyticT - Trad); - analyticTF = analyticCF + analyticRF; - bound_args.nprimitives = 2; - OK(SOLVE(box_scn, &bound_args, &estimator)); - printf("Average values of the left side of the box = "); - check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); - OK(sdis_estimator_ref_put(estimator)); - - /* Average temperature on the left/right side of the square */ + BA(SOLVE(box_scn, &bound_args, &estimator)); prims[0] = 1; bound_args.nprimitives = 1; - OK(SOLVE(square_scn, &bound_args, &estimator)); - printf("Average values of the left side of the square = "); - check_estimator(estimator, N, analyticT, analyticCF, analyticRF, analyticTF); - OK(sdis_estimator_ref_put(estimator)); + BA(SOLVE(square_scn, &bound_args, &estimator)); #undef SOLVE OK(sdis_scene_ref_put(box_scn)); diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c @@ -472,7 +472,8 @@ main(int argc, char** argv) check_green_function(green); check_estimator_eq(estimator, estimator2); - CHK(stream = tmpfile()); + stream = tmpfile(); + CHK(stream); BA(sdis_green_function_write(NULL, stream)); BA(sdis_green_function_write(green, NULL)); OK(sdis_green_function_write(green, stream)); diff --git a/src/test_sdis_solve_probe2.c b/src/test_sdis_solve_probe2.c @@ -74,7 +74,7 @@ static double temperature_unknown(const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) { (void)data; - CHK(vtx != NULL); + CHK(vtx != NULL && IS_INF(vtx->time)); return -1; } @@ -83,7 +83,8 @@ solid_get_calorific_capacity (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) { (void)data; - CHK(vtx != NULL && data == NULL); + CHK(vtx != NULL && IS_INF(vtx->time) && data == NULL); + CHK(IS_INF(vtx->time)); return 2.0; } @@ -92,7 +93,7 @@ solid_get_thermal_conductivity (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) { (void)data; - CHK(vtx != NULL); + CHK(vtx != NULL && IS_INF(vtx->time)); return 50.0; } @@ -101,7 +102,7 @@ solid_get_volumic_mass (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) { (void)data; - CHK(vtx != NULL); + CHK(vtx != NULL && IS_INF(vtx->time)); return 25.0; } @@ -110,7 +111,7 @@ solid_get_delta (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) { (void)data; - CHK(vtx != NULL); + CHK(vtx != NULL && IS_INF(vtx->time)); return 1.0/20.0; } @@ -125,7 +126,7 @@ static double null_interface_value (const struct sdis_interface_fragment* frag, struct sdis_data* data) { - CHK(frag != NULL); + CHK(frag != NULL && IS_INF(frag->time)); (void)data; return 0; } @@ -134,7 +135,7 @@ static double interface_get_temperature (const struct sdis_interface_fragment* frag, struct sdis_data* data) { - CHK(data != NULL && frag != NULL); + CHK(data != NULL && frag != NULL && IS_INF(frag->time)); return ((const struct interf*)sdis_data_cget(data))->temperature; } diff --git a/src/test_sdis_utils.c b/src/test_sdis_utils.c @@ -376,7 +376,8 @@ check_green_serialization struct sdis_green_function* green2 = NULL; CHK(green && time_range); - CHK(stream = tmpfile()); + stream = tmpfile(); + CHK(stream); OK(sdis_green_function_write(green, stream)); diff --git a/src/test_sdis_volumic_power4.c b/src/test_sdis_volumic_power4.c @@ -22,7 +22,7 @@ #define Power 10000.0 #define H 50.0 #define LAMBDA 100.0 -#define DELTA 0.4/*(1.0/2.0)*/ +#define DELTA 0.2/*(1.0/2.0)*/ #define N 100000 #define LENGTH 10000.0