test_sphin_load_prop_rad.c (12800B)
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 25 #include "sphin.h" 26 27 #include <rsys/math.h> 28 #include <rsys/mem_allocator.h> 29 #include <rsys/rsys.h> 30 31 #include <stdio.h> 32 #include <string.h> 33 34 struct sphin; 35 36 static void 37 write_prop_rad_test_files 38 (void) 39 { 40 FILE* file; 41 static const char* test0 = 42 "#wv abs_cross_sec\n" 43 "100 1\n" 44 "200 2\n" 45 "300 3\n" 46 "400 4\n"; 47 static const char* test1 = /* Invalid first line */ 48 "wv abs_cross_sec\n" 49 "100 1\n" 50 "200 2\n" 51 "300 3\n" 52 "400 4\n"; 53 static const char* test2 = /* Unsorted wavelengths */ 54 "100 1\n" 55 "300 3\n" 56 "200 2\n" 57 "400 4\n"; 58 static const char* test3 = /* Missing data */ 59 "100 1\n" 60 "200 2\n" 61 "300 \n" 62 "400 4\n"; 63 static const char* test4 = /* Bad formating */ 64 "100 1\n" 65 "200 2\n" 66 "300 2,5\n" 67 "400 4\n"; 68 file = fopen("abs_cross_sec_0.txt", "w"); 69 CHK(file != NULL); 70 fwrite(test0, sizeof(char), strlen(test0), file); 71 fclose(file); 72 73 file = fopen("abs_cross_sec_1.txt", "w"); 74 CHK(file != NULL); 75 fwrite(test1, sizeof(char), strlen(test1), file); 76 fclose(file); 77 78 file = fopen("abs_cross_sec_2.txt", "w"); 79 CHK(file != NULL); 80 fwrite(test2, sizeof(char), strlen(test2), file); 81 fclose(file); 82 83 file = fopen("abs_cross_sec_3.txt", "w"); 84 CHK(file != NULL); 85 fwrite(test3, sizeof(char), strlen(test3), file); 86 fclose(file); 87 88 file = fopen("abs_cross_sec_4.txt", "w"); 89 CHK(file != NULL); 90 fwrite(test4, sizeof(char), strlen(test4), file); 91 fclose(file); 92 } 93 94 static void 95 test_prop_rad_api 96 (struct sphin* sphin) 97 { 98 struct sphin_config* config = NULL; 99 const char* path = "file.txt"; 100 char* name = NULL; 101 struct sphin_volume* volume = NULL; 102 struct sphin_prop_rad* prop_rad = NULL; 103 struct sphin_scatterer* scatterer = NULL; 104 struct sphin_spectral_property* abs_cross_sec = NULL; 105 struct sphin_spectral_property_descriptor abs_cs_desc = 106 SPHIN_SPECTRAL_PROPERTY_DESCRIPTOR_NULL; 107 size_t nprop_rad; 108 double concentration, value; 109 FILE* fp = NULL; 110 CHK(fp = fopen(path, "w+")); 111 fprintf(fp, "#Mot Clé Nom\n"); 112 fprintf(fp, "volume: \"reaction volume\"\n"); 113 fprintf(fp, "\tprop_rad:\"my prop_rad\"\n"); 114 fprintf(fp, "\t\tscatterer:\n"); 115 fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n"); 116 fprintf(fp, "\t\tcross_sections:\n"); 117 fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_0.txt nm m^2/part\n"); 118 fclose(fp); 119 120 CHK(sphin_load(sphin, path, &config) == RES_OK); 121 CHK(sphin_config_get_volume(config, 0, &volume) == RES_OK); 122 CHK(sphin_volume_get_prop_rad_count(NULL, NULL) == RES_BAD_ARG); 123 CHK(sphin_volume_get_prop_rad_count(volume, NULL) == RES_BAD_ARG); 124 CHK(sphin_volume_get_prop_rad_count(NULL, &nprop_rad) == RES_BAD_ARG); 125 CHK(sphin_volume_get_prop_rad_count(volume, &nprop_rad) == RES_OK); 126 CHK(nprop_rad == 1); 127 CHK(sphin_volume_get_prop_rad(NULL, 0, NULL) == RES_BAD_ARG); 128 CHK(sphin_volume_get_prop_rad(volume, 0, NULL) == RES_BAD_ARG); 129 CHK(sphin_volume_get_prop_rad(NULL, 0, &prop_rad) == RES_BAD_ARG); 130 CHK(sphin_volume_get_prop_rad(volume, (size_t)-1, &prop_rad) == RES_BAD_ARG); 131 CHK(sphin_volume_get_prop_rad(volume, 10, &prop_rad) == RES_BAD_ARG); 132 CHK(sphin_volume_get_prop_rad(volume, 0, &prop_rad) == RES_OK); 133 CHK(sphin_prop_rad_get_name(NULL, NULL) == RES_BAD_ARG); 134 CHK(sphin_prop_rad_get_name(prop_rad, NULL) == RES_BAD_ARG); 135 CHK(sphin_prop_rad_get_name(NULL, &name) == RES_BAD_ARG); 136 CHK(sphin_prop_rad_get_name(prop_rad, &name) == RES_OK); 137 CHK(strcmp(name, "my prop_rad") == 0); 138 CHK(sphin_prop_rad_ref_get(prop_rad) == RES_OK); 139 CHK(sphin_prop_rad_ref_get(NULL) == RES_BAD_ARG); 140 CHK(sphin_prop_rad_ref_put(NULL) == RES_BAD_ARG); 141 CHK(sphin_prop_rad_ref_put(prop_rad) == RES_OK); 142 CHK(sphin_prop_rad_get_scatterer(NULL, NULL) == RES_BAD_ARG); 143 CHK(sphin_prop_rad_get_scatterer(prop_rad, NULL) == RES_BAD_ARG); 144 CHK(sphin_prop_rad_get_scatterer(NULL, &scatterer) == RES_BAD_ARG); 145 CHK(sphin_prop_rad_get_scatterer(prop_rad, &scatterer) == RES_OK); 146 CHK(sphin_scatterer_ref_get(NULL) == RES_BAD_ARG); 147 CHK(sphin_scatterer_ref_get(scatterer) == RES_OK); 148 CHK(sphin_scatterer_ref_put(NULL) == RES_BAD_ARG); 149 CHK(sphin_scatterer_ref_put(scatterer) == RES_OK); 150 CHK(sphin_scatterer_get_concentration(NULL, NULL) == RES_BAD_ARG); 151 CHK(sphin_scatterer_get_concentration(scatterer, NULL) == RES_BAD_ARG); 152 CHK(sphin_scatterer_get_concentration(NULL, &concentration) == RES_BAD_ARG); 153 CHK(sphin_scatterer_get_concentration(scatterer, &concentration) == RES_OK); 154 CHK(eq_eps(concentration, 1.935, 1e-15)); 155 CHK(sphin_scatterer_get_abs_cross_sec(NULL, NULL) == RES_BAD_ARG); 156 CHK(sphin_scatterer_get_abs_cross_sec(scatterer, NULL) == RES_BAD_ARG); 157 CHK(sphin_scatterer_get_abs_cross_sec(NULL, &abs_cross_sec) == RES_BAD_ARG); 158 CHK(sphin_scatterer_get_abs_cross_sec(scatterer, &abs_cross_sec) == RES_OK); 159 CHK(sphin_spectral_property_ref_get(NULL) == RES_BAD_ARG); 160 CHK(sphin_spectral_property_ref_get(abs_cross_sec) == RES_OK); 161 CHK(sphin_spectral_property_ref_put(NULL) == RES_BAD_ARG); 162 CHK(sphin_spectral_property_ref_put(abs_cross_sec) == RES_OK); 163 CHK(sphin_spectral_property_get_desc(NULL, NULL) == RES_BAD_ARG); 164 CHK(sphin_spectral_property_get_desc(abs_cross_sec, NULL) == RES_BAD_ARG); 165 CHK(sphin_spectral_property_get_desc(NULL, &abs_cs_desc) == RES_BAD_ARG); 166 CHK(sphin_spectral_property_get_desc(abs_cross_sec, &abs_cs_desc) == RES_OK); 167 CHK(sphin_spectral_property_interpolate_at_wavelength 168 (abs_cross_sec, 100, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK); 169 CHK(eq_eps(value, 1., 1e-15)); 170 CHK(sphin_spectral_property_interpolate_at_wavelength 171 (abs_cross_sec, 175, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK); 172 CHK(eq_eps(value, 1.75, 1e-15)); 173 CHK(sphin_spectral_property_interpolate_at_wavelength 174 (abs_cross_sec, 400, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK); 175 CHK(eq_eps(value, 4., 1e-15)); 176 CHK(eq_eps(abs_cs_desc.wavelengths[0], 100, 1e-15)); 177 CHK(eq_eps(abs_cs_desc.wavelengths[2], 300, 1e-15)); 178 CHK(eq_eps(abs_cs_desc.values[0], 1, 1e-15)); 179 CHK(eq_eps(abs_cs_desc.values[2], 3, 1e-15)); 180 CHK(abs_cs_desc.data_count == 4); 181 CHK(sphin_config_ref_put(config) == RES_OK); 182 } 183 184 static void 185 test_prop_rad_api_units 186 (struct sphin* sphin) 187 { 188 struct sphin_config* config = NULL; 189 const char* path = "file.txt"; 190 struct sphin_volume* volume = NULL; 191 struct sphin_prop_rad* prop_rad = NULL; 192 struct sphin_scatterer* scatterer = NULL; 193 struct sphin_spectral_property* abs_cross_sec = NULL; 194 struct sphin_spectral_property_descriptor abs_cs_desc = 195 SPHIN_SPECTRAL_PROPERTY_DESCRIPTOR_NULL; 196 double value; 197 FILE* fp = NULL; 198 CHK(fp = fopen(path, "w+")); 199 fprintf(fp, "#Mot Clé Nom\n"); 200 fprintf(fp, "volume: \"reaction volume\"\n"); 201 fprintf(fp, "\tprop_rad: \"name\"\n"); 202 fprintf(fp, "\t\tscatterer:\n"); 203 fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n"); 204 fprintf(fp, "\t\tcross_sections:\n"); 205 fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_0.txt cm m^2/part\n"); 206 fclose(fp); 207 208 CHK(sphin_load(sphin, path, &config) == RES_OK); 209 CHK(sphin_config_get_volume(config, 0, &volume) == RES_OK); 210 CHK(sphin_volume_get_prop_rad(volume, 0, &prop_rad) == RES_OK); 211 CHK(sphin_prop_rad_get_scatterer(prop_rad, &scatterer) == RES_OK); 212 CHK(sphin_scatterer_get_abs_cross_sec(scatterer, &abs_cross_sec) == RES_OK); 213 CHK(sphin_spectral_property_get_desc(abs_cross_sec, &abs_cs_desc) == RES_OK); 214 CHK(sphin_spectral_property_interpolate_at_wavelength 215 (abs_cross_sec, 100e7, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK); 216 CHK(eq_eps(value, 1., 1e-15)); 217 CHK(sphin_spectral_property_interpolate_at_wavelength 218 (abs_cross_sec, 175e7, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK); 219 CHK(eq_eps(value, 1.75, 1e-15)); 220 CHK(sphin_spectral_property_interpolate_at_wavelength 221 (abs_cross_sec, 400e7, SPHIN_INTERPOLATION_LINEAR, &value) == RES_OK); 222 CHK(eq_eps(value, 4., 1e-15)); 223 CHK(eq_eps(abs_cs_desc.wavelengths[0], 100e7, 1e-15)); 224 CHK(eq_eps(abs_cs_desc.wavelengths[2], 300e7, 1e-15)); 225 CHK(sphin_config_ref_put(config) == RES_OK); 226 } 227 static void 228 test_prop_rad_api_bad_comment 229 (struct sphin* sphin) 230 { 231 struct sphin_config* config = NULL; 232 const char* path = "file.txt"; 233 FILE* fp = NULL; 234 235 CHK(fp = fopen(path, "w+")); 236 fprintf(fp, "#Mot Clé Nom\n"); 237 fprintf(fp, "volume: \"reaction volume\"\n"); 238 fprintf(fp, "\tprop_rad: \"name\"\n"); 239 fprintf(fp, "\t\tscatterer:\n"); 240 fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n"); 241 fprintf(fp, "\t\tcross_sections:\n"); 242 fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_1.txt nm m^2/part\n"); 243 fclose(fp); 244 245 CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG); 246 } 247 248 static void 249 test_prop_rad_api_unsorted_wavelengths 250 (struct sphin* sphin) 251 { 252 struct sphin_config* config = NULL; 253 const char* path = "file.txt"; 254 FILE* fp = NULL; 255 256 CHK(fp = fopen(path, "w+")); 257 fprintf(fp, "#Mot Clé Nom\n"); 258 fprintf(fp, "volume: \"reaction volume\"\n"); 259 fprintf(fp, "\tprop_rad: \"name\"\n"); 260 fprintf(fp, "\t\tscatterer:\n"); 261 fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n"); 262 fprintf(fp, "\t\tcross_sections:\n"); 263 fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_2.txt nm m^2/part\n"); 264 fclose(fp); 265 266 CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG); 267 } 268 269 static void 270 test_prop_rad_api_missing_data 271 (struct sphin* sphin) 272 { 273 struct sphin_config* config = NULL; 274 const char* path = "file.txt"; 275 FILE* fp = NULL; 276 277 CHK(fp = fopen(path, "w+")); 278 fprintf(fp, "#Mot Clé Nom\n"); 279 fprintf(fp, "volume: \"reaction volume\"\n"); 280 fprintf(fp, "\tprop_rad: \"name\"\n"); 281 fprintf(fp, "\t\tscatterer:\n"); 282 fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n"); 283 fprintf(fp, "\t\tcross_sections:\n"); 284 fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_3.txt nm m^2/part\n"); 285 fclose(fp); 286 287 CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG); 288 } 289 290 static void 291 test_prop_rad_api_bad_formatting 292 (struct sphin* sphin) 293 { 294 struct sphin_config* config = NULL; 295 const char* path = "file.txt"; 296 FILE* fp = NULL; 297 298 CHK(fp = fopen(path, "w+")); 299 fprintf(fp, "#Mot Clé Nom\n"); 300 fprintf(fp, "volume: \"reaction volume\"\n"); 301 fprintf(fp, "\tprop_rad: \"name\"\n"); 302 fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n"); 303 fprintf(fp, "\t\tcross_sections:\n"); 304 fprintf(fp, "\t\t\tabs_cross_sec: abs_cross_sec_4.txt nm m^2/part\n"); 305 fclose(fp); 306 307 CHK(sphin_load(sphin, path, &config) == RES_BAD_ARG); 308 } 309 310 static void 311 test_prop_rad_api_non_existing_file 312 (struct sphin* sphin) 313 { 314 struct sphin_config* config = NULL; 315 const char* path = "file.txt"; 316 FILE* fp = NULL; 317 318 CHK(fp = fopen(path, "w+")); 319 fprintf(fp, "#Mot Clé Nom\n"); 320 fprintf(fp, "volume: \"reaction volume\"\n"); 321 fprintf(fp, "\tprop_rad: \"name\"\n"); 322 fprintf(fp, "\t\tscatterer:\n"); 323 fprintf(fp, "\t\tconcentration: 1.935 mol/m^3\n"); 324 fprintf(fp, "\t\tcross_sections:\n"); 325 fprintf(fp, "\t\t\tabs_cross_sec: non_existing_file.txt nm m^2/part\n"); 326 fclose(fp); 327 328 CHK(sphin_load(sphin, path, &config) == RES_IO_ERR); 329 } 330 331 int 332 main(int argc, char** argv) 333 { 334 struct sphin* sphin = NULL; 335 struct sphin_create_args args = SPHIN_CREATE_ARGS_DEFAULT; 336 337 (void)argc; 338 (void)argv; 339 340 args.verbose = 1; 341 sphin_create(&args, &sphin); 342 343 write_prop_rad_test_files(); 344 test_prop_rad_api(sphin); 345 test_prop_rad_api_units(sphin); 346 test_prop_rad_api_bad_comment(sphin); 347 test_prop_rad_api_unsorted_wavelengths(sphin); 348 test_prop_rad_api_missing_data(sphin); 349 test_prop_rad_api_bad_formatting(sphin); 350 test_prop_rad_api_non_existing_file(sphin); 351 CHK(sphin_ref_put(sphin) == RES_OK); 352 353 CHK(mem_allocated_size() == 0); 354 return 0; 355 }