atrstm

Load and structure a combustion gas mixture
git clone git://git.meso-star.fr/atrstm.git
Log | Files | Refs | README | LICENSE

test_atrstm.c (8649B)


      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.h"
     18 
     19 #include <rsys/cstr.h>
     20 #include <rsys/mem_allocator.h>
     21 #include <rsys/rsys.h>
     22 
     23 #include <getopt.h>
     24 #include <stdio.h>
     25 #include <string.h>
     26 
     27 struct args {
     28   struct atrstm_args atrstm;
     29   const char* dump_octree_filename; /* NULL <=> no dump */
     30   int quit;
     31 };
     32 
     33 #define ARGS_DEFAULT__ { ATRSTM_ARGS_DEFAULT__, NULL, 0 }
     34 static const struct args ARGS_DEFAULT = ARGS_DEFAULT__;
     35 
     36 /*******************************************************************************
     37  * Helper functions
     38  ******************************************************************************/
     39 static void
     40 print_help(const char* cmd)
     41 {
     42   ASSERT(cmd);
     43   printf(
     44 "Usage: %s <option>...\n"
     45 "Test the Astoria: Semi-Transparent Medium library.\n",
     46     cmd);
     47   printf("\n");
     48   printf(
     49 "  -d OCTREE      dump SVX octree to the OCTREE file.\n");
     50   printf(
     51 "  -f FRACTAL_DIM fractal dimension. Its default value is %g.\n",
     52     ATRSTM_ARGS_DEFAULT.fractal_dimension);
     53   printf(
     54 "  -g PREFACTOR   fractal prefactor. Its default value is %g.\n",
     55     ATRSTM_ARGS_DEFAULT.fractal_prefactor);
     56   printf(
     57 "  -h             display this help and exit.\n");
     58   printf(
     59 "  -m TETRAHEDRA  path toward the volumetric mesh.\n");
     60   printf(
     61 "  -N             precompute the tetrahedra normals.\n");
     62   printf(
     63 "  -n NAME        name of the medium. Default is \"%s\".\n",
     64     ATRSTM_ARGS_DEFAULT.name);
     65   printf(
     66 "  -O CACHE       name of the cache file to use/fill. By default\n"
     67 "                 no cache is used\n");
     68   printf(
     69 "  -p THERMOPROPS path toward the thermodynamic properties.\n");
     70   printf(
     71 "  -r REFRACT_ID  path toward the per wavelength refractive\n"
     72 "                 indices.\n");
     73   printf(
     74 "  -T THRESHOLD   optical thickness used as threshold during the octree\n"
     75 "                 building. By default its value is %g.\n",
     76     ATRSTM_ARGS_DEFAULT.optical_thickness);
     77   printf(
     78 "  -t NTHREADS    hint on the number of threads to use. By default use\n"
     79 "                 as many threads as CPU cores.\n");
     80   printf(
     81 "  -V <DEFINITION|X,Y,Z>\n"
     82 "                 maximum definition of the acceleration grids\n"
     83 "                 along the 3 axis. Its default value is [%u, %u, %u].\n",
     84     SPLIT3(ATRSTM_ARGS_DEFAULT.grid_max_definition));
     85   printf(
     86 "  -v             make the program verbose.\n");
     87   printf(
     88 "  -w WAVELENGTH  shortwave wavelength to use, in nanometer.\n"
     89 "                 By default it is set to %g nm\n",
     90     ATRSTM_ARGS_DEFAULT.wlen_range[0]);
     91   printf("\n");
     92   printf(
     93 "This is free software released under the GNU GPL license, version 3 or\n"
     94 "later. You are free to change or redistribute it under certain\n"
     95 "conditions <http://gnu.org.licenses/gpl.html>\n");
     96 }
     97 
     98 static res_T
     99 parse_grid_definition(struct atrstm_args* args, const char* str)
    100 {
    101   unsigned def[3];
    102   size_t len;
    103   res_T res = RES_OK;
    104   ASSERT(args && str);
    105 
    106   res = cstr_to_list_uint(str, ',', def, &len, 3);
    107   if(res == RES_OK && len == 2) res = RES_OK;
    108   if(res != RES_OK) {
    109     fprintf(stderr, "Invalid grid definition `%s'.\n", str);
    110     goto error;
    111   }
    112 
    113   if(len == 1) {
    114     if(!def[0]) {
    115       fprintf(stderr, "Invalid null grid definition %u.\n", def[0]);
    116       res = RES_BAD_ARG;
    117       goto error;
    118     }
    119     args->auto_grid_definition = 1;
    120     args->auto_grid_definition_hint = def[0];
    121 
    122   } else {
    123     if(!def[0] || !def[1] || !def[2]) {
    124       fprintf(stderr,
    125         "Invalid null grid definition [%u, %u, %u].\n", SPLIT3(def));
    126       res = RES_BAD_ARG;
    127       goto error;
    128     }
    129     args->auto_grid_definition = 0;
    130     args->grid_max_definition[0] = def[0];
    131     args->grid_max_definition[1] = def[1];
    132     args->grid_max_definition[2] = def[2];
    133   }
    134 
    135 exit:
    136   return res;
    137 error:
    138   goto exit;
    139 }
    140 
    141 static void
    142 args_release(struct args* args)
    143 {
    144   ASSERT(args);
    145   *args = ARGS_DEFAULT;
    146 }
    147 
    148 static res_T
    149 args_init(struct args* args, int argc, char** argv)
    150 {
    151   res_T res = RES_OK;
    152   int opt;
    153   ASSERT(args && argc && argv);
    154 
    155   *args = ARGS_DEFAULT;
    156 
    157   while((opt = getopt(argc, argv, "d:f:g:hm:Nn:O:p:T:t:r:vV:w:")) != -1) {
    158     switch(opt) {
    159       case 'd': args->dump_octree_filename = optarg; break;
    160       case 'f':
    161         res = cstr_to_double(optarg, &args->atrstm.fractal_dimension);
    162         if(res == RES_OK && args->atrstm.fractal_dimension <= 0)
    163           res = RES_BAD_ARG;
    164         break;
    165       case 'g':
    166         res = cstr_to_double(optarg, &args->atrstm.fractal_prefactor);
    167         if(res == RES_OK && args->atrstm.fractal_prefactor <= 0)
    168           res = RES_BAD_ARG;
    169         break;
    170       case 'h':
    171         print_help(argv[0]);
    172         args_release(args);
    173         args->quit = 1;
    174         goto exit;
    175       case 'm': args->atrstm.sth_filename = optarg; break;
    176       case 'N': args->atrstm.precompute_normals = 1; break;
    177       case 'n': args->atrstm.name = optarg; break;
    178       case 'O': args->atrstm.cache_filename = optarg; break;
    179       case 'p': args->atrstm.atrtp_filename = optarg; break;
    180       case 'r': args->atrstm.atrri_filename = optarg; break;
    181       case 'T':
    182         res = cstr_to_double(optarg, &args->atrstm.optical_thickness);
    183         if(res == RES_OK && args->atrstm.optical_thickness<0) res = RES_BAD_ARG;
    184         break;
    185       case 't':
    186         res = cstr_to_uint(optarg, &args->atrstm.nthreads);
    187         if(res == RES_OK && !args->atrstm.nthreads) res = RES_BAD_ARG;
    188         break;
    189       case 'V': res = parse_grid_definition(&args->atrstm, optarg); break;
    190       case 'v': args->atrstm.verbose = 1; break;
    191       case 'w':
    192         res = cstr_to_double(optarg, &args->atrstm.wlen_range[0]);
    193         if(res == RES_OK && args->atrstm.wlen_range[0] < 0) res = RES_BAD_ARG;
    194         args->atrstm.wlen_range[1] = args->atrstm.wlen_range[0];
    195         break;
    196       default: res = RES_BAD_ARG; break;
    197     }
    198     if(res != RES_OK) {
    199       if(optarg) {
    200         fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n",
    201           argv[0], optarg, opt);
    202       }
    203       goto error;
    204     }
    205   }
    206 
    207   /* Check parsed arguments */
    208   if(!args->atrstm.sth_filename) {
    209     fprintf(stderr,
    210       "Missing the path toward the volumetric mesh -- option '-m'\n");
    211     res = RES_BAD_ARG;
    212     goto error;
    213   }
    214   if(!args->atrstm.atrtp_filename) {
    215     fprintf(stderr,
    216       "Missing the path of the thermodynamic properties -- option '-p'\n");
    217     res = RES_BAD_ARG;
    218     goto error;
    219   }
    220   if(!args->atrstm.atrri_filename) {
    221     fprintf(stderr,
    222       "Missing the path of the refractive indices -- option '-r'\n");
    223     res = RES_BAD_ARG;
    224     goto error;
    225   }
    226 
    227 exit:
    228   return res;
    229 error:
    230   args_release(args);
    231   goto exit;
    232 }
    233 
    234 /*******************************************************************************
    235  * Main function
    236  ******************************************************************************/
    237 int
    238 main(int argc, char** argv)
    239 {
    240   struct args args = ARGS_DEFAULT;
    241   struct atrstm* atrstm = NULL;
    242   FILE* fp_octree = NULL; 
    243   res_T res = RES_OK;
    244   int err = 0;
    245 
    246   res = args_init(&args, argc, argv);
    247   if(res != RES_OK) goto error;
    248   if(args.quit) goto exit;
    249 
    250   res = atrstm_create(NULL, &mem_default_allocator, &args.atrstm, &atrstm);
    251   if(res != RES_OK) goto error;
    252 
    253   if(args.dump_octree_filename) {
    254     const struct atrstm_dump_svx_octree_args dump_svx_octree_args = 
    255       ATRSTM_DUMP_SVX_OCTREE_ARGS_DEFAULT;
    256 
    257     fp_octree = fopen(args.dump_octree_filename, "w");
    258     if(!fp_octree) {
    259       fprintf(stderr, "Could not open `%s' -- %s.",
    260         args.dump_octree_filename, strerror(errno));
    261       res = RES_IO_ERR;
    262       goto error;
    263     }
    264 
    265     res = atrstm_dump_svx_octree(atrstm, &dump_svx_octree_args, fp_octree);
    266     if(res != RES_OK) goto error;
    267   }
    268 
    269 exit:
    270   args_release(&args);
    271   if(atrstm) ATRSTM(ref_put(atrstm));
    272   if(fp_octree) fclose(fp_octree);
    273   if(MEM_ALLOCATED_SIZE(&mem_default_allocator) != 0) {
    274     fprintf(stderr, "Memory leaks: %lu bytes\n", 
    275       (unsigned long)MEM_ALLOCATED_SIZE(&mem_default_allocator));
    276     err = -1;
    277   }
    278   return err;
    279 error:
    280   err = -1;
    281   goto exit;
    282 }