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 de5e84bde83cd7f27183410d8ddc75a0a2e62850
parent 8905ab82a5f0b9ab5e05973f9354569e411125ed
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 22 Mar 2017 16:38:21 +0100

Specify, load and test the dielectric material descriptor

Diffstat:
Mcmake/parser/CMakeLists.txt | 1+
Mdoc/input | 15++++++++++-----
Msrc/parser/solparser.c | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/parser/solparser.h | 5+++++
Msrc/parser/solparser_material.h | 9+++++++++
Asrc/parser/test_solparser8.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/parser/yaml/test_ko_0.yaml | 36++++++++++++++++++++++++++++++++++--
7 files changed, 276 insertions(+), 9 deletions(-)

diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -91,6 +91,7 @@ if(NOT NO_TEST) new_test(test_solparser5) new_test(test_solparser6) new_test(test_solparser7) + new_test(test_solparser8) rcmake_copy_runtime_libraries(test_solparser) endif() diff --git a/doc/input b/doc/input @@ -219,17 +219,22 @@ back: <material-descriptor> <material-descriptor> ::= - <mirror> | <matte> | <thin-dielectric> | <virtual> + <dielectric> | <matte> | <mirror> | thin-dielectric> | <virtual> -<mirror> ::= - mirror: - reflectivity: REAL # in [0, 1] - roughness: REAL # in [0, 1] +<dielectric> ::= + dielectric: + eta_i: REAL # in ]0, INF) + eta_t: REAL # in ]0, INF) <matte> ::= matte: reflectivity: REAL # in [0, 1] +<mirror> ::= + mirror: + reflectivity: REAL # in [0, 1] + roughness: REAL # in [0, 1] + <virtual> ::= virtual: EMPTY-STRING diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -44,6 +44,11 @@ struct target_alias { #define DARRAY_DATA struct target_alias #include <rsys/dynamic_array.h> +/* Declare the array of dielectric materials */ +#define DARRAY_NAME dielectric +#define DARRAY_DATA struct solparser_material_dielectric +#include <rsys/dynamic_array.h> + /* Declare the array of matte materials */ #define DARRAY_NAME matte #define DARRAY_DATA struct solparser_material_matte @@ -188,6 +193,7 @@ struct solparser { struct htable_yaml2sols yaml2mtls; /* Cache of materials */ struct darray_material mtls; struct darray_material2 mtls2; /* Double sided materials */ + struct darray_dielectric dielectrics; struct darray_matte mattes; struct darray_mirror mirrors; struct darray_thin_dielectric thin_dielectrics; @@ -386,6 +392,7 @@ parser_clear(struct solparser* parser) htable_yaml2sols_clear(&parser->yaml2mtls); darray_material_clear(&parser->mtls); darray_material2_clear(&parser->mtls2); + darray_dielectric_clear(&parser->dielectrics); darray_matte_clear(&parser->mattes); darray_mirror_clear(&parser->mirrors); darray_thin_dielectric_clear(&parser->thin_dielectrics); @@ -438,6 +445,7 @@ parser_release(ref_T* ref) htable_yaml2sols_release(&parser->yaml2mtls); darray_material_release(&parser->mtls); darray_material2_release(&parser->mtls2); + darray_dielectric_release(&parser->dielectrics); darray_matte_release(&parser->mattes); darray_mirror_release(&parser->mirrors); darray_thin_dielectric_release(&parser->thin_dielectrics); @@ -859,6 +867,99 @@ error: * Material ******************************************************************************/ static res_T +parse_material_dielectric + (struct solparser* parser, + yaml_document_t* doc, + const yaml_node_t* dielec, + struct solparser_material_dielectric_id* out_imtl) +{ + enum { ETA_I, ETA_T }; + struct solparser_material_dielectric* mtl = NULL; + size_t imtl = SIZE_MAX; + int mask = 0; /* Register the parsed attributes */ + intptr_t i, n; + res_T res = RES_OK; + ASSERT(doc && dielec && out_imtl); + + if(dielec->type != YAML_MAPPING_NODE) { + log_err(parser, dielec, + "expect a mapping of dielec material attributes.\n"); + res = RES_BAD_ARG; + goto error; + } + + /* Allocate the dielec material */ + imtl = darray_dielectric_size_get(&parser->dielectrics); + res = darray_dielectric_resize(&parser->dielectrics, imtl + 1); + if(res != RES_OK) { + log_err(parser, dielec, + "could not allocate the dielec material.\n"); + goto error; + } + mtl = darray_dielectric_data_get(&parser->dielectrics) + imtl; + + n = dielec->data.mapping.pairs.top - dielec->data.mapping.pairs.start; + FOR_EACH(i, 0, n) { + yaml_node_t* key; + yaml_node_t* val; + + key = yaml_document_get_node(doc, dielec->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, dielec->data.mapping.pairs.start[i].value); + if(key->type != YAML_SCALAR_NODE) { + log_err(parser, key, "expect a dielec material 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 dielectric material is already defined.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } \ + mask |= BIT(Flag); \ + } (void)0 + if(!strcmp((char*)key->data.scalar.value, "eta_i")) { + SETUP_MASK(ETA_I, "eta_i"); + res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &mtl->eta_i); + } else if(!strcmp((char*)key->data.scalar.value, "eta_t")) { + SETUP_MASK(ETA_T, "eta_t"); + res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &mtl->eta_t); + } else { + log_err(parser, key, "unknown dielectric 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, dielec, \ + "the "Name" of the dielectric material is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(ETA_I, "eta_i"); + CHECK_PARAM(ETA_T, "eta_t"); + #undef CHECK_PARAM +exit: + out_imtl->i = imtl; + return res; +error: + if(imtl) { + darray_dielectric_pop_back(&parser->dielectrics); + imtl = SIZE_MAX; + } + goto exit; +} + +static res_T parse_material_matte (struct solparser* parser, yaml_document_t* doc, @@ -1048,7 +1149,7 @@ parse_material_thin_dielectric if(thin->type != YAML_MAPPING_NODE) { log_err(parser, thin, - "expect a mapping of thin material attributes.\n"); + "expect a mapping of thin dielectric material attributes.\n"); res = RES_BAD_ARG; goto error; } @@ -1211,7 +1312,11 @@ parse_material_descriptor } \ mask |= BIT(Flag); \ } (void)0 - if(!strcmp((char*)key->data.scalar.value, "matte")) { + if(!strcmp((char*)key->data.scalar.value, "dielectric")) { + SETUP_MASK(DESCRIPTOR, "descriptor"); + mtl->type = SOLPARSER_MATERIAL_DIELECTRIC; + res = parse_material_dielectric(parser, doc, val, &mtl->data.dielectric); + } else if(!strcmp((char*)key->data.scalar.value, "matte")) { SETUP_MASK(DESCRIPTOR, "descriptor"); mtl->type = SOLPARSER_MATERIAL_MATTE; res = parse_material_matte(parser, doc, val, &mtl->data.matte); @@ -3627,6 +3732,7 @@ solparser_create htable_yaml2sols_init(mem_allocator, &parser->yaml2mtls); darray_material_init(mem_allocator, &parser->mtls); darray_material2_init(mem_allocator, &parser->mtls2); + 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); @@ -3964,6 +4070,16 @@ solparser_get_material_double_sided return darray_material2_cdata_get(&parser->mtls2) + mtl2.i; } +const struct solparser_material_dielectric* +solparser_get_material_dielectric + (const struct solparser* parser, + const struct solparser_material_dielectric_id dielectric) +{ + ASSERT(parser); + ASSERT(dielectric.i < darray_dielectric_size_get(&parser->dielectrics)); + return darray_dielectric_cdata_get(&parser->dielectrics) + dielectric.i; +} + const struct solparser_material_matte* solparser_get_material_matte (const struct solparser* parser, diff --git a/src/parser/solparser.h b/src/parser/solparser.h @@ -102,6 +102,11 @@ solparser_get_material_double_sided (const struct solparser* parser, const struct solparser_material_double_sided_id mtl2); +extern LOCAL_SYM const struct solparser_material_dielectric* +solparser_get_material_dielectric + (const struct solparser* parser, + const struct solparser_material_dielectric_id dielectric); + extern LOCAL_SYM const struct solparser_material_matte* solparser_get_material_matte (const struct solparser* parser, diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h @@ -19,12 +19,20 @@ #include <stddef.h> enum solparser_material_type { + SOLPARSER_MATERIAL_DIELECTRIC, SOLPARSER_MATERIAL_MATTE, SOLPARSER_MATERIAL_MIRROR, SOLPARSER_MATERIAL_THIN_DIELECTRIC, SOLPARSER_MATERIAL_VIRTUAL }; +struct solparser_material_dielectric { + double eta_i; /* Refractive index of the medium the material "looks at" */ + double eta_t; /* Refractive index of the opposite medium */ +}; + +struct solparser_material_dielectric_id { size_t i; }; + struct solparser_material_matte { double reflectivity; /* In [0, 1] */ }; @@ -49,6 +57,7 @@ struct solparser_material_thin_dielectric_id { size_t i; }; struct solparser_material { enum solparser_material_type type; union { + struct solparser_material_dielectric_id dielectric; struct solparser_material_matte_id matte; struct solparser_material_mirror_id mirror; struct solparser_material_thin_dielectric_id thin_dielectric; diff --git a/src/parser/test_solparser8.c b/src/parser/test_solparser8.c @@ -0,0 +1,99 @@ +/* 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/>. */ + +#include "solparser.h" +#include "solparser_sun.h" +#include "test_solstice_utils.h" + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct solparser* parser; + struct solparser_entity_iterator it, end; + struct solparser_entity_id entity_id; + struct solparser_object_id obj_id; + const struct solparser_entity* entity; + const struct solparser_geometry* geom; + const struct solparser_material_double_sided* mtl2; + const struct solparser_material* mtl; + const struct solparser_material_dielectric* dielec; + const struct solparser_object* obj; + const struct solparser_shape* shape; + FILE* stream; + (void)argc, (void)argv; + + CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK); + solparser_create(&allocator, &parser); + + stream = tmpfile(); + NCHECK(stream, NULL); + + fprintf(stream, "- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1 }] }\n"); + fprintf(stream, "- entity:\n"); + fprintf(stream, " name: test\n"); + fprintf(stream, " primary: 0\n"); + fprintf(stream, " geometry:\n"); + fprintf(stream, " - sphere: { radius: 1 }\n"); + fprintf(stream, " material:\n"); + fprintf(stream, " front: { dielectric: { eta_i: 1.0, eta_t: 1.5 } }\n"); + fprintf(stream, " back: { dielectric: { eta_i: 1.5, eta_t: 1.0 } }\n"); + rewind(stream); + + CHECK(solparser_setup(parser, NULL, stream), RES_OK); + CHECK(solparser_load(parser), RES_OK); + + solparser_entity_iterator_begin(parser, &it); + solparser_entity_iterator_end(parser, &end); + CHECK(solparser_entity_iterator_eq(&it, &end), 0); + + entity_id = solparser_entity_iterator_get(&it); + entity = solparser_get_entity(parser, entity_id); + + CHECK(strcmp("test", str_cget(&entity->name)), 0); + CHECK(solparser_entity_get_children_count(entity), 0); + CHECK(entity->type, SOLPARSER_ENTITY_GEOMETRY); + geom = solparser_get_geometry(parser, entity->data.geometry); + CHECK(solparser_geometry_get_objects_count(geom), 1); + obj_id = solparser_geometry_get_object(geom, 0); + obj = solparser_get_object(parser, obj_id); + shape = solparser_get_shape(parser, obj->shape); + CHECK(shape->type, SOLPARSER_SHAPE_SPHERE); + mtl2 = solparser_get_material_double_sided(parser, obj->mtl2); + NCHECK(mtl2->front.i, mtl2->back.i); + + mtl = solparser_get_material(parser, mtl2->front); + CHECK(mtl->type, SOLPARSER_MATERIAL_DIELECTRIC); + dielec = solparser_get_material_dielectric(parser, mtl->data.dielectric); + CHECK(dielec->eta_i, 1.0); + CHECK(dielec->eta_t, 1.5); + + mtl = solparser_get_material(parser, mtl2->back); + CHECK(mtl->type, SOLPARSER_MATERIAL_DIELECTRIC); + dielec = solparser_get_material_dielectric(parser, mtl->data.dielectric); + CHECK(dielec->eta_i, 1.5); + CHECK(dielec->eta_t, 1.0); + + CHECK(solparser_load(parser), RES_BAD_OP); + solparser_ref_put(parser); + + fclose(stream); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHECK(mem_allocated_size(), 0); + return 0; +} + diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml @@ -245,6 +245,38 @@ # invalid refractive index - material: thin_dielectric: { absorption: 0, thickness: 0, refractive_index: -0.0001 } + +--- + +# +# <dielectric> ::= +# dielectric: +# eta_i: REAL # in ]0, INF) +# eta_t: REAL # in ]0, INF) +# + +# invalid eta_i +- material: + dielectric: { eta_i: -1, eta_t: 1 } +--- +- material: + dielectric: { eta_i: 0, eta_t: 1 } +--- +# invalid eta_t +- material: + dielectric: { eta_i: 1, eta_t: -1 } +--- +# invalid eta_t +- material: + dielectric: { eta_i: 1, eta_t: 0 } +--- +# missing eta_t +- material: + dielectric: { eta_i: 1 } +--- +# missing eta_i +- material: + dielectric: { eta_t: 1 } --- # @@ -772,7 +804,7 @@ - [-0.50, -0.50] - [-0.50, 0.50] - [0.50, 0.50] - - [0.50, -0.50] + - [0.50, -0.50] --- # invalid slices - geometry: &target @@ -784,7 +816,7 @@ - [-0.50, -0.50] - [-0.50, 0.50] - [0.50, 0.50] - - [0.50, -0.50] + - [0.50, -0.50] --- #