stardis-solver

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

commit 4f71c30745b0f71d207c2f9ffeda2a6abd935b1f
parent 43f4f2e2fbb45ef3c9e8f2037831715f51716aff
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 18 Dec 2017 16:15:22 +0100

Implement the scene API

Diffstat:
Mcmake/CMakeLists.txt | 6++++--
Msrc/sdis_device.c | 13+++++++++++++
Msrc/sdis_device_c.h | 9+++++++++
Msrc/sdis_interface.c | 16+++++++++++++++-
Asrc/sdis_interface_c.h | 28++++++++++++++++++++++++++++
Asrc/sdis_scene.c | 280+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 349 insertions(+), 3 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -24,6 +24,7 @@ option(NO_TEST "Do not build tests" OFF) # Check dependencies ################################################################################ find_package(RCMake 0.3 REQUIRED) +find_package(Star3D 0.4 REQUIRED) find_package(RSys 0.6 REQUIRED) find_package(OpenMP 1.2 REQUIRED) @@ -45,7 +46,8 @@ set(SDIS_FILES_SRC sdis_data.c sdis_device.c sdis_interface.c - sdis_medium.c) + sdis_medium.c + sdis_scene.c) set(SDIS_FILES_INC_API sdis.h) @@ -65,7 +67,7 @@ add_library(sdis SHARED ${SDIS_FILES_SRC} ${SDIS_FILES_INC} ${SDIS_FILES_INC_API}) -target_link_libraries(sdis RSys) +target_link_libraries(sdis RSys Star3D) set_target_properties(sdis PROPERTIES DEFINE_SYMBOL SDIS_SHARED_BUILD diff --git a/src/sdis_device.c b/src/sdis_device.c @@ -19,6 +19,8 @@ #include <rsys/logger.h> #include <rsys/mem_allocator.h> +#include <star/s3d.h> + #include <omp.h> /******************************************************************************* @@ -45,6 +47,9 @@ device_release(ref_T* ref) struct sdis_device* dev; ASSERT(ref); dev = CONTAINER_OF(ref, struct sdis_device, ref); + if(dev->s3d) S3D(device_ref_put(dev->s3d)); + ASSERT(flist_name_is_empty(&dev->names)); + flist_name_release(&dev->names); MEM_RM(dev->allocator, dev); } @@ -86,6 +91,14 @@ sdis_device_create dev->verbose = verbose; dev->nthreads = MMIN(nthreads_hint, (unsigned)omp_get_num_procs()); ref_init(&dev->ref); + flist_name_init(allocator, &dev->names); + + res = s3d_device_create(log, allocator, 0, &dev->s3d); + if(res != RES_OK) { + log_err(dev, + "%s: could not create the Star-3D device on Stardis.\n", FUNC_NAME); + goto error; + } exit: if(out_dev) *out_dev = dev; diff --git a/src/sdis_device_c.h b/src/sdis_device_c.h @@ -16,14 +16,23 @@ #ifndef SDIS_DEVICE_C_H #define SDIS_DEVICE_C_H +#include <rsys/free_list.h> #include <rsys/ref_count.h> +struct name { FITEM; }; +#define FITEM_TYPE name +#include <rsys/free_list.h> + struct sdis_device { struct logger* logger; struct mem_allocator* allocator; unsigned nthreads; int verbose; + struct flist_name names; + + struct s3d_device* s3d; + ref_T ref; }; diff --git a/src/sdis_interface.c b/src/sdis_interface.c @@ -15,6 +15,7 @@ #include "sdis.h" #include "sdis_device_c.h" +#include "sdis_interface_c.h" #include <rsys/mem_allocator.h> @@ -23,6 +24,7 @@ struct sdis_interface { struct sdis_medium* medium_back; struct sdis_interface_shader shader; struct sdis_data* data; + struct fid id; /* Unique identifier of the interface */ ref_T ref; struct sdis_device* dev; @@ -44,7 +46,7 @@ check_interface_shader type0 = sdis_medium_get_type(front); type1 = sdis_medium_get_type(back); - /* Fluid<->solid interface */ + /* Fluid<->solid interface */ if(type0 != type1 && shader->convection_coef == NULL) { return 0; } @@ -70,6 +72,7 @@ interface_release(ref_T* ref) if(interface->medium_front) SDIS(medium_ref_put(interface->medium_front)); if(interface->medium_back) SDIS(medium_ref_put(interface->medium_back)); if(interface->data) SDIS(data_ref_put(interface->data)); + flist_name_del(&dev->names, interface->id); MEM_RM(dev->allocator, interface); SDIS(device_ref_put(dev)); } @@ -121,6 +124,7 @@ sdis_interface_create interface->medium_back = back; interface->dev = dev; interface->shader = *shader; + interface->id = flist_name_add(&dev->names); if(data) { SDIS(data_ref_get(data)); @@ -154,3 +158,13 @@ sdis_interface_ref_put(struct sdis_interface* interface) return RES_OK; } +/******************************************************************************* + * Local function + ******************************************************************************/ +unsigned +interface_get_id(const struct sdis_interface* interface) +{ + ASSERT(interface); + return interface->id.index; +} + diff --git a/src/sdis_interface_c.h b/src/sdis_interface_c.h @@ -0,0 +1,28 @@ +/* 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/>. */ + +#ifndef SDIS_INTERFACE_C_H +#define SDIS_INTERFACE_C_H + +#include <rsys/rsys.h> + +struct sdis_interface; + +extern LOCAL_SYM unsigned +interface_get_id + (const struct sdis_interface* interface); + +#endif /* SDIS_INTERFACE_C_H */ + diff --git a/src/sdis_scene.c b/src/sdis_scene.c @@ -0,0 +1,280 @@ +/* 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 "sdis_device_c.h" +#include "sdis_interface_c.h" + +#include <rsys/dynamic_array.h> +#include <rsys/mem_allocator.h> +#include <star/s3d.h> + +#include <limits.h> + +/* Context used to wrap the user geometry to Star-3D */ +struct geometry_context { + void (*indices)(const size_t itri, size_t ids[3], void*); + void (*position)(const size_t ivert, double pos[3], void*); + void* data; +}; + +static INLINE void +interface_init + (struct mem_allocator* allocator, + struct sdis_interface** interface) +{ + (void)allocator; + *interface = NULL; +} + +/* Declare the array of interfaces */ +#define DARRAY_NAME interface +#define DARRAY_DATA struct sdis_interface* +#define DARRAY_FUNCTOR_INIT interface_init +#include <rsys/dynamic_array.h> + +struct sdis_scene { + struct darray_interface interfaces; /* List of interfaces own by the scene */ + struct darray_interface prim_interfaces; /* Per primitive interface */ + struct s3d_scene_view* s3d_view; + + ref_T ref; + struct sdis_device* dev; +}; + +/******************************************************************************* + * Helper function + ******************************************************************************/ +static void +get_indices(const unsigned itri, unsigned out_ids[3], void* data) +{ + struct geometry_context* ctx = data; + size_t ids[3]; + ASSERT(ctx); + ctx->indices(itri, ids, ctx->data); + out_ids[0] = (unsigned)ids[0]; + out_ids[1] = (unsigned)ids[1]; + out_ids[2] = (unsigned)ids[2]; +} + +static void +get_position(const unsigned ivert, float out_pos[3], void* data) +{ + struct geometry_context* ctx = data; + double pos[3]; + ASSERT(ctx); + ctx->position(ivert, pos, ctx->data); + out_pos[0] = (float)pos[0]; + out_pos[1] = (float)pos[1]; + out_pos[2] = (float)pos[2]; +} + +static void +clear_interfaces(struct sdis_scene* scn) +{ + size_t i; + ASSERT(scn); + FOR_EACH(i, 0, darray_interface_size_get(&scn->interfaces)) { + if(!darray_interface_cdata_get(&scn->interfaces)[i]) continue; + SDIS(interface_ref_put(darray_interface_data_get(&scn->interfaces)[i])); + } + darray_interface_clear(&scn->interfaces); + darray_interface_clear(&scn->prim_interfaces); +} + +static res_T +setup_interfaces + (struct sdis_scene* scn, + const size_t ntris, /* #triangles */ + void (*interface)(const size_t itri, struct sdis_interface**, void*), + void* ctx) +{ + size_t itri; + res_T res = RES_OK; + ASSERT(ntris && interface); + + clear_interfaces(scn); + + FOR_EACH(itri, 0, ntris) { + struct sdis_interface* itface; + size_t ninterfaces; + unsigned id; + + /* Retrieve the interface of the primitive */ + interface(itri, &itface, ctx); + id = interface_get_id(itface); + + /* Check that the interface is already registered against the scene */ + ninterfaces = darray_interface_size_get(&scn->interfaces); + if(id >= ninterfaces) { + res = darray_interface_resize(&scn->interfaces, ninterfaces + 1); + if(res != RES_OK) goto error; + } + if(darray_interface_cdata_get(&scn->interfaces)[id]) { + ASSERT(darray_interface_cdata_get(&scn->interfaces)[id] == itface); + } else { + SDIS(interface_ref_get(itface)); + darray_interface_data_get(&scn->interfaces)[id] = itface; + } + + /* Register the primitive interface */ + res = darray_interface_push_back(&scn->prim_interfaces, &itface); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + clear_interfaces(scn); + goto exit; +} + +static res_T +setup_geometry + (struct sdis_scene* scn, + const size_t ntris, /* #triangles */ + void (*indices)(const size_t itri, size_t ids[3], void*), + const size_t nverts, /* #vertices */ + void (*position)(const size_t ivert, double pos[3], void* ctx), + void* ctx) +{ + struct geometry_context context; + struct s3d_shape* s3d_msh = NULL; + struct s3d_scene* s3d_scn = NULL; + struct s3d_vertex_data vdata = S3D_VERTEX_DATA_NULL; + res_T res = RES_OK; + ASSERT(scn && ntris && indices && nverts && position); + + /* Setup the intermediary geometry context */ + context.indices = indices; + context.position = position; + context.data = ctx; + + /* Setup the vertex data */ + vdata.usage = S3D_POSITION; + vdata.type = S3D_FLOAT3; + vdata.get = get_position; + + /* Create the Star-3D geometry */ + res = s3d_scene_create(scn->dev->s3d, &s3d_scn); + if(res != RES_OK) goto error; + res = s3d_shape_create_mesh(scn->dev->s3d, &s3d_msh); + if(res != RES_OK) goto error; + res = s3d_scene_attach_shape(s3d_scn, s3d_msh); + if(res != RES_OK) goto error; + 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); + if(res != RES_OK) goto error; + +exit: + if(s3d_msh) S3D(shape_ref_put(s3d_msh)); + if(s3d_scn) S3D(scene_ref_put(s3d_scn)); + return res; +error: + if(scn->s3d_view) S3D(scene_view_ref_put(scn->s3d_view)); + goto exit; +} + +static void +scene_release(ref_T * ref) +{ + struct sdis_device* dev = NULL; + struct sdis_scene* scn = NULL; + ASSERT(ref); + scn = CONTAINER_OF(ref, struct sdis_scene, ref); + dev = scn->dev; + clear_interfaces(scn); + darray_interface_release(&scn->interfaces); + darray_interface_release(&scn->prim_interfaces); + MEM_RM(dev->allocator, scn); + SDIS(device_ref_put(dev)); +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +sdis_scene_create + (struct sdis_device* dev, + const size_t ntris, /* #triangles */ + void (*indices)(const size_t itri, size_t ids[3], void*), + void (*interface)(const size_t itri, struct sdis_interface** bound, void*), + const size_t nverts, /* #vertices */ + void (*position)(const size_t ivert, double pos[3], void* ctx), + void* ctx, + struct sdis_scene** out_scn) +{ + struct sdis_scene* scn = NULL; + res_T res = RES_OK; + + if(!dev || !out_scn || !scn || !ntris || !indices || !interface || nverts + || !position || ntris > UINT_MAX || nverts > UINT_MAX) { + res = RES_BAD_ARG; + goto error; + } + + scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct sdis_scene)); + if(!scn) { + log_err(dev, "%s: could not allocate the Stardis scene.\n", FUNC_NAME); + res = RES_MEM_ERR; + goto error; + } + ref_init(&scn->ref); + SDIS(device_ref_get(dev)); + scn->dev = dev; + darray_interface_init(dev->allocator, &scn->interfaces); + darray_interface_init(dev->allocator, &scn->prim_interfaces); + + res = setup_interfaces(scn, ntris, interface, ctx); + if(res != RES_OK) { + log_err(dev, "%s: could not setup the scene interfaces.\n", FUNC_NAME); + goto error; + } + + res = setup_geometry(scn, ntris, indices, nverts, position, ctx); + if(res != RES_OK) { + log_err(dev, "%s: could not setup the scene geometry.\n", FUNC_NAME); + goto error; + } + +exit: + if(out_scn) *out_scn = scn; + return res; +error: + if(scn) { + SDIS(scene_ref_put(scn)); + scn = NULL; + } + goto exit; +} + +res_T +sdis_scene_ref_get(struct sdis_scene* scn) +{ + if(scn) return RES_BAD_ARG; + ref_get(&scn->ref); + return RES_OK; +} + +res_T +sdis_scene_ref_put(struct sdis_scene* scn) +{ + if(scn) return RES_BAD_ARG; + ref_put(&scn->ref, scene_release); + return RES_OK; +} +