htrdr_combustion_args.c (9129B)
1 /* Copyright (C) 2018-2019, 2022-2025 Centre National de la Recherche Scientifique 2 * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux 3 * Copyright (C) 2022-2025 Institut Pierre-Simon Laplace 4 * Copyright (C) 2022-2025 Institut de Physique du Globe de Paris 5 * Copyright (C) 2018-2025 |Méso|Star> (contact@meso-star.com) 6 * Copyright (C) 2022-2025 Observatoire de Paris 7 * Copyright (C) 2022-2025 Université de Reims Champagne-Ardenne 8 * Copyright (C) 2022-2025 Université de Versaille Saint-Quentin 9 * Copyright (C) 2018-2019, 2022-2025 Université Paul Sabatier 10 * 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation, either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 23 24 #define _POSIX_C_SOURCE 200112L /* strtok_r support */ 25 26 #include "combustion/htrdr_combustion_args.h" 27 28 #include <rsys/cstr.h> 29 30 #include <getopt.h> 31 #include <string.h> 32 33 /******************************************************************************* 34 * Helper functions 35 ******************************************************************************/ 36 static void 37 usage(void) 38 { 39 printf("usage: htrdr-combustion [-fhINsv] [-C persp_camera_opt[:persp_camera_opt ...]]\n"); 40 printf(" [-D laser_flux_density] [-d dump_type]\n"); 41 printf(" [-F rdgfa_opt[:rdgfa_opt ...]]\n"); 42 printf(" [-g combustion_chamber_opt[:combustion_chamber_opt...]]\n"); 43 printf(" [-i image_opt[:image_opt ...]]\n"); 44 printf(" [-l laser_opt[:laser_opt ...]] [-O cache] [-o output]\n"); 45 printf(" [-P ortho_camera_opt[:ortho_camera_opt ...]]\n"); 46 printf(" [-R flux_sensor_opt[:flux_sensor_opt ...]]\n"); 47 printf(" [-T optical_thickness] [-t threads_count]\n"); 48 printf(" [-V accel_struct_definition] [-w laser_wavelength]\n"); 49 printf(" -m medium_geometry -p thermo_properties\n"); 50 printf(" -r refractive_ids\n"); 51 } 52 53 static res_T 54 parse_grid_definition 55 (struct htrdr_combustion_args_grid_definition* grid_def, 56 const char* str) 57 { 58 unsigned def[3]; 59 size_t len; 60 res_T res = RES_OK; 61 ASSERT(grid_def && str); 62 63 res = cstr_to_list_uint(str, ',', def, &len, 3); 64 if(res == RES_OK && len == 2) res = RES_BAD_ARG; 65 if(res != RES_OK) { 66 fprintf(stderr, "Invalid grid definition `%s'.\n", str); 67 goto error; 68 } 69 70 if(len == 1) { 71 if(!def[0]) { 72 fprintf(stderr, "Invalid null grid definition %u.\n", def[0]); 73 res = RES_BAD_ARG; 74 goto error; 75 } 76 grid_def->type = HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_AUTO; 77 grid_def->definition.hint = def[0]; 78 79 } else { 80 if(!def[0] || !def[1] || !def[2]) { 81 fprintf(stderr, 82 "Invalid null grid definition [%u, %u, %u].\n", SPLIT3(def)); 83 res = RES_BAD_ARG; 84 goto error; 85 } 86 grid_def->type = HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_FIXED; 87 grid_def->definition.fixed[0] = def[0]; 88 grid_def->definition.fixed[1] = def[1]; 89 grid_def->definition.fixed[2] = def[2]; 90 } 91 92 exit: 93 return res; 94 error: 95 goto exit; 96 } 97 98 static res_T 99 parse_fractal_parameters(const char* str, void* ptr) 100 { 101 char buf[128]; 102 struct htrdr_combustion_args* args = ptr; 103 char* key; 104 char* val; 105 char* ctx; 106 res_T res = RES_OK; 107 ASSERT(ptr && str); 108 109 if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { 110 fprintf(stderr, 111 "Could not duplicate the fractal option string `%s'.\n", str); 112 res = RES_MEM_ERR; 113 goto error; 114 } 115 strncpy(buf, str, sizeof(buf)); 116 117 key = strtok_r(buf, "=", &ctx); 118 val = strtok_r(NULL, "", &ctx); 119 120 if(!strcmp(key, "prefactor")) { 121 res = cstr_to_double(val, &args->fractal_prefactor); 122 if(res != RES_OK) goto error; 123 } else if(!strcmp(key, "dimension")) { 124 res = cstr_to_double(val, &args->fractal_dimension); 125 if(res != RES_OK) goto error; 126 } else { 127 fprintf(stderr, "Invalid fractal parameter `%s'.\n", key); 128 res = RES_BAD_ARG; 129 goto error; 130 } 131 132 exit: 133 return res; 134 error: 135 goto exit; 136 } 137 138 static res_T 139 parse_dump_parameter 140 (const char* str, 141 enum htrdr_combustion_args_output_type* output_type) 142 { 143 res_T res = RES_OK; 144 ASSERT(str && output_type); 145 146 if(!strcmp(str, "octree")) { 147 *output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_OCTREES; 148 } else if(!strcmp(str, "laser")) { 149 *output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_LASER_SHEET; 150 } else { 151 fprintf(stderr, "Invalid dump parameter `%s'.\n", str); 152 res = RES_BAD_ARG; 153 goto error; 154 } 155 156 exit: 157 return res; 158 error: 159 goto exit; 160 } 161 162 /******************************************************************************* 163 * Local functions 164 ******************************************************************************/ 165 res_T 166 htrdr_combustion_args_init 167 (struct htrdr_combustion_args* args, 168 int argc, 169 char** argv) 170 { 171 int opt; 172 res_T res = RES_OK; 173 ASSERT(args && argc && argv); 174 175 *args = HTRDR_COMBUSTION_ARGS_DEFAULT; 176 177 while((opt = getopt(argc, argv, "C:D:d:F:fg:hIi:l:m:NO:o:P:p:R:r:sT:t:V:vw:")) != -1) { 178 switch(opt) { 179 case 'C': 180 args->output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE; 181 args->cam_type = HTRDR_ARGS_CAMERA_PERSPECTIVE; 182 res = htrdr_args_camera_perspective_parse(&args->cam_persp, optarg); 183 break; 184 case 'D': 185 res = cstr_to_double(optarg, &args->laser_flux_density); 186 if(res == RES_OK && args->laser_flux_density <= 0) res = RES_BAD_ARG; 187 break; 188 case 'd': 189 res = parse_dump_parameter(optarg, &args->output_type); 190 break; 191 case 'F': 192 res = cstr_parse_list(optarg, ':', parse_fractal_parameters, args); 193 args->phase_func_type = HTRDR_COMBUSTION_ARGS_PHASE_FUNC_RDGFA; 194 break; 195 case 'f': args->force_overwriting = 1; break; 196 case 'g': 197 res = htrdr_args_geometry_parse(&args->geom, optarg); 198 break; 199 case 'h': 200 usage(); 201 htrdr_combustion_args_release(args); 202 args->quit = 1; 203 goto exit; 204 case 'I': 205 args->phase_func_type = HTRDR_COMBUSTION_ARGS_PHASE_FUNC_ISOTROPIC; 206 break; 207 case 'i': 208 res = htrdr_args_image_parse(&args->image, optarg); 209 break; 210 case 'l': 211 res = htrdr_args_rectangle_parse(&args->laser, optarg); 212 break; 213 case 'm': args->path_tetra = optarg; break; 214 case 'N': args->precompute_normals = 1; break; 215 case 'O': args->path_cache = optarg; break; 216 case 'o': args->path_output = optarg; break; 217 case 'p': args->path_therm_props = optarg; break; 218 case 'P': 219 args->output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE; 220 args->cam_type = HTRDR_ARGS_CAMERA_ORTHOGRAPHIC; 221 res = htrdr_args_camera_orthographic_parse(&args->cam_ortho, optarg); 222 break; 223 case 'r': args->path_refract_ids = optarg; break; 224 case 'R': 225 args->output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_FLUX_MAP; 226 res = htrdr_args_rectangle_parse(&args->flux_map, optarg); 227 break; 228 case 's': args->use_simd = 1; break; 229 case 'T': 230 res = cstr_to_double(optarg, &args->optical_thickness); 231 if(res == RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG; 232 break; 233 case 't': /* Submit an hint on the number of threads to use */ 234 res = cstr_to_uint(optarg, &args->nthreads); 235 if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG; 236 break; 237 case 'V': 238 res = parse_grid_definition(&args->grid, optarg); 239 break; 240 case 'v': args->verbose = 1; break; 241 case 'w': 242 res = cstr_to_double(optarg, &args->wavelength); 243 break; 244 default: res = RES_BAD_ARG; break; 245 } 246 if(res != RES_OK) { 247 if(optarg) { 248 fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n", 249 argv[0], optarg, opt); 250 } 251 goto error; 252 } 253 } 254 255 if(!args->path_tetra) { 256 fprintf(stderr, "missing the volumetric mesh -- option '-m'\n"); 257 res = RES_BAD_ARG; 258 goto error; 259 } 260 if(!args->path_therm_props) { 261 fprintf(stderr, "missing the thermodynamic properties -- option '-p'\n"); 262 res = RES_BAD_ARG; 263 goto error; 264 } 265 if(!args->path_refract_ids) { 266 fprintf(stderr, "missing the refractive indices -- option '-r'\n"); 267 res = RES_BAD_ARG; 268 goto error; 269 } 270 271 exit: 272 return res; 273 error: 274 usage(); 275 htrdr_combustion_args_release(args); 276 goto exit; 277 } 278 279 void 280 htrdr_combustion_args_release(struct htrdr_combustion_args* args) 281 { 282 ASSERT(args); 283 htrdr_args_geometry_free(&args->geom); 284 *args = HTRDR_COMBUSTION_ARGS_DEFAULT; 285 } 286