solstice

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

commit 46552ba425acb9d9be534d66301bbb9b92482f07
parent 5aa6d008e2228d1a01de1b5befbbf899fa6c769c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 19 Apr 2017 14:26:09 +0200

Add medium to the list of first level items in the YAML format

Diffstat:
Mcmake/parser/CMakeLists.txt | 3++-
Mdoc/input | 23++++++++++++++---------
Msrc/parser/solparser.c | 20++++++++++++++++----
Msrc/parser/solparser_c.h | 15+++++++++++++--
Msrc/parser/solparser_material.c | 92-------------------------------------------------------------------------------
Msrc/parser/solparser_material.h | 8+-------
Asrc/parser/solparser_medium.c | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/parser/solparser_medium.h | 29+++++++++++++++++++++++++++++
Msrc/parser/test_solparser8.c | 14++++++--------
Msrc/parser/yaml/test_ok_7.yaml | 13+++++++++++++
10 files changed, 225 insertions(+), 123 deletions(-)

diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -35,6 +35,7 @@ set(SOLPARSER_FILES_SRC solparser_image.c solparser_geometry.c solparser_material.c + solparser_medium.c solparser_pivot.c solparser_sun.c solparser_spectrum.c) @@ -45,6 +46,7 @@ set(SOLPARSER_FILES_INC solparser_geometry.h solparser_image.h solparser_material.h + solparser_medium.h solparser_pivot.h solparser_shape.h solparser_sun.h @@ -110,4 +112,3 @@ if(NOT NO_TEST) rcmake_copy_runtime_libraries(test_solparser) endif() - diff --git a/doc/input b/doc/input @@ -91,6 +91,7 @@ <item> ::= <geometry> | <material> + | <medium> | <entity> | <template> @@ -212,7 +213,7 @@ #---------------------------------------- <material> ::= - <material-descriptor> | <double-sided-material> + material: <material-descriptor> | <double-sided-material> <double-sided-material> ::= front: <material-descriptor> @@ -223,8 +224,8 @@ <dielectric> ::= dielectric: - medium_i: <dielectric-medium> - medium_t: <dielectric-medium> + medium_i: <medium-descriptor> + medium_t: <medium-descriptor> [ <normal-map> ] <matte> ::= @@ -244,18 +245,22 @@ <thin-dielectric> ::= thin_dielectric: thickness: REAL # in [0, INF) - medium_i: <dielectric-medium> - medium_t: <dielectric-medium> + medium_i: <medium-descriptor> + medium_t: <medium-descriptor> [ <normal-map> ] -<dielectric-medium> ::= - refractive_index: REAL # in ]0, INF) - absorptivity: REAL # in [0, INF) - <normal-map> ::= normal_map: { path: PATH } #---------------------------------------- +<medium> ::= + medium: <medium-descriptor> + +<medium-descriptor> ::= + refractive_index: REAL # in ]0, INF) + absorptivity: REAL # in [0, INF) + +#---------------------------------------- <entity> ::= entity: <entity-data> diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -114,9 +114,10 @@ parse_item const yaml_node_t* item) { /* Temporary dummy variables */ - struct solparser_material_double_sided_id mtl2; struct solparser_entity_id entity; struct solparser_geometry_id geometry; + struct solparser_material_double_sided_id mtl2; + struct solparser_medium_id medium; struct solparser_sun* sun; yaml_node_t* key; @@ -149,6 +150,8 @@ parse_item if(!strcmp((char*)key->data.scalar.value, "material")) { res = parse_material(parser, doc, val, &mtl2); + } else if(!strcmp((char*)key->data.scalar.value, "medium")) { + res = parse_medium(parser, doc, val, &medium); } else if(!strcmp((char*)key->data.scalar.value, "entity")) { res = parse_entity(parser, doc, val, &parser->str2entities, &entity); if(res == RES_OK) { @@ -189,12 +192,15 @@ parser_clear(struct solparser* parser) darray_image_clear(&parser->images); darray_material_clear(&parser->mtls); darray_material2_clear(&parser->mtls2); - darray_medium_clear(&parser->mediums); darray_dielectric_clear(&parser->dielectrics); darray_matte_clear(&parser->mattes); darray_mirror_clear(&parser->mirrors); darray_thin_dielectric_clear(&parser->thin_dielectrics); + /* Mediums */ + htable_yaml2sols_clear(&parser->yaml2mediums); + darray_medium_clear(&parser->mediums); + /* Deferred targeted anchors */ darray_tgtalias_clear(&parser->tgtaliases); @@ -244,12 +250,15 @@ parser_release(ref_T* ref) darray_image_release(&parser->images); darray_material_release(&parser->mtls); darray_material2_release(&parser->mtls2); - darray_medium_release(&parser->mediums); darray_dielectric_release(&parser->dielectrics); darray_matte_release(&parser->mattes); darray_mirror_release(&parser->mirrors); darray_thin_dielectric_release(&parser->thin_dielectrics); + /* Mediums */ + htable_yaml2sols_release(&parser->yaml2mediums); + darray_medium_release(&parser->mediums); + /* Deferred targeted anchors */ darray_tgtalias_release(&parser->tgtaliases); @@ -573,12 +582,15 @@ solparser_create darray_image_init(mem_allocator, &parser->images); darray_material_init(mem_allocator, &parser->mtls); darray_material2_init(mem_allocator, &parser->mtls2); - darray_medium_init(mem_allocator, &parser->mediums); darray_dielectric_init(mem_allocator, &parser->dielectrics); darray_matte_init(mem_allocator, &parser->mattes); darray_mirror_init(mem_allocator, &parser->mirrors); darray_thin_dielectric_init(mem_allocator, &parser->thin_dielectrics); + /* Mediums */ + htable_yaml2sols_init(mem_allocator, &parser->yaml2mediums); + darray_medium_init(mem_allocator, &parser->mediums); + /* Deferred targeted anchors */ darray_tgtalias_init(mem_allocator, &parser->tgtaliases); diff --git a/src/parser/solparser_c.h b/src/parser/solparser_c.h @@ -20,6 +20,7 @@ #include "solparser_entity.h" #include "solparser_image.h" #include "solparser_material.h" +#include "solparser_medium.h" #include "solparser_pivot.h" #include "solparser_shape.h" #include "solparser_sun.h" @@ -204,17 +205,20 @@ struct solparser { struct str stream_name; int parser_is_init; - /* Materia data */ + /* Material */ struct htable_yaml2sols yaml2mtls; /* Cache of materials */ struct darray_image images; struct darray_material mtls; struct darray_material2 mtls2; /* Double sided materials */ - struct darray_medium mediums; struct darray_dielectric dielectrics; struct darray_matte mattes; struct darray_mirror mirrors; struct darray_thin_dielectric thin_dielectrics; + /* Medium */ + struct htable_yaml2sols yaml2mediums; /* Cache of mediums */ + struct darray_medium mediums; + /* Use to deferred the setup of the anchor targeted by a pivot */ struct darray_tgtalias tgtaliases; @@ -379,6 +383,13 @@ parse_material struct solparser_material_double_sided_id* out_imtl2); extern LOCAL_SYM res_T +parse_medium + (struct solparser* parser, + yaml_document_t* doc, + yaml_node_t* medium, + struct solparser_medium_id* out_imedium); + +extern LOCAL_SYM res_T parse_spectrum (struct solparser* parser, yaml_document_t* doc, diff --git a/src/parser/solparser_material.c b/src/parser/solparser_material.c @@ -22,98 +22,6 @@ * Helper functions ******************************************************************************/ static res_T -parse_medium - (struct solparser* parser, - yaml_document_t* doc, - const yaml_node_t* medium, - struct solparser_medium_id* out_imedium) -{ - enum { ABSORPTIVITY, REFRACTIVE_INDEX }; - struct solparser_medium* mdm = NULL; - size_t imedium = SIZE_MAX; - int mask = 0; /* Register the parsed attributes */ - intptr_t i, n; - res_T res = RES_OK; - ASSERT(doc && medium && out_imedium); - - if(medium->type != YAML_MAPPING_NODE) { - log_err(parser, medium, "expect a mapping of medium attributes.\n"); - res = RES_BAD_ARG; - goto error; - } - - /* Allocate the medium */ - imedium = darray_medium_size_get(&parser->mediums); - res = darray_medium_resize(&parser->mediums, imedium + 1); - if(res != RES_OK) { - log_err(parser, medium, "could not allocate the medium.\n"); - res = RES_BAD_ARG; - goto error; - } - mdm = darray_medium_data_get(&parser->mediums) + imedium; - - n = medium->data.mapping.pairs.top - medium->data.mapping.pairs.start; - FOR_EACH(i, 0, n) { - yaml_node_t* key; - yaml_node_t* val; - - key = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].key); - val = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].value); - if(key->type != YAML_SCALAR_NODE) { - log_err(parser, key, "expect a medium parameter.\n"); - res = RES_BAD_ARG; - goto error; - } - #define SETUP_MASK(Flag, Name) { \ - if(mask & BIT(Flag)) { \ - log_err(parser, key,"the "Name" of the medium is already defined.\n");\ - res = RES_BAD_ARG; \ - goto error; \ - } \ - mask |= BIT(Flag); \ - } (void)0 - if(!strcmp((char*)key->data.scalar.value, "absorptivity")) { - SETUP_MASK(ABSORPTIVITY, "absorptivity"); - res = parse_real(parser, val, 0, DBL_MAX, &mdm->absorptivity); - } else if(!strcmp((char*)key->data.scalar.value, "refractive_index")) { - SETUP_MASK(REFRACTIVE_INDEX, "refractive_index"); - res = parse_real - (parser, val, nextafter(0, 1), DBL_MAX, &mdm->refractive_index); - } else { - log_err(parser, key, "unknown medium parameter `%s'.\n", - key->data.scalar.value); - res = RES_BAD_ARG; - goto error; - } - if(res != RES_OK) { - log_node(parser, key); - goto error; - } - #undef SETUP_MASK - } - - #define CHECK_PARAM(Flag, Name) \ - if(!(mask & BIT(Flag))) { \ - log_err(parser, medium, "the "Name" of the medium is missing.\n"); \ - res = RES_BAD_ARG; \ - goto error; \ - } (void)0 - CHECK_PARAM(ABSORPTIVITY, "absorptivity"); - CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index"); - #undef CHECK_PARAM - -exit: - out_imedium->i = imedium; - return res; -error: - if(imedium) { - darray_medium_pop_back(&parser->mediums); - imedium = SIZE_MAX; - } - goto exit; -} - -static res_T parse_material_dielectric (struct solparser* parser, yaml_document_t* doc, diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h @@ -17,6 +17,7 @@ #define SOLPARSER_MATERIAL_H #include "solparser_image.h" +#include "solparser_medium.h" #include <stddef.h> enum solparser_material_type { @@ -27,13 +28,6 @@ enum solparser_material_type { SOLPARSER_MATERIAL_VIRTUAL }; -struct solparser_medium { - double refractive_index; - double absorptivity; -}; - -struct solparser_medium_id { size_t i; }; - struct solparser_material_dielectric { struct solparser_medium_id medium_i; /* Medium the material "looks at" */ struct solparser_medium_id medium_t; /* Opposite medium */ diff --git a/src/parser/solparser_medium.c b/src/parser/solparser_medium.c @@ -0,0 +1,131 @@ +/* Copyright (C) CNRS 2016-2017 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define _POSIX_C_SOURCE 200112L /* nextafter support */ + +#include "solparser_c.h" +#include <math.h> /* nextafter */ + +/******************************************************************************* + * Local function + ******************************************************************************/ +res_T +parse_medium + (struct solparser* parser, + yaml_document_t* doc, + yaml_node_t* medium, + struct solparser_medium_id* out_imedium) +{ + enum { ABSORPTIVITY, REFRACTIVE_INDEX }; + struct solparser_medium* mdm = NULL; + size_t* pimedium = NULL; + size_t imedium = SIZE_MAX; + int mask = 0; /* Register the parsed attributes */ + intptr_t i, n; + res_T res = RES_OK; + ASSERT(doc && medium && out_imedium); + + if(medium->type != YAML_MAPPING_NODE) { + log_err(parser, medium, "expect a mapping of medium attributes.\n"); + res = RES_BAD_ARG; + goto error; + } + + /* Check whether or not the YAML medium alias an already created Solstice + * medium */ + pimedium = htable_yaml2sols_find(&parser->yaml2mediums, &medium); + if(pimedium) { + imedium = *pimedium; + goto exit; + } + + /* Allocate the medium */ + imedium = darray_medium_size_get(&parser->mediums); + res = darray_medium_resize(&parser->mediums, imedium + 1); + if(res != RES_OK) { + log_err(parser, medium, "could not allocate the medium.\n"); + res = RES_BAD_ARG; + goto error; + } + mdm = darray_medium_data_get(&parser->mediums) + imedium; + + n = medium->data.mapping.pairs.top - medium->data.mapping.pairs.start; + FOR_EACH(i, 0, n) { + yaml_node_t* key; + yaml_node_t* val; + + key = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].value); + if(key->type != YAML_SCALAR_NODE) { + log_err(parser, key, "expect a medium parameter.\n"); + res = RES_BAD_ARG; + goto error; + } + #define SETUP_MASK(Flag, Name) { \ + if(mask & BIT(Flag)) { \ + log_err(parser, key,"the "Name" of the medium is already defined.\n");\ + res = RES_BAD_ARG; \ + goto error; \ + } \ + mask |= BIT(Flag); \ + } (void)0 + if(!strcmp((char*)key->data.scalar.value, "absorptivity")) { + SETUP_MASK(ABSORPTIVITY, "absorptivity"); + res = parse_real(parser, val, 0, DBL_MAX, &mdm->absorptivity); + } else if(!strcmp((char*)key->data.scalar.value, "refractive_index")) { + SETUP_MASK(REFRACTIVE_INDEX, "refractive_index"); + res = parse_real + (parser, val, nextafter(0, 1), DBL_MAX, &mdm->refractive_index); + } else { + log_err(parser, key, "unknown medium parameter `%s'.\n", + key->data.scalar.value); + res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; + } + #undef SETUP_MASK + } + + #define CHECK_PARAM(Flag, Name) \ + if(!(mask & BIT(Flag))) { \ + log_err(parser, medium, "the "Name" of the medium is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(ABSORPTIVITY, "absorptivity"); + CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index"); + #undef CHECK_PARAM + + /* Cache the medium */ + res = htable_yaml2sols_set(&parser->yaml2mediums, &medium, &imedium); + if(res != RES_OK) { + log_err(parser, medium, "could not register the medium.\n"); + goto error; + } + +exit: + out_imedium->i = imedium; + return res; +error: + if(imedium) { + darray_medium_pop_back(&parser->mediums); + imedium = SIZE_MAX; + } + goto exit; +} + diff --git a/src/parser/solparser_medium.h b/src/parser/solparser_medium.h @@ -0,0 +1,29 @@ +/* Copyright (C) CNRS 2016-2017 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SOLPARSER_MEDIUM_H +#define SOLPARSER_MEDIUM_H + +#include <stddef.h> + +struct solparser_medium { + double refractive_index; + double absorptivity; +}; + +struct solparser_medium_id { size_t i; }; + +#endif /* SOLPARSER_MEDIUM_H */ + diff --git a/src/parser/test_solparser8.c b/src/parser/test_solparser8.c @@ -43,6 +43,8 @@ main(int argc, char** argv) NCHECK(stream, NULL); fprintf(stream, "- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1 }] }\n"); + fprintf(stream, "- medium: &vacuum {refractive_index: 1, absorptivity: 0}\n"); + fprintf(stream, "- medium: &glass {refractive_index: 1.5, absorptivity: 20}\n"); fprintf(stream, "- entity:\n"); fprintf(stream, " name: test\n"); fprintf(stream, " primary: 0\n"); @@ -51,16 +53,12 @@ main(int argc, char** argv) fprintf(stream, " material:\n"); fprintf(stream, " front:\n"); fprintf(stream, " dielectric:\n"); - fprintf(stream, " medium_i: &outside\n"); - fprintf(stream, " refractive_index: 1\n"); - fprintf(stream, " absorptivity: 0\n"); - fprintf(stream, " medium_t: &inside\n"); - fprintf(stream, " refractive_index: 1.5\n"); - fprintf(stream, " absorptivity: 20\n"); + fprintf(stream, " medium_i: *vacuum\n"); + fprintf(stream, " medium_t: *glass\n"); fprintf(stream, " back:\n"); fprintf(stream, " dielectric:\n"); - fprintf(stream, " medium_i: *inside\n"); - fprintf(stream, " medium_t: *outside\n"); + fprintf(stream, " medium_i: *glass\n"); + fprintf(stream, " medium_t: *vacuum\n"); rewind(stream); CHECK(solparser_setup(parser, NULL, stream), RES_OK); diff --git a/src/parser/yaml/test_ok_7.yaml b/src/parser/yaml/test_ok_7.yaml @@ -38,3 +38,16 @@ medium_i: { absorptivity: 0, refractive_index: 1 } medium_t: { absorptivity: 20, refractive_index: 1.5 } +--- +- sun: { dni: 1 } +- medium: &vacuum { refractive_index: 1, absorptivity: 0 } +- medium: &glass { refractive_index: 1.5, absorptivity: 20 } +- entity: + name: "entity" + primary: 0 + geometry: + - cylinder: { height: 1, radius: 1 } + material: + front: {dielectric: { medium_i: *vacuum, medium_t: *glass }} + back: {dielectric: {medium_i: *glass, medium_t: *vacuum}} +