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 64af11c1a4866444225abb8dd3db2fc7280c8d53
parent 46552ba425acb9d9be534d66301bbb9b92482f07
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 19 Apr 2017 15:29:17 +0200

The parsed spectrum does not need to be sorted anymore

Sort the spectrum after the parsing of its data.

Diffstat:
Mcmake/parser/CMakeLists.txt | 1+
Msrc/parser/solparser_spectrum.c | 47+++++++++++++++++++++++++++++++++++------------
Asrc/parser/test_solparser_spectrum.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+), 12 deletions(-)

diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -108,6 +108,7 @@ if(NOT NO_TEST) new_test(test_solparser7) new_test(test_solparser8) new_test(test_solparser_normal_map) + new_test(test_solparser_spectrum) rcmake_copy_runtime_libraries(test_solparser) endif() diff --git a/src/parser/solparser_spectrum.c b/src/parser/solparser_spectrum.c @@ -20,12 +20,22 @@ /******************************************************************************* * Helper functions ******************************************************************************/ +static int +cmp_spectrum_data(const void* op0, const void* op1) +{ + const struct solparser_spectrum_data* a = op0; + const struct solparser_spectrum_data* b = op1; + ASSERT(a && b); + if(a->wavelength < b->wavelength) return -1; + if(a->wavelength > b->wavelength) return 1; + return 0; +} + static res_T parse_spectrum_data (struct solparser* parser, yaml_document_t* doc, const yaml_node_t* sdata, - double* last_wl, struct solparser_spectrum_data* spectrum_data) { enum { DATA, WAVELENGTH }; @@ -67,16 +77,8 @@ parse_spectrum_data res = parse_real(parser, val, 0, DBL_MAX, &spectrum_data->data); } else if(!strcmp((char*)key->data.scalar.value, "wavelength")) { SETUP_MASK(WAVELENGTH, "wavelength"); - res = parse_real(parser, val, nextafter(*last_wl, DBL_MAX), DBL_MAX, + res = parse_real(parser, val, nextafter(0, DBL_MAX), DBL_MAX, &spectrum_data->wavelength); - if(*last_wl >= spectrum_data->wavelength) { - ASSERT(res != RES_OK); - log_err(parser, key, - "spectrum with non-increasing wavelengths (%g after %g).\n", - spectrum_data->wavelength, - *last_wl); - } - *last_wl = spectrum_data->wavelength; } else { log_err(parser, key, "unknown spectrum data parameter `%s'.\n", key->data.scalar.value); @@ -118,7 +120,6 @@ parse_spectrum { intptr_t i, n; res_T res = RES_OK; - double last_wl = 0; ASSERT(doc && spectrum && data); if(spectrum->type != YAML_SEQUENCE_NODE) { @@ -140,10 +141,32 @@ parse_spectrum sdata = yaml_document_get_node(doc, spectrum->data.sequence.items.start[i]); spectrum_data = darray_spectrum_data_data_get(data) + i; - res = parse_spectrum_data(parser, doc, sdata, &last_wl, spectrum_data); + res = parse_spectrum_data(parser, doc, sdata, spectrum_data); if(res != RES_OK) goto error; } + if(n == 1) goto exit; + + qsort + (darray_spectrum_data_data_get(data), + darray_spectrum_data_size_get(data), + sizeof(struct solparser_spectrum_data), + cmp_spectrum_data); + + FOR_EACH(i, 1, n) { + const struct solparser_spectrum_data* a; + const struct solparser_spectrum_data* b; + a = darray_spectrum_data_cdata_get(data) + i - 1; + b = darray_spectrum_data_cdata_get(data) + i; + ASSERT(cmp_spectrum_data(a, b) <= 0); + if(a->wavelength == b->wavelength) { + log_err(parser, spectrum, + "duplicated spectrum entry for the wavelength %g\n", a->wavelength); + res = RES_BAD_ARG; + goto error; + } + } + exit: return res; error: diff --git a/src/parser/test_solparser_spectrum.c b/src/parser/test_solparser_spectrum.c @@ -0,0 +1,84 @@ +/* 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" + +static void +test_sun(struct solparser* parser) +{ + const struct solparser_sun* sun; + FILE* stream; + size_t i; + + NCHECK(stream = tmpfile(), NULL); + + fprintf(stream, "- sun:\n"); + fprintf(stream, " dni: 123.456\n"); + fprintf(stream, " spectrum:\n"); + fprintf(stream, " - { wavelength: 2, data: 2 }\n"); + fprintf(stream, " - { wavelength: 1, data: 1 }\n"); + fprintf(stream, " - { wavelength: 8, data: 8 }\n"); + fprintf(stream, " - { wavelength: 3, data: 3 }\n"); + fprintf(stream, " - { wavelength: 5, data: 5 }\n"); + fprintf(stream, " - { wavelength: 9, data: 9 }\n"); + fprintf(stream, " - { wavelength: 6, data: 6 }\n"); + fprintf(stream, " - { wavelength: 7, data: 7 }\n"); + fprintf(stream, " - { wavelength: 4, data: 4 }\n"); + fprintf(stream, "- material: &matte { matte: { reflectivity: 1 } }\n"); + fprintf(stream, "- entity:\n"); + fprintf(stream, " name: foo bar\n"); + fprintf(stream, " primary: 0\n"); + fprintf(stream, " geometry: [{sphere: {radius: 1}, material: *matte}]\n"); + rewind(stream); + + CHECK(solparser_setup(parser, NULL, stream), RES_OK); + CHECK(solparser_load(parser), RES_OK); + + sun = solparser_get_sun(parser); + CHECK(sun->dni, 123.456); + CHECK(sun->radang_distrib_type, SOLPARSER_SUN_RADANG_DISTRIB_DIRECTIONAL); + CHECK(darray_spectrum_data_size_get(&sun->spectrum), 9); + + FOR_EACH(i, 0, darray_spectrum_data_size_get(&sun->spectrum)) { + CHECK(darray_spectrum_data_cdata_get(&sun->spectrum)[i].wavelength, i+1); + CHECK(darray_spectrum_data_cdata_get(&sun->spectrum)[i].wavelength, i+1); + } + + CHECK(solparser_load(parser), RES_BAD_OP); + fclose(stream); +} + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct solparser* parser; + (void)argc, (void)argv; + + CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK); + CHECK(solparser_create(&allocator, &parser), RES_OK); + + test_sun(parser); + + solparser_ref_put(parser); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHECK(mem_allocated_size(), 0); + return 0; +} +