htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

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