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 b6aa4da0b4c25947d4ee82e879b08ba10c2d31b5
parent 49c064810e2be07d0f87677829521cb8380c85f1
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu,  4 May 2017 10:17:36 +0200

Merge branch 'feature_atmosphere' into develop

Diffstat:
Mcmake/CMakeLists.txt | 1+
Mcmake/parser/CMakeLists.txt | 2++
Mdoc/input | 7++++++-
Msrc/parser/solparser.c | 13++++++++++++-
Msrc/parser/solparser.h | 4++++
Asrc/parser/solparser_atmosphere.c | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/parser/solparser_atmosphere.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/parser/solparser_c.h | 13+++++++++++++
Msrc/parser/test_solparser2.c | 2++
Msrc/parser/test_solparser3.c | 2++
Msrc/parser/yaml/test_ko_0.yaml | 51++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/solstice.c | 6++++++
Msrc/solstice.h | 1+
Asrc/solstice_atmosphere.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/solstice_atmosphere.h | 0
Msrc/solstice_c.h | 10++++++++++
Msrc/solstice_material.c | 64++++++++++++++++++++++++++++++++--------------------------------
Msrc/solstice_object.c | 8++++----
Myaml/test07.yaml | 3+++
Myaml/test08.yaml | 3+++
20 files changed, 381 insertions(+), 39 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -86,6 +86,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SOLSTICE_FILES_SRC solstice.c solstice_args.c + solstice_atmosphere.c solstice_draw.c solstice_dump.c solstice_entity.c diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -31,6 +31,7 @@ include_directories( ################################################################################ set(SOLPARSER_FILES_SRC solparser.c + solparser_atmosphere.c solparser_entity.c solparser_image.c solparser_geometry.c @@ -43,6 +44,7 @@ set(SOLPARSER_FILES_SRC set(SOLPARSER_FILES_INC solparser.h solparser_c.h + solparser_atmosphere.h solparser_entity.h solparser_geometry.h solparser_image.h diff --git a/doc/input b/doc/input @@ -83,6 +83,7 @@ <solar-factory> ::= <sun> <items> +[ <atmosphere> ] <items> ::= - <item> @@ -348,6 +349,11 @@ aperture: REAL # in ]0, 90] #---------------------------------------- +<atmosphere> ::= + atmosphere: + absorption: <mtl-data> # in [0, 1] + +#---------------------------------------- <mtl-data> ::= REAL | <spectrum-data-list> @@ -380,4 +386,3 @@ <spectrum-data> ::= wavelength: REAL # in [0, INF) data: REAL # in [0, INF) - diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -119,6 +119,7 @@ parse_item struct solparser_material_double_sided_id mtl2; struct solparser_medium_id medium; struct solparser_sun* sun; + struct solparser_atmosphere* atmosphere; yaml_node_t* key; yaml_node_t* val; @@ -148,7 +149,7 @@ parse_item goto error; } - /* The parsing of the templates/spectraa is deferred to their explicit use */ + /* The parsing of the templates/spectra is deferred to their explicit use */ if(!strcmp((char*)key->data.scalar.value, "material")) { res = parse_material(parser, doc, val, &mtl2); } else if(!strcmp((char*)key->data.scalar.value, "medium")) { @@ -163,6 +164,8 @@ parse_item res = parse_geometry(parser, doc, val, &geometry); } else if(!strcmp((char*)key->data.scalar.value, "sun")) { res = parse_sun(parser, doc, val, &sun); + } else if (!strcmp((char*)key->data.scalar.value, "atmosphere")) { + res = parse_atmosphere(parser, doc, val, &atmosphere); } else if(!strcmp((char*)key->data.scalar.value, "spectrum")) { /* Deferred */ } else { log_err(parser, key, "unknown item `%s'.\n", key->data.scalar.value); @@ -1135,6 +1138,14 @@ solparser_get_sun(const struct solparser* parser) return &parser->sun; } +const struct solparser_atmosphere* +solparser_get_atmosphere(const struct solparser* parser) +{ + ASSERT(parser); + if(parser->sun_key) return &parser->atmosphere; + else return NULL; +} + void solparser_entity_iterator_begin (struct solparser* parser, diff --git a/src/parser/solparser.h b/src/parser/solparser.h @@ -200,6 +200,10 @@ extern LOCAL_SYM const struct solparser_sun* solparser_get_sun (const struct solparser* parser); +extern LOCAL_SYM const struct solparser_atmosphere* +solparser_get_atmosphere + (const struct solparser* parser); + extern LOCAL_SYM const struct solparser_x_pivot* solparser_get_x_pivot (const struct solparser* parser, diff --git a/src/parser/solparser_atmosphere.c b/src/parser/solparser_atmosphere.c @@ -0,0 +1,118 @@ +/* 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_atmosphere + (struct solparser* parser, + yaml_document_t* doc, + yaml_node_t* atm, + struct solparser_atmosphere** out_solatm) +{ + enum { ABSORPTION }; + struct solparser_atmosphere* solatm = NULL; + int mask = 0; /* Register the parsed attributes */ + intptr_t i, n; + res_T res = RES_OK; + ASSERT(doc && atm && out_solatm); + + if(atm == parser->atmosphere_key) { + solatm = &parser->atmosphere; + goto exit; + } else if(parser->atmosphere_key != 0) { + log_err(parser, atm, + "an atmosphere is already defined. Previous definition is here %lu:%lu.\n", + (unsigned long)parser->atmosphere_key->start_mark.line + 1, + (unsigned long)parser->atmosphere_key->start_mark.column + 1); + res = RES_BAD_ARG; + goto error; + } else { + solatm = &parser->atmosphere; + parser->atmosphere_key = atm; + } + + if(atm->type != YAML_MAPPING_NODE) { + log_err(parser, atm, "expect a mapping of atmosphere attributes.\n"); + res = RES_BAD_ARG; + goto error; + } + + n = atm->data.mapping.pairs.top - atm->data.mapping.pairs.start; + FOR_EACH(i, 0, n) { + yaml_node_t* key; + yaml_node_t* val; + + key = yaml_document_get_node(doc, atm->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, atm->data.mapping.pairs.start[i].value); + if(key->type != YAML_SCALAR_NODE) { + log_err(parser, key, "expect an atmosphere 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 atmosphere is already defined.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } \ + mask |= BIT(Flag); \ + } (void)0 + if(!strcmp((char*)key->data.scalar.value, "absorption")) { + SETUP_MASK(ABSORPTION, "absorption"); + res = parse_mtl_data + (parser, doc, val, 0, 1, &solatm->absorption); + } else { + log_err(parser, key, "unknown atmosphere 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, atm, "the "Name" of the atmosphere is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(ABSORPTION, "absorption"); + #undef CHECK_PARAM + +exit: + *out_solatm = solatm; + return res; +error: + if(solatm) { + solparser_atmosphere_clear(solatm); + solatm = NULL; + parser->atmosphere_key = 0; + } + solatm = NULL; + goto exit; +} + diff --git a/src/parser/solparser_atmosphere.h b/src/parser/solparser_atmosphere.h @@ -0,0 +1,49 @@ +/* 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_ATMOSPHERE_H +#define SOLPARSER_ATMOSPHERE_H + +#include "solparser_mtl_data.h" + +struct solparser_atmosphere { + struct solparser_mtl_data absorption; +}; + +static INLINE void +solparser_atmosphere_init + (struct mem_allocator* allocator, struct solparser_atmosphere* atmosphere) +{ + ASSERT(atmosphere); + (void)allocator; + /* Do nothing */ +} + +static INLINE void +solparser_atmosphere_release(struct solparser_atmosphere* atmosphere) +{ + ASSERT(atmosphere); + (void)atmosphere; + /* Do nothing */ +} + +static INLINE void +solparser_atmosphere_clear(struct solparser_atmosphere* atmosphere) +{ + ASSERT(atmosphere); + /* Do nothing */ +} +#endif /* SOLPARSER_ATMOSPHERE_H */ + diff --git a/src/parser/solparser_c.h b/src/parser/solparser_c.h @@ -17,6 +17,7 @@ #define SOLPARSER_C_H #include "solparser.h" +#include "solparser_atmosphere.h" #include "solparser_entity.h" #include "solparser_image.h" #include "solparser_material.h" @@ -265,6 +266,11 @@ struct solparser { const yaml_node_t* sun_key; /* yaml_node_t ptr used to spawn the sun */ struct solparser_sun sun; /* The loaded sun */ + /* Atmosphere. Note that at most one atmosphere is supported */ + const yaml_node_t* atmosphere_key; + /* yaml_node_t ptr used to spawn the atmosphere; can be NULL */ + struct solparser_atmosphere atmosphere; /* The loaded atmosphere, if any */ + /* Entity */ struct htable_str2sols str2entities; struct darray_entity entities; @@ -438,6 +444,13 @@ parse_sun struct solparser_sun** out_solsun); extern LOCAL_SYM res_T +parse_atmosphere + (struct solparser* parser, + yaml_document_t* doc, + yaml_node_t* atm, + struct solparser_atmosphere** out_solatm); + +extern LOCAL_SYM res_T parse_x_pivot (struct solparser* parser, yaml_document_t* doc, diff --git a/src/parser/test_solparser2.c b/src/parser/test_solparser2.c @@ -79,6 +79,8 @@ main(int argc, char** argv) fprintf(stream, "- sun:\n"); fprintf(stream, " dni: 1\n"); fprintf(stream, " spectrum: [ { wavelength: 1, data: 1} ]\n"); + fprintf(stream, "- atmosphere:\n"); + fprintf(stream, " absorption: 0\n"); rewind(stream); CHECK(solparser_setup(parser, NULL, stream), RES_OK); diff --git a/src/parser/test_solparser3.c b/src/parser/test_solparser3.c @@ -42,6 +42,8 @@ static const char* input[] = { "- sun: \n", " dni: 1\n", " spectrum: [{wavelength: 1, data: 1}]\n", + "- atmosphere:\n", + " absorption: [{wavelength: 1, data: 1}]\n", "- entity:\n", " name: entity0\n", " primary: 0\n", diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml @@ -1862,9 +1862,49 @@ --- # +# <atmosphere> ::= +# atmosphere: +# absorption: <mtl-data> # in [0, 1] +# + +# missing atmosphere definition +- atmosphere: +--- +# unknown dummy parameter +- atmosphere: + dummy: 1 +--- +# missing absorption definition +- atmosphere: + absorption: +--- +# absorption should be a number +- atmosphere: + absorption: "dummy" +--- +# 2 invalid +- atmosphere: + absorption: 2 +--- +# 0 invalid +- atmosphere: + absorption: [{wavelength: 0, data: 1}] +--- +# 2 invalid +- atmosphere: + absorption: [{wavelength: 0, data: 2}] +--- +# 2x absorption +- atmosphere: + absorption: 0.1 + absorption: [{wavelength: 1, data: 1}] +--- + +# # <solar-factory> ::= # <sun> # <items> +# [ <atmosphere> ] # # <items> ::= # - <item> @@ -1887,4 +1927,13 @@ geometry: - cuboid: { size: [1, 2, 3] } material: { matte: { reflectivity: 1 } } - +--- +# 2x sun +- sun: { dni: 1000, spectrum: [{wavelength: 1, data: 1}] } +- sun: { dni: 1000, spectrum: [{wavelength: 1, data: 1}] } +--- +# 2x atmosphere +- atmosphere: + absorption: 0.1 +- atmosphere: + absorption: 0.1 diff --git a/src/solstice.c b/src/solstice.c @@ -608,6 +608,12 @@ solstice_init goto error; } + res = solstice_create_atmosphere(solstice); + if(res != RES_OK) { + fprintf(stderr, "Could not setup the Solstice atmosphere.\n"); + goto error; + } + solstice->nexperiments = args->nexperiments; solstice->output_hits = args->output_hits; solstice->dump_format = args->dump_format; diff --git a/src/solstice.h b/src/solstice.h @@ -88,6 +88,7 @@ struct solstice { struct ssol_device* ssol; struct ssol_scene* scene; struct ssol_sun* sun; + struct ssol_atmosphere* atmosphere; struct solparser* parser; diff --git a/src/solstice_atmosphere.c b/src/solstice_atmosphere.c @@ -0,0 +1,63 @@ +/* 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 "solstice_c.h" +#include "parser/solparser.h" +#include "parser/solparser_atmosphere.h" + +#include <solstice/ssol.h> + +res_T +solstice_create_atmosphere(struct solstice* solstice) +{ + struct ssol_atmosphere* atm = NULL; + struct ssol_data absorption = SSOL_DATA_NULL; + const struct solparser_atmosphere* solparser_atm = NULL; + res_T res = RES_OK; + ASSERT(solstice); + + solparser_atm = solparser_get_atmosphere(solstice->parser); + if(!solparser_atm) return res; + + res = ssol_atmosphere_create(solstice->ssol, &atm); + if(res != RES_OK) goto error; + + res = mtl_to_ssol_data(solstice, &solparser_atm->absorption, &absorption); + if(res != RES_OK) goto error; + + res = ssol_atmosphere_set_absorption(atm, &absorption); + if(res != RES_OK) { + fprintf(stderr, "Could not set atmosphere absorbtion.\n"); + goto error; + } + + res = ssol_scene_attach_atmosphere(solstice->scene, atm); + if(res != RES_OK) { + fprintf(stderr, "Could not attach the atmosphere to the scene.\n"); + goto error; + } + +exit: + ssol_data_clear(&absorption); + solstice->atmosphere = atm; + return res; +error: + if(atm) { + SSOL(atmosphere_ref_put(atm)); + atm = NULL; + } + + goto exit; +} diff --git a/src/solstice_atmosphere.h b/src/solstice_atmosphere.h diff --git a/src/solstice_c.h b/src/solstice_c.h @@ -61,6 +61,10 @@ solstice_create_sun (struct solstice* solstice); extern LOCAL_SYM res_T +solstice_create_atmosphere + (struct solstice* solstice); + +extern LOCAL_SYM res_T solstice_setup_entities (struct solstice* solstice); @@ -76,6 +80,12 @@ solstice_create_ssol_spectrum struct ssol_spectrum** spectrum); extern LOCAL_SYM res_T +mtl_to_ssol_data + (struct solstice* solstice, + const struct solparser_mtl_data* mtl_data, + struct ssol_data* data); + +extern LOCAL_SYM res_T solstice_create_ssol_material (struct solstice* solstice, const struct solparser_material_id mtl_id, diff --git a/src/solstice_material.c b/src/solstice_material.c @@ -205,38 +205,6 @@ thin_dielectric_param_release(void* mem) } static res_T -mtl_to_ssol_data - (struct solstice* solstice, - const struct solparser_mtl_data* mtl_data, - struct ssol_data* data) -{ - struct ssol_spectrum* spectrum = NULL; - res_T res = RES_OK; - ASSERT(mtl_data && data); - - ssol_data_clear(data); - switch(mtl_data->type) { - case SOLPARSER_MTL_DATA_REAL: - ssol_data_set_real(data, mtl_data->value.real); - break; - case SOLPARSER_MTL_DATA_SPECTRUM: - res = solstice_create_ssol_spectrum - (solstice, mtl_data->value.spectrum, &spectrum); - if(res != RES_OK) goto error; - ssol_data_set_spectrum(data, spectrum); - break; - default: FATAL("Unreachable code.\n"); break; - } - -exit: - if(spectrum) SSOL(spectrum_ref_put(spectrum)); - return res; -error: - ssol_data_clear(data); - goto exit; -} - -static res_T load_image (struct solstice* solstice, const char* filename, @@ -601,6 +569,38 @@ error: * Local functions ******************************************************************************/ res_T +mtl_to_ssol_data + (struct solstice* solstice, + const struct solparser_mtl_data* mtl_data, + struct ssol_data* data) +{ + struct ssol_spectrum* spectrum = NULL; + res_T res = RES_OK; + ASSERT(mtl_data && data); + + ssol_data_clear(data); + switch(mtl_data->type) { + case SOLPARSER_MTL_DATA_REAL: + ssol_data_set_real(data, mtl_data->value.real); + break; + case SOLPARSER_MTL_DATA_SPECTRUM: + res = solstice_create_ssol_spectrum + (solstice, mtl_data->value.spectrum, &spectrum); + if(res != RES_OK) goto error; + ssol_data_set_spectrum(data, spectrum); + break; + default: FATAL("Unreachable code.\n"); break; + } + +exit: + if(spectrum) SSOL(spectrum_ref_put(spectrum)); + return res; +error: + ssol_data_clear(data); + goto exit; +} + +res_T solstice_create_ssol_material (struct solstice* solstice, const struct solparser_material_id mtl_id, diff --git a/src/solstice_object.c b/src/solstice_object.c @@ -294,7 +294,7 @@ create_stl stl = solparser_get_shape_stl(solstice->parser, stl_id); ASSERT(str_cget(&stl->filename)); - res = sstl_create(NULL, solstice->allocator, 0, &tmp_stl); + res = sstl_create(NULL, solstice->allocator, 1, &tmp_stl); if(res != RES_OK) { fprintf(stderr, "Could not create a Solstice Solver STL shape.\n"); goto error; @@ -608,9 +608,9 @@ create_shaded_shape exit: return res; error: - if(*ssol_front) SSOL(material_ref_put(*ssol_front)); - if(*ssol_back) SSOL(material_ref_put(*ssol_back)); - if(*ssol_shape) SSOL(shape_ref_put(*ssol_shape)); + if(*ssol_front) SSOL(material_ref_put(*ssol_front)), *ssol_front = NULL; + if(*ssol_back) SSOL(material_ref_put(*ssol_back)), *ssol_back = NULL; + if(*ssol_shape) SSOL(shape_ref_put(*ssol_shape)), *ssol_shape = NULL; goto exit; } diff --git a/yaml/test07.yaml b/yaml/test07.yaml @@ -1,5 +1,8 @@ - sun: &sun { dni: 1 } +- atmosphere: + absorption: [{wavelength: 1, data: 0},{wavelength: 10, data: 0}] + - material: &specular front: mirror: { reflectivity: 1, roughness: 0 } diff --git a/yaml/test08.yaml b/yaml/test08.yaml @@ -1,5 +1,8 @@ - sun: &sun { dni: 1 } +- atmosphere: + absorption: 0 + - material: &lambertian front: matte: { reflectivity: 1 }