stardis-solver

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

commit 0b10594c55e221bb8cdd18e4eec51512f4869bc9
parent dfe2ae42870c4b1023a78f8ff0814e7f128826e4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 21 Dec 2017 16:00:52 +0100

Test the sdis_solve_probe function

Diffstat:
Mcmake/CMakeLists.txt | 1+
Msrc/sdis.h | 6++++--
Msrc/sdis_estimator.c | 1+
Msrc/sdis_scene.c | 3++-
Msrc/sdis_solve_probe.c | 25++++++++++++++++---------
Asrc/test_sdis_solve_probe.c | 271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 295 insertions(+), 12 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -113,6 +113,7 @@ if(NOT NO_TEST) new_test(test_sdis_interface) new_test(test_sdis_medium) new_test(test_sdis_scene) + new_test(test_sdis_solve_probe) endif() ################################################################################ diff --git a/src/sdis.h b/src/sdis.h @@ -96,13 +96,15 @@ struct sdis_mc { double V; /* Variance */ double SE; /* Standard error */ }; +#define SDIS_MC_NULL__ {0, 0, 0} +static const struct sdis_mc SDIS_MC_NULL = SDIS_MC_NULL__; /* Functor type to retrieve the medium properties. */ typedef double (*sdis_medium_getter_T) (const struct sdis_rwalk_vertex* vert, struct sdis_data* data); - + /* Functor type to retrieve the interface properties. */ typedef double @@ -304,7 +306,7 @@ sdis_estimator_get_temperature * Miscellaneous functions ******************************************************************************/ SDIS_API res_T -sdis_solve_probe_temperature +sdis_solve_probe (struct sdis_scene* scn, const size_t nrealisations, const double position[3], diff --git a/src/sdis_estimator.c b/src/sdis_estimator.c @@ -102,6 +102,7 @@ estimator_create(struct sdis_device* dev, struct sdis_estimator** out_estimator) estimator->dev = dev; exit: + if(out_estimator) *out_estimator = estimator; return res; error: if(estimator) { diff --git a/src/sdis_scene.c b/src/sdis_scene.c @@ -152,7 +152,8 @@ setup_geometry res = s3d_mesh_setup_indexed_vertices(s3d_msh, (unsigned)ntris, get_indices, (unsigned)nverts, &vdata, 1, &context); if(res != RES_OK) goto error; - res = s3d_scene_view_create(s3d_scn, S3D_SAMPLE|S3D_TRACE, &scn->s3d_view); + res = s3d_scene_view_create(s3d_scn, S3D_SAMPLE|S3D_TRACE|S3D_GET_PRIMITIVE, + &scn->s3d_view); if(res != RES_OK) goto error; exit: diff --git a/src/sdis_solve_probe.c b/src/sdis_solve_probe.c @@ -50,8 +50,9 @@ struct temperature { struct ssp_rng* rng, struct temperature* temp); double value; /* Current value of the temperature */ + int done; }; -static const struct temperature TEMPERATURE_NULL = { NULL, -1 }; +static const struct temperature TEMPERATURE_NULL = { NULL, 0, 0 }; static res_T boundary_temperature @@ -103,9 +104,10 @@ check_rwalk_fragment_consistency d2_set_f2(uv, rwalk->hit.uv); return !S3D_HIT_NONE(&rwalk->hit) && d3_eq_eps(rwalk->vtx.P, frag->P, 1.e-6) - && eq_eps(rwalk->vtx.time, frag->time, 1.e-6) && d3_eq_eps(N, frag->Ng, 1.e-6) - && d2_eq_eps(uv, frag->uv, 1.e-6); + && d2_eq_eps(uv, frag->uv, 1.e-6) + && ( (IS_INF(rwalk->vtx.time) && IS_INF(frag->time)) + || eq_eps(rwalk->vtx.time, frag->time, 1.e-6)); } res_T @@ -128,6 +130,7 @@ fluid_temperature return RES_BAD_OP; } T->value += tmp; + T->done = 1; return RES_OK; } @@ -292,6 +295,7 @@ boundary_temperature tmp = interface_get_temperature(interface, &frag); if(tmp >= 0) { T->value += tmp; + T->done = 1; return RES_OK; } @@ -346,6 +350,7 @@ solid_temperature tmp = solid_get_temperature(mdm, &rwalk->vtx); if(tmp >= 0) { T->value += tmp; + T->done = 1; return RES_OK; } @@ -384,6 +389,7 @@ solid_temperature tmp = solid_get_temperature(mdm, &rwalk->vtx); if(tmp >= 0) { T->value += tmp; + T->done = 1; return RES_OK; } @@ -433,13 +439,13 @@ compute_temperature res_T res = RES_OK; ASSERT(scn && fp_to_meter && rwalk && rng && T); - while(T->value) { /* Unknown temperature */ + do { res = T->func(scn, fp_to_meter, rwalk, rng, T); if(res != RES_OK) goto error; sa_push(stack, *T); ++istack; - } + } while(!T->done); exit: sa_release(stack); @@ -452,7 +458,7 @@ error: * Exported functions ******************************************************************************/ res_T -sdis_solve_probe_temperature +sdis_solve_probe (struct sdis_scene* scn, const size_t nrealisations, const double position[3], @@ -468,7 +474,8 @@ sdis_solve_probe_temperature size_t irealisation = 0; res_T res = RES_OK; - if(!scn || !position || time < 0 || fp_to_meter < 0 || !out_estimator) { + if(!scn || !nrealisations || !position || time < 0 || fp_to_meter <= 0 + || !out_estimator) { res = RES_BAD_ARG; goto error; } @@ -486,8 +493,8 @@ sdis_solve_probe_temperature struct temperature T = TEMPERATURE_NULL; switch(medium->type) { - case SDIS_MEDIUM_FLUID: T.func = solid_temperature; break; - case SDIS_MEDIUM_SOLID: T.func = fluid_temperature; break; + case SDIS_MEDIUM_FLUID: T.func = fluid_temperature; break; + case SDIS_MEDIUM_SOLID: T.func = solid_temperature; break; default: FATAL("Unreachable code\n"); break; } diff --git a/src/test_sdis_solve_probe.c b/src/test_sdis_solve_probe.c @@ -0,0 +1,271 @@ +/* Copyright (C) |Meso|Star> 2016-2017 (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 "test_sdis_utils.h" + +#include <rsys/math.h> + +/******************************************************************************* + * Geometry + ******************************************************************************/ +struct context { + const double* positions; + const size_t* indices; + struct sdis_interface* interface; +}; + +static void +get_indices(const size_t itri, size_t ids[3], void* context) +{ + struct context* ctx = context; + ids[0] = ctx->indices[itri*3+0]; + ids[1] = ctx->indices[itri*3+1]; + ids[2] = ctx->indices[itri*3+2]; +} + +static void +get_position(const size_t ivert, double pos[3], void* context) +{ + struct context* ctx = context; + pos[0] = ctx->positions[ivert*3+0]; + pos[1] = ctx->positions[ivert*3+1]; + pos[2] = ctx->positions[ivert*3+2]; +} + +static void +get_interface(const size_t itri, struct sdis_interface** bound, void* context) +{ + struct context* ctx = context; + (void)itri; + *bound = ctx->interface; +} + +/******************************************************************************* + * Fluid medium + ******************************************************************************/ +struct fluid { + double temperature; +}; + +static double +fluid_get_temperature + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(data != NULL && vtx != NULL); + return ((const struct fluid*)sdis_data_cget(data))->temperature; +} + +/******************************************************************************* + * Solid medium + ******************************************************************************/ +struct solid { + double cp; + double lambda; + double rho; + double delta; + double temperature; +}; + +static double +solid_get_calorific_capacity + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(data != NULL && vtx != NULL); + return ((const struct solid*)sdis_data_cget(data))->cp; +} + +static double +solid_get_thermal_conductivity + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(data != NULL && vtx != NULL); + return ((const struct solid*)sdis_data_cget(data))->lambda; +} + +static double +solid_get_volumic_mass + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(data != NULL && vtx != NULL); + return ((const struct solid*)sdis_data_cget(data))->rho; +} + +static double +solid_get_delta + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(data != NULL && vtx != NULL); + return ((const struct solid*)sdis_data_cget(data))->delta; +} + +static double +solid_get_delta_boundary + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(data != NULL && vtx != NULL); + return ((const struct solid*)sdis_data_cget(data))->delta * 2.1; +} + +static double +solid_get_temperature + (const struct sdis_rwalk_vertex* vtx, struct sdis_data* data) +{ + CHK(data != NULL && vtx != NULL); + return ((const struct solid*)sdis_data_cget(data))->temperature; +} + +/******************************************************************************* + * Interface + ******************************************************************************/ +struct interface { + double hc; +}; + +static double +interface_get_convection_coef + (const struct sdis_interface_fragment* frag, struct sdis_data* data) +{ + CHK(data != NULL && frag != NULL); + return ((const struct interface*)sdis_data_cget(data))->hc; +} + +/******************************************************************************* + * Test + ******************************************************************************/ +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct sdis_mc T = SDIS_MC_NULL; + struct sdis_device* dev = NULL; + struct sdis_medium* solid = NULL; + struct sdis_medium* fluid = NULL; + struct sdis_interface* interface = NULL; + struct sdis_scene* scn = NULL; + struct sdis_data* data = NULL; + struct sdis_estimator* estimator = NULL; + struct sdis_fluid_shader fluid_shader = DUMMY_FLUID_SHADER; + struct sdis_solid_shader solid_shader = DUMMY_SOLID_SHADER; + struct sdis_interface_shader interface_shader = DUMMY_INTERFACE_SHADER; + struct context ctx; + struct fluid* fluid_param; + struct solid* solid_param; + struct interface* interface_param; + double pos[3]; + double time; + const size_t N = 1000; + size_t nreals; + size_t nfails; + (void)argc, (void)argv; + + CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); + CHK(sdis_device_create + (NULL, &allocator, SDIS_NTHREADS_DEFAULT, 0, &dev) == RES_OK); + + /* Create the fluid medium */ + CHK(sdis_data_create + (dev, sizeof(struct fluid), ALIGNOF(struct fluid), NULL, &data) == RES_OK); + fluid_param = sdis_data_get(data); + fluid_param->temperature = 300; + fluid_shader.temperature = fluid_get_temperature; + CHK(sdis_fluid_create(dev, &fluid_shader, data, &fluid) == RES_OK); + CHK(sdis_data_ref_put(data) == RES_OK); + + /* Create the solid medium */ + CHK(sdis_data_create + (dev, sizeof(struct solid), ALIGNOF(struct solid), NULL, &data) == RES_OK); + solid_param = sdis_data_get(data); + solid_param->cp = 1.0; + solid_param->lambda = 0.1; + solid_param->rho = 1.0; + solid_param->delta = 1.0/20.0; + solid_param->temperature = -1; + solid_shader.calorific_capacity = solid_get_calorific_capacity; + solid_shader.thermal_conductivity = solid_get_thermal_conductivity; + solid_shader.volumic_mass = solid_get_volumic_mass; + solid_shader.delta_solid = solid_get_delta; + solid_shader.delta_boundary = solid_get_delta_boundary; + solid_shader.temperature = solid_get_temperature; + CHK(sdis_solid_create(dev, &solid_shader, data, &solid) == RES_OK); + CHK(sdis_data_ref_put(data) == RES_OK); + + /* Create the solid/fluid interface */ + CHK(sdis_data_create(dev, sizeof(struct interface), + ALIGNOF(struct interface), NULL, &data) == RES_OK); + interface_param = sdis_data_get(data); + interface_param->hc = 0.5; + interface_shader.convection_coef = interface_get_convection_coef; + interface_shader.temperature = NULL; + CHK(sdis_interface_create + (dev, solid, fluid, &interface_shader, data, &interface) == RES_OK); + CHK(sdis_data_ref_put(data) == RES_OK); + + /* Release the media */ + CHK(sdis_medium_ref_put(solid) == RES_OK); + CHK(sdis_medium_ref_put(fluid) == RES_OK); + + /* Create the scene */ + ctx.positions = box_vertices; + ctx.indices = box_indices; + ctx.interface = interface; + CHK(sdis_scene_create(dev, box_ntriangles, get_indices, get_interface, + box_nvertices, get_position, &ctx, &scn) == RES_OK); + + CHK(sdis_interface_ref_put(interface) == RES_OK); + + /* Test the solver */ + pos[0] = 0.5; + pos[1] = 0.5; + pos[2] = 0.5; + time = INF; + CHK(sdis_solve_probe(NULL, N, pos, time, 1.0, &estimator) == RES_BAD_ARG); + CHK(sdis_solve_probe(scn, 0, pos, time, 1.0, &estimator) == RES_BAD_ARG); + CHK(sdis_solve_probe(scn, N, NULL, time, 1.0, &estimator) == RES_BAD_ARG); + CHK(sdis_solve_probe(scn, N, pos, time, 0, &estimator) == RES_BAD_ARG); + CHK(sdis_solve_probe(scn, N, pos, time, 1.0, NULL) == RES_BAD_ARG); + CHK(sdis_solve_probe(scn, N, pos, time, 1.0, &estimator) == RES_OK); + + CHK(sdis_estimator_get_realisation_count(estimator, NULL) == RES_BAD_ARG); + CHK(sdis_estimator_get_realisation_count(NULL, &nreals) == RES_BAD_ARG); + CHK(sdis_estimator_get_realisation_count(estimator, &nreals) == RES_OK); + + CHK(sdis_estimator_get_failure_count(estimator, NULL) == RES_BAD_ARG); + CHK(sdis_estimator_get_failure_count(NULL, &nfails) == RES_BAD_ARG); + CHK(sdis_estimator_get_failure_count(estimator, &nfails) == RES_OK); + + CHK(nfails + nreals == N); + + CHK(sdis_estimator_get_temperature(estimator, NULL) == RES_BAD_ARG); + CHK(sdis_estimator_get_temperature(NULL, &T) == RES_BAD_ARG); + CHK(sdis_estimator_get_temperature(estimator, &T) == RES_OK); + + CHK(eq_eps(T.E, 300, T.SE)); + + CHK(sdis_estimator_ref_get(NULL) == RES_BAD_ARG); + CHK(sdis_estimator_ref_get(estimator) == RES_OK); + CHK(sdis_estimator_ref_put(NULL) == RES_BAD_ARG); + CHK(sdis_estimator_ref_put(estimator) == RES_OK); + CHK(sdis_estimator_ref_put(estimator) == RES_OK); + + CHK(sdis_scene_ref_put(scn) == RES_OK); + CHK(sdis_device_ref_put(dev) == RES_OK); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHK(mem_allocated_size() == 0); + return 0; +} +