solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

solparser_medium.c (4782B)


      1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2016-2018 CNRS
      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 #define _POSIX_C_SOURCE 200112L /* nextafter support */
     18 
     19 #include "solparser_c.h"
     20 #include <math.h> /* nextafter */
     21 
     22 /*******************************************************************************
     23  * Local function
     24  ******************************************************************************/
     25 res_T
     26 parse_medium
     27   (struct solparser* parser,
     28    yaml_document_t* doc,
     29    yaml_node_t* medium,
     30    struct solparser_medium_id* out_imedium)
     31 {
     32   enum { EXTINCTION, REFRACTIVE_INDEX };
     33   struct solparser_medium* mdm = NULL;
     34   size_t* pimedium = NULL;
     35   size_t imedium = SIZE_MAX;
     36   int mask = 0; /* Register the parsed attributes */
     37   intptr_t i, n;
     38   res_T res = RES_OK;
     39   ASSERT(doc && medium && out_imedium);
     40 
     41   if(medium->type != YAML_MAPPING_NODE) {
     42     log_err(parser, medium, "expect a mapping of medium attributes.\n");
     43     res = RES_BAD_ARG;
     44     goto error;
     45   }
     46 
     47   /* Check whether or not the YAML medium alias an already created Solstice
     48    * medium */
     49   pimedium = htable_yaml2sols_find(&parser->yaml2mediums, &medium);
     50   if(pimedium) {
     51     imedium = *pimedium;
     52     goto exit;
     53   }
     54 
     55   /* Allocate the medium */
     56   imedium = darray_medium_size_get(&parser->mediums);
     57   res = darray_medium_resize(&parser->mediums, imedium + 1);
     58   if(res != RES_OK) {
     59     log_err(parser, medium, "could not allocate the medium.\n");
     60     res = RES_BAD_ARG;
     61     goto error;
     62   }
     63   mdm = darray_medium_data_get(&parser->mediums) + imedium;
     64 
     65   n = medium->data.mapping.pairs.top - medium->data.mapping.pairs.start;
     66   FOR_EACH(i, 0, n) {
     67     yaml_node_t* key;
     68     yaml_node_t* val;
     69 
     70     key = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].key);
     71     val = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].value);
     72     if(key->type != YAML_SCALAR_NODE) {
     73       log_err(parser, key, "expect a medium parameter.\n");
     74       res = RES_BAD_ARG;
     75       goto error;
     76     }
     77     #define SETUP_MASK(Flag, Name) {                                           \
     78       if(mask & BIT(Flag)) {                                                   \
     79          log_err(parser, key,"the "Name" of the medium is already defined.\n");\
     80          res = RES_BAD_ARG;                                                    \
     81          goto error;                                                           \
     82       }                                                                        \
     83       mask |= BIT(Flag);                                                       \
     84     } (void)0
     85     if(!strcmp((char*)key->data.scalar.value, "extinction")) {
     86       SETUP_MASK(EXTINCTION, "extinction");
     87       res = parse_mtl_data(parser, doc, val, 0, DBL_MAX, &mdm->extinction);
     88     } else if(!strcmp((char*)key->data.scalar.value, "refractive_index")) {
     89       SETUP_MASK(REFRACTIVE_INDEX, "refractive_index");
     90       res = parse_mtl_data
     91         (parser, doc, val, nextafter(0, 1), DBL_MAX, &mdm->refractive_index);
     92     } else {
     93       log_err(parser, key, "unknown medium parameter `%s'.\n",
     94         key->data.scalar.value);
     95       res = RES_BAD_ARG;
     96       goto error;
     97     }
     98     if(res != RES_OK) {
     99       log_node(parser, key);
    100       goto error;
    101     }
    102     #undef SETUP_MASK
    103   }
    104 
    105   #define CHECK_PARAM(Flag, Name)                                              \
    106   if(!(mask & BIT(Flag))) {                                                    \
    107     log_err(parser, medium, "the "Name" of the medium is missing.\n");         \
    108     res = RES_BAD_ARG;                                                         \
    109     goto error;                                                                \
    110   } (void)0
    111   CHECK_PARAM(EXTINCTION, "absorption");
    112   CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index");
    113   #undef CHECK_PARAM
    114 
    115   /* Cache the medium */
    116   res = htable_yaml2sols_set(&parser->yaml2mediums, &medium, &imedium);
    117   if(res != RES_OK) {
    118     log_err(parser, medium, "could not register the medium.\n");
    119     goto error;
    120   }
    121 
    122 exit:
    123   out_imedium->i = imedium;
    124   return res;
    125 error:
    126   if(imedium) {
    127     darray_medium_pop_back(&parser->mediums);
    128     imedium = SIZE_MAX;
    129   }
    130   goto exit;
    131 }
    132