atrstm_setup_uvm.c (4724B)
1 /* Copyright (C) 2022, 2023 |Méso|Star> (contact@meso-star.com) 2 * Copyright (C) 2020, 2021 Centre National de la Recherche Scientifique 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #include "atrstm_c.h" 18 #include "atrstm_log.h" 19 20 #include <star/smsh.h> 21 #include <star/suvm.h> 22 23 #include <rsys/clock_time.h> 24 25 /******************************************************************************* 26 * Helper functions 27 ******************************************************************************/ 28 static res_T 29 check_smsh_desc(struct atrstm* atrstm, const struct smsh_desc* desc) 30 { 31 res_T res = RES_OK; 32 ASSERT(atrstm && desc); 33 34 if(desc->dnode != 3 || desc->dcell != 4) { 35 log_err(atrstm, 36 "The mesh of a semi-transparent material must be a 3D tetrahedral mesh " 37 "(dimension of the mesh: %u; dimension of the vertices: %u)\n", 38 desc->dnode, desc->dcell); 39 res = RES_BAD_ARG; 40 goto error; 41 } 42 43 exit: 44 return res; 45 error: 46 goto exit; 47 } 48 49 static INLINE void 50 tetrahedron_get_indices(const size_t itetra, size_t ids[4], void* ctx) 51 { 52 const struct smsh_desc* smsh_desc = ctx; 53 const uint64_t* indices = NULL; 54 ASSERT(ctx && ids && itetra < smsh_desc->ncells && smsh_desc->dcell == 4); 55 indices = smsh_desc_get_cell(smsh_desc, itetra); 56 ids[0] = (size_t)indices[0]; 57 ids[1] = (size_t)indices[1]; 58 ids[2] = (size_t)indices[2]; 59 ids[3] = (size_t)indices[3]; 60 } 61 62 static INLINE void 63 vertex_get_position(const size_t ivert, double pos[3], void* ctx) 64 { 65 struct smsh_desc* smsh_desc = ctx; 66 const double* position = NULL; 67 ASSERT(ctx && pos && ivert < smsh_desc->nnodes && smsh_desc->dnode == 3); 68 position = smsh_desc_get_node(smsh_desc, ivert); 69 pos[0] = position[0]; 70 pos[1] = position[1]; 71 pos[2] = position[2]; 72 } 73 74 /******************************************************************************* 75 * Local functions 76 ******************************************************************************/ 77 res_T 78 setup_unstructured_volumetric_mesh 79 (struct atrstm* atrstm, 80 const int precompute_normals, 81 const char* smsh_filename, 82 struct suvm_volume** out_volume) 83 { 84 struct suvm_tetrahedral_mesh_args mesh_args = SUVM_TETRAHEDRAL_MESH_ARGS_NULL; 85 struct smsh_create_args smsh_create_args = SMSH_CREATE_ARGS_DEFAULT; 86 struct smsh_desc smsh_desc = SMSH_DESC_NULL; 87 struct smsh_load_args smsh_load_args = SMSH_LOAD_ARGS_NULL; 88 struct smsh* smsh = NULL; 89 struct suvm_volume* volume = NULL; 90 struct time t0, t1; 91 char buf[128]; 92 res_T res = RES_OK; 93 ASSERT(atrstm && smsh_filename && out_volume); 94 95 log_info(atrstm, "Load and structure the volumetric mesh '%s'.\n", 96 smsh_filename); 97 98 time_current(&t0); 99 100 /* Load the volumetric mesh */ 101 smsh_create_args.logger = atrstm->logger; 102 smsh_create_args.allocator = atrstm->allocator; 103 smsh_create_args.verbose = atrstm->verbose; 104 res = smsh_create(&smsh_create_args, &smsh); 105 if(res != RES_OK) goto error; 106 smsh_load_args.path = smsh_filename; 107 smsh_load_args.memory_mapping = 1; 108 res = smsh_load(smsh, &smsh_load_args); 109 if(res != RES_OK) goto error; 110 res = smsh_get_desc(smsh, &smsh_desc); 111 if(res != RES_OK) goto error; 112 res = check_smsh_desc(atrstm, &smsh_desc); 113 if(res != RES_OK) goto error; 114 115 /* Partition the unstructured volumetric mesh */ 116 mesh_args.ntetrahedra = smsh_desc.ncells; 117 mesh_args.nvertices = smsh_desc.nnodes; 118 mesh_args.get_indices = tetrahedron_get_indices; 119 mesh_args.get_position = vertex_get_position; 120 mesh_args.tetrahedron_data = SUVM_DATA_NULL; /* Tetra data are not in SUVM */ 121 mesh_args.vertex_data = SUVM_DATA_NULL; /* Vertex data are not in SUVM */ 122 mesh_args.precompute_normals = precompute_normals; 123 mesh_args.context = &smsh_desc; 124 res = suvm_tetrahedral_mesh_create(atrstm->suvm, &mesh_args, &volume); 125 if(res != RES_OK) goto error; 126 127 /* Report time */ 128 time_sub(&t0, time_current(&t1), &t0); 129 time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); 130 log_info(atrstm, "Setup volumetric mesh in %s.\n", buf); 131 132 exit: 133 *out_volume = volume; 134 if(smsh) SMSH(ref_put(smsh)); 135 return res; 136 error: 137 if(volume) { 138 SUVM(volume_ref_put(volume)); 139 volume = NULL; 140 } 141 goto exit; 142 }