sphin_prop_rad.c (6303B)
1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique 2 * Copyright (C) 2024-2026 Clermont Auvergne INP 3 * Copyright (C) 2024-2026 INSA Lyon 4 * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux 5 * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse 6 * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com) 7 * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com) 8 * Copyright (C) 2024-2026 Université de Lorraine 9 * Copyright (C) 2024-2026 Université Paul Sabatier 10 * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès 11 * 12 * This program is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation, either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 24 #define _POSIX_C_SOURCE 200112L /* for strtok_r support */ 25 26 #include "sphin_c.h" 27 #include "sphin_config.h" 28 #include "sphin_prop_rad.h" 29 #include "sphin_scatterer.h" 30 #include "sphin_volume.h" 31 32 #include <rsys/mem_allocator.h> 33 #include <rsys/ref_count.h> 34 #include <rsys/rsys.h> 35 #include <rsys/str.h> 36 #include <rsys/text_reader.h> 37 38 /******************************************************************************* 39 * Helper functions 40 ******************************************************************************/ 41 static res_T 42 prop_rad_create 43 (struct sphin* sphin, 44 const char* name, 45 struct sphin_prop_rad** out_prop_rad) 46 { 47 struct sphin_prop_rad* prop_rad = NULL; 48 res_T res = RES_OK; 49 50 ASSERT('\0' != name[0]); /* Name can't be empty */ 51 ASSERT(NULL != name); 52 ASSERT(NULL != out_prop_rad); 53 ASSERT(NULL != sphin); 54 55 prop_rad = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_prop_rad)); 56 if (NULL == prop_rad) { res = RES_MEM_ERR; goto error; } 57 ref_init(&prop_rad->ref); 58 SPHIN(ref_get(sphin)); 59 prop_rad->sphin = sphin; 60 prop_rad->scatterer = NULL; 61 62 str_init(sphin->allocator, &prop_rad->name); 63 res = str_set(&prop_rad->name, name); 64 if (RES_OK != res) { goto error; } 65 66 exit: 67 *out_prop_rad = prop_rad; 68 return res; 69 error: 70 if (NULL != prop_rad) { 71 SPHIN(prop_rad_ref_put(prop_rad)); 72 prop_rad = NULL; 73 } 74 goto exit; 75 } 76 77 static void 78 release_prop_rad 79 (ref_T* address) 80 { 81 struct sphin_prop_rad* prop_rad = NULL; 82 struct sphin* sphin = NULL; 83 84 ASSERT(NULL != address); 85 86 prop_rad = CONTAINER_OF(address, struct sphin_prop_rad, ref); 87 str_release(&prop_rad->name); 88 if (NULL != prop_rad->scatterer) { 89 SPHIN(scatterer_ref_put(prop_rad->scatterer)); 90 } 91 sphin = prop_rad->sphin; 92 MEM_RM(sphin->allocator, prop_rad); 93 SPHIN(ref_put(sphin)); 94 } 95 96 /******************************************************************************* 97 * Local functions 98 ******************************************************************************/ 99 res_T 100 parse_prop_rad 101 (struct sphin_config* config, 102 struct sphin_volume* volume, 103 struct txtrdr* txtrdr, 104 char* value) 105 { 106 char* prop_rad_type_str = NULL; 107 char* name = NULL; 108 char* token = NULL; 109 char* token_ptr = NULL; 110 enum sphin_prop_rad_type prop_rad_type = SPHIN_PROP_RAD_NONE__; 111 struct str line; 112 struct sphin_prop_rad* prop_rad = NULL; 113 res_T res = RES_OK; 114 115 ASSERT(NULL != volume); 116 ASSERT(NULL != txtrdr); 117 ASSERT(NULL != value); 118 ASSERT('\0' != value[0]); /* Name can't be empty */ 119 120 str_init(config->sphin->allocator, &line); 121 122 /* Parse name of the prop_rad */ 123 name = trim_string(value); 124 if (NULL == name){ res = RES_BAD_ARG; goto error; } 125 126 /* Next line: corresponds to the prop_rad type */ 127 res = txtrdr_read_line(txtrdr); 128 if (RES_OK != res) { goto error; } 129 130 if (NULL == txtrdr_get_line(txtrdr)) { res = RES_BAD_ARG; goto error; } 131 132 res = str_set(&line, txtrdr_get_cline(txtrdr)); 133 if (RES_OK != res) { goto error; } 134 135 token = strtok_r(str_get(&line), ":", &token_ptr); 136 if (NULL == token) { res = RES_BAD_ARG; goto error; } 137 138 prop_rad_type_str = trim_keyword(token); 139 if (0 == strcmp(prop_rad_type_str, "scatterer")) { 140 prop_rad_type = SPHIN_PROP_RAD_SCATTERER; 141 } else { 142 res = RES_BAD_ARG; goto error; 143 } 144 145 res = prop_rad_create(volume->sphin, name, &prop_rad); 146 if (RES_OK != res) { goto error; } 147 148 /* Parse prop rad parameters in function of its type */ 149 switch(prop_rad_type) { 150 case SPHIN_PROP_RAD_BOLTZMANN: 151 /* TODO Parse prop rad coefficients */ 152 break; 153 154 case SPHIN_PROP_RAD_SCATTERER: 155 res = parse_scatterer(prop_rad, txtrdr); 156 if (RES_OK != res) { goto error; } 157 break; 158 159 case SPHIN_PROP_RAD_NONE__: 160 res = RES_BAD_ARG; 161 goto error; 162 163 default: 164 FATAL("Unreachable code\n"); break; 165 } 166 167 res = darray_sphin_prop_rad_ptr_push_back(&volume->prop_rads, &prop_rad); 168 if (RES_OK != res) { goto error; } 169 170 exit: 171 str_release(&line); 172 return res; 173 error: 174 if (NULL != prop_rad) { 175 SPHIN(prop_rad_ref_put(prop_rad)); 176 prop_rad = NULL; 177 } 178 goto exit; 179 } 180 181 /******************************************************************************* 182 * Exported functions 183 ******************************************************************************/ 184 res_T 185 sphin_prop_rad_ref_get 186 (struct sphin_prop_rad* prop_rad) 187 { 188 if (NULL == prop_rad) { 189 return RES_BAD_ARG; 190 } 191 ref_get(&prop_rad->ref); 192 return RES_OK; 193 } 194 195 res_T 196 sphin_prop_rad_ref_put 197 (struct sphin_prop_rad* prop_rad) 198 { 199 if (NULL == prop_rad) { 200 return RES_BAD_ARG; 201 } 202 ref_put(&prop_rad->ref, release_prop_rad); 203 return RES_OK; 204 } 205 206 res_T 207 sphin_prop_rad_get_name 208 (struct sphin_prop_rad* prop_rad, 209 char** name) 210 { 211 if (NULL == prop_rad || NULL == name) { 212 return RES_BAD_ARG; 213 } 214 *name = (char*)str_get((struct str*)&prop_rad->name); 215 return RES_OK; 216 } 217 218 res_T 219 sphin_prop_rad_get_scatterer 220 (struct sphin_prop_rad* prop_rad, 221 struct sphin_scatterer** scatterer) 222 { 223 if (NULL == prop_rad 224 || NULL == scatterer) { 225 return RES_BAD_ARG; 226 } 227 *scatterer = prop_rad->scatterer; 228 return RES_OK; 229 }