star-phor

Radiative transfer solver for photoreactors.
git clone https://www.edstar.cnrs.fr/git/star-phor.git
Log | Files | Refs | README | LICENSE

sphor_main.c (5542B)


      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 #define _POSIX_C_SOURCE 200112L /* for getopt support */
     26 
     27 #include "sphor.h"
     28 
     29 #include <rsys/cstr.h>
     30 #include <rsys/mem_allocator.h>
     31 #include <rsys/rsys.h>
     32 
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <unistd.h>
     36 
     37 struct args {
     38   int verbose; /* Verbosity level. Bigger values => more verbosity */
     39   int quit; /* Either stop (1) or continue (0) the execution */
     40   unsigned nthreads; /* hint: number of threads; defaults to all available
     41                         threads in the computer */
     42   size_t samples; /* number of realisations used during the Monte Carlo
     43                      integrating algorithm */
     44   char* input_filename; /* May be NULL <=> uses stdin */
     45   char* output_filename; /* May be NULL <=> uses stdout */
     46   int force; /* Either force overwriting (1) or return an error (0)
     47                 if the output file already exists */
     48 };
     49 
     50 #define ARGS_DEFAULT__ {0, 0, UINT_MAX, 10000, NULL, NULL, 0}
     51 
     52 static const struct args ARGS_DEFAULT =
     53   ARGS_DEFAULT__;
     54 
     55 static void
     56 usage(FILE* stream)
     57 {
     58   ASSERT(NULL != stream);
     59   fprintf(stream,
     60     "Usage: star-phor [-hvf] [-n samples] [-o output] [-t threads] [file]\n");
     61 }
     62 
     63 static res_T
     64 parse_args
     65   (struct args* args,
     66    int argc,
     67    char** argv)
     68 {
     69   unsigned long nreal;
     70   unsigned int nthreads;
     71   int opt = 0;
     72   char* arglist = "hfn:o:t:v";
     73   res_T res = RES_OK;
     74 
     75   ASSERT(NULL != args);
     76   ASSERT(NULL != argv);
     77   ASSERT(argc > 0);
     78 
     79   *args = ARGS_DEFAULT;
     80 
     81   while((opt = getopt(argc, argv, arglist)) != -1) {
     82     switch(opt) {
     83       case 'h':
     84         usage(stdout);
     85         args->quit = 1;
     86         break;
     87       /* Verbosity level */
     88       case 'v':
     89         /* Increase the verbosity level counter for each 'v' entered, up to a
     90          * maximum of 3.  We use the boolean value of (3 > args->verbose): if
     91          * the condition is true, it evaluates to 1, increasing the counter.
     92          * Otherwise, it evaluates to 0, leaving the counter unchanged. */
     93         args->verbose += (3 > args->verbose);
     94         break;
     95       /* Output filename */
     96       case 'o':
     97         args->output_filename = optarg;
     98         break;
     99       /* Force overwrite */
    100       case 'f':
    101         args->force = 1;
    102         break;
    103       /* Number of samples */
    104       case 'n':
    105         res = cstr_to_ulong(optarg, &nreal);
    106         if (res == RES_OK && nreal == 0) res = RES_BAD_ARG;
    107         args->samples = (size_t)nreal;
    108         break;
    109       /* Number of threads */
    110       case 't':
    111         res = cstr_to_uint(optarg, &nthreads);
    112         if (res == RES_OK && nthreads == 0) res = RES_BAD_ARG;
    113         args->nthreads = nthreads;
    114         break;
    115       default:
    116         res = RES_BAD_ARG;
    117         break;
    118     }
    119     if (RES_OK != res) {
    120       if (NULL != optarg) {
    121         fprintf(stderr, "Invalid option argument: %s -- %c\n", optarg, opt);
    122       }
    123       goto error;
    124     }
    125   }
    126 
    127   /* optind is a global variable that indexes the next argv to be processed */
    128   if (optind < argc) { /* True if not all the args have been processed */
    129     args->input_filename = argv[optind];
    130   }
    131 
    132 exit:
    133   return res;
    134 error:
    135   usage(stderr);
    136   goto exit;
    137 }
    138 
    139 int
    140 main (int argc, char** argv)
    141 {
    142   struct sphor* sphor = NULL;
    143   struct args args = ARGS_DEFAULT;
    144   struct sphor_create_args sphor_create_args = SPHOR_CREATE_ARGS_DEFAULT;
    145   size_t sz = 0;
    146   int err = EXIT_SUCCESS;
    147   res_T res = RES_OK;
    148 
    149   /* Process command line args */
    150   res = parse_args(&args, argc, argv);
    151   if (RES_OK != res) { goto error; }
    152   if (0 != args.quit) { goto exit; }
    153 
    154   /* Create sphor struct */
    155   sphor_create_args.verbose = args.verbose;
    156   sphor_create_args.samples = args.samples;
    157   sphor_create_args.nthreads = args.nthreads;
    158   sphor_create_args.force = args.force;
    159   sphor_create_args.input_filename = args.input_filename;
    160   sphor_create_args.output_filename = args.output_filename;
    161 
    162   res = sphor_create(&sphor_create_args, &sphor);
    163   if (RES_OK != res) { goto error; }
    164 
    165   /* Run simulation */
    166   res = sphor_run(sphor);
    167   if (RES_OK != res) { goto error; }
    168 
    169 exit:
    170   if (NULL != sphor) { SPHOR(ref_put(sphor)); }
    171   sz = mem_allocated_size();
    172   if (sz != 0) {
    173     char buffer[64] = {0}; /* Initialize all fields to 0 */
    174     size_to_cstr(sz, SIZE_ALL, NULL, buffer, sizeof(buffer));
    175     fprintf(stderr, "Memory leaks: %s\n", buffer);
    176     err = EXIT_FAILURE;
    177   }
    178   return err;
    179 error:
    180   err = EXIT_FAILURE;
    181   goto exit;
    182 }