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_atmosphere.c (4273B)


      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_atmosphere
     27   (struct solparser* parser,
     28    yaml_document_t* doc,
     29    yaml_node_t* atm,
     30    struct solparser_atmosphere** out_solatm)
     31 {
     32   enum { EXTINCTION };
     33   struct solparser_atmosphere* solatm = NULL;
     34   int mask = 0; /* Register the parsed attributes */
     35   intptr_t i, n;
     36   res_T res = RES_OK;
     37   ASSERT(doc && atm && out_solatm);
     38 
     39   if(atm == parser->atmosphere_key) {
     40     solatm = &parser->atmosphere;
     41     goto exit;
     42   } else if(parser->atmosphere_key != 0) {
     43     log_err(parser, atm,
     44       "an atmosphere is already defined. Previous definition is here %lu:%lu.\n",
     45       (unsigned long)parser->atmosphere_key->start_mark.line + 1,
     46       (unsigned long)parser->atmosphere_key->start_mark.column + 1);
     47     res = RES_BAD_ARG;
     48     goto error;
     49   } else {
     50     solatm = &parser->atmosphere;
     51     parser->atmosphere_key = atm;
     52   }
     53 
     54   if(atm->type != YAML_MAPPING_NODE) {
     55     log_err(parser, atm, "expect a mapping of atmosphere attributes.\n");
     56     res = RES_BAD_ARG;
     57     goto error;
     58   }
     59 
     60   n = atm->data.mapping.pairs.top - atm->data.mapping.pairs.start;
     61   FOR_EACH(i, 0, n) {
     62     yaml_node_t* key;
     63     yaml_node_t* val;
     64 
     65     key = yaml_document_get_node(doc, atm->data.mapping.pairs.start[i].key);
     66     val = yaml_document_get_node(doc, atm->data.mapping.pairs.start[i].value);
     67     if(key->type != YAML_SCALAR_NODE) {
     68       log_err(parser, key, "expect an atmosphere parameter.\n");
     69       res = RES_BAD_ARG;
     70       goto error;
     71     }
     72     #define SETUP_MASK(Flag, Name) {                                           \
     73       if(mask & BIT(Flag)) {                                                   \
     74          log_err(parser, key,                                                  \
     75            "the "Name" of the atmosphere is already defined.\n");              \
     76          res = RES_BAD_ARG;                                                    \
     77          goto error;                                                           \
     78       }                                                                        \
     79       mask |= BIT(Flag);                                                       \
     80     } (void)0
     81     if(!strcmp((char*)key->data.scalar.value, "extinction")) {
     82       SETUP_MASK(EXTINCTION, "extinction");
     83       res = parse_mtl_data
     84         (parser, doc, val, 0, 1, &solatm->extinction);
     85     } else {
     86       log_err(parser, key, "unknown atmosphere parameter `%s'.\n",
     87         key->data.scalar.value);
     88       res = RES_BAD_ARG;
     89       goto error;
     90     }
     91     if(res != RES_OK) {
     92       log_node(parser, key);
     93       goto error;
     94     }
     95     #undef SETUP_MASK
     96   }
     97 
     98   #define CHECK_PARAM(Flag, Name)                                              \
     99   if(!(mask & BIT(Flag))) {                                                    \
    100     log_err(parser, atm, "the "Name" of the atmosphere is missing.\n");        \
    101     res = RES_BAD_ARG;                                                         \
    102     goto error;                                                                \
    103   } (void)0
    104   CHECK_PARAM(EXTINCTION, "extinction");
    105   #undef CHECK_PARAM
    106 
    107 exit:
    108   *out_solatm = solatm;
    109   return res;
    110 error:
    111   if(solatm) {
    112     solparser_atmosphere_clear(solatm);
    113     solatm = NULL;
    114     parser->atmosphere_key = 0;
    115   }
    116   solatm = NULL;
    117   goto exit;
    118 }
    119