star-phor

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

sphor.c (6070B)


      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 "sphor.h"
     26 #include "sphor_c.h"
     27 #include "sphor_config.h"
     28 #include "sphor_compute_mvrea.h"
     29 
     30 #include <star/sphin.h>
     31 #include <star/s3d.h>
     32 #include <star/ssp.h>
     33 
     34 #include <rsys/logger.h>
     35 #include <rsys/mem_allocator.h>
     36 
     37 #include <errno.h> /* errno and EEXIST */
     38 #include <fcntl.h> /* open */
     39 #include <unistd.h> /* close */
     40 #include <sys/stat.h> /* S_IRUSR & S_IWUSR */
     41 
     42 /*******************************************************************************
     43  * Helper functions
     44  ******************************************************************************/
     45 static res_T
     46 check_sphor_create_args
     47   (const struct sphor_create_args* args)
     48 {
     49   if (NULL == args) {
     50     return RES_BAD_ARG;
     51   }
     52   return RES_OK;
     53 }
     54 
     55 static void
     56 release_sphor
     57   (ref_T* address)
     58 {
     59   struct sphor* sphor = NULL;
     60   ASSERT(NULL != address);
     61 
     62   sphor = CONTAINER_OF(address, struct sphor, ref);
     63   if (NULL != sphor->config) {
     64     sphin_config_ref_put(sphor->config);
     65   }
     66   if (NULL != sphor->scene_view) {
     67     s3d_scene_view_ref_put(sphor->scene_view);
     68   }
     69   if (NULL != sphor->source_distrib_power) {
     70     ssp_ranst_discrete_ref_put(sphor->source_distrib_power);
     71   }
     72   if (NULL != sphor->stream) { fclose(sphor->stream); }
     73   darray_interface_release(&sphor->interfaces);
     74   darray_source_view_release(&sphor->source_views);
     75   MEM_RM(sphor->allocator, sphor);
     76 }
     77 
     78 /*******************************************************************************
     79  * Local functions
     80  ******************************************************************************/
     81 FILE*
     82 open_output_stream
     83   (const struct sphor_create_args* args,
     84    const struct sphor* sphor)
     85 {
     86   FILE* fp = NULL;
     87   int fd = -1;
     88 
     89   if (args->force) {
     90     fp = fopen(args->output_filename, "w");
     91     if (NULL == fp) {
     92       ERROR
     93         (sphor, "Could not open output file `%s'\n", args->output_filename);
     94       goto error;
     95     }
     96   } else {
     97     fd = open
     98       (args->output_filename,
     99        O_CREAT | O_EXCL | O_TRUNC | O_WRONLY,
    100        S_IRUSR | S_IWUSR);
    101     if (fd >= 0) {
    102       fp = fdopen(fd, "w");
    103       if (NULL == fp) {
    104         ERROR
    105           (sphor, "Could not open output file `%s'\n", args->output_filename);
    106         goto error;
    107       }
    108     } else if (errno == EEXIST) {
    109         ERROR
    110           (sphor, "The output file `%s' already exists'\n",
    111            args->output_filename);
    112         goto error;
    113     } else {
    114         ERROR
    115           (sphor,
    116            "Unexpected error while opening output file `%s'\n",
    117            args->output_filename);
    118         goto error;
    119     }
    120   }
    121 
    122 exit:
    123   return fp;
    124 error:
    125   if (NULL != fp) {
    126     fclose(fp);
    127     fp = NULL;
    128   } else if (fd >= 0) {
    129     close(fd);
    130   }
    131   goto exit;
    132 }
    133 
    134 /*******************************************************************************
    135  * Exported functions
    136  ******************************************************************************/
    137 res_T
    138 sphor_create
    139   (const struct sphor_create_args* args,
    140    struct sphor** out_sphor)
    141 {
    142   struct mem_allocator* allocator = NULL;
    143   struct sphor* sphor = NULL;
    144   res_T res = RES_OK;
    145 
    146   if (NULL == out_sphor) {
    147     res = RES_BAD_ARG;
    148     goto error;
    149   }
    150   res = check_sphor_create_args(args);
    151   if (RES_OK != res) goto error;
    152 
    153   if (NULL == args->allocator) {
    154     allocator = &mem_default_allocator;
    155   } else {
    156     allocator = args->allocator;
    157   }
    158   sphor = MEM_CALLOC(allocator, 1, sizeof(struct sphor));
    159   if (NULL == sphor) {
    160     res = RES_MEM_ERR;
    161     goto error;
    162   }
    163   ref_init(&sphor->ref);
    164   sphor->verbose = args->verbose;
    165   sphor->allocator = allocator;
    166   sphor->nthreads = args->nthreads;
    167   sphor->samples = args->samples;
    168   if (NULL == args->logger) {
    169     sphor->logger = LOGGER_DEFAULT;
    170   } else {
    171     sphor->logger = args->logger;
    172   }
    173   darray_interface_init(sphor->allocator, &sphor->interfaces);
    174   darray_source_view_init(sphor->allocator, &sphor->source_views);
    175 
    176   if (NULL != args->output_filename){
    177     sphor->stream = open_output_stream(args, sphor);
    178     if (NULL == sphor->stream) { goto error; }
    179   } else { sphor->stream = stdout; }
    180 
    181   /* Load the system and build data structure for Monte Carlo */
    182   res = setup_config(sphor, args);
    183   if (RES_OK != res) { goto error; }
    184 
    185 exit:
    186   if (NULL != out_sphor) *out_sphor = sphor;
    187   return res;
    188 error:
    189   if (NULL != sphor) {
    190     SPHOR(ref_put(sphor)); /* <=> ASSERT(sphor_ref_put(sphor) == RES_OK) */
    191     sphor = NULL;
    192   }
    193   goto exit;
    194 }
    195 
    196 res_T
    197 sphor_ref_get(struct sphor* sphor)
    198 {
    199   if (NULL == sphor) {
    200     return RES_BAD_ARG;
    201   }
    202   ref_get(&sphor->ref);
    203   return RES_OK;
    204 }
    205 
    206 res_T
    207 sphor_ref_put(struct sphor* sphor)
    208 {
    209   if (NULL == sphor) {
    210     return RES_BAD_ARG;
    211   }
    212   ref_put(&sphor->ref, release_sphor);
    213   return RES_OK;
    214 }
    215 
    216 res_T
    217 sphor_run(struct sphor* sphor)
    218 {
    219   res_T res = RES_OK;
    220 
    221   if (NULL == sphor) { goto error; }
    222 
    223   res = sphor_compute_MVREA(sphor);
    224   if (RES_OK != res) { goto error; }
    225 
    226 exit:
    227   return res;
    228 error:
    229   goto exit;
    230 }