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 8bd58de2fa8341c8614dbfb14f52c54f6c416315
parent 72607b32af4ff01dce1e5cc60ceda6230d2d4e04
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 24 Apr 2017 10:41:57 +0200

Parse and handle the medium mtl_data

The refractive index and the absorptivity of the medium is a mtl_data,
i.e. they can be defined either as a scalar or as a spectrum.

Diffstat:
Mcmake/CMakeLists.txt | 1+
Mcmake/parser/CMakeLists.txt | 2++
Msrc/parser/solparser_c.h | 12++++++++++++
Msrc/parser/solparser_medium.c | 6+++---
Msrc/parser/solparser_medium.h | 5+++--
Asrc/parser/solparser_mtl_data.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/parser/solparser_mtl_data.h | 35+++++++++++++++++++++++++++++++++++
Msrc/parser/solparser_spectrum.c | 12++++++++++--
Msrc/parser/solparser_sun.c | 2+-
Msrc/parser/test_solparser7.c | 45+++++++++++++++++++++++++++++++++++++++------
Msrc/parser/test_solparser8.c | 52++++++++++++++++++++++++++++++++++++++--------------
Msrc/solstice_c.h | 6++++++
Msrc/solstice_material.c | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Asrc/solstice_spectrum.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/solstice_sun.c | 56++++----------------------------------------------------
15 files changed, 341 insertions(+), 95 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -93,6 +93,7 @@ set(SOLSTICE_FILES_SRC solstice_node.c solstice_object.c solstice_solve.c + solstice_spectrum.c solstice_sun.c solstice_sun_spectrum.c) set(SOLSTICE_FILES_INC diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOLPARSER_FILES_SRC solparser_geometry.c solparser_material.c solparser_medium.c + solparser_mtl_data.c solparser_pivot.c solparser_sun.c solparser_spectrum.c) @@ -47,6 +48,7 @@ set(SOLPARSER_FILES_INC solparser_image.h solparser_material.h solparser_medium.h + solparser_mtl_data.h solparser_pivot.h solparser_shape.h solparser_sun.h diff --git a/src/parser/solparser_c.h b/src/parser/solparser_c.h @@ -21,6 +21,7 @@ #include "solparser_image.h" #include "solparser_material.h" #include "solparser_medium.h" +#include "solparser_mtl_data.h" #include "solparser_pivot.h" #include "solparser_shape.h" #include "solparser_spectrum.h" @@ -401,10 +402,21 @@ parse_medium struct solparser_medium_id* out_imedium); extern LOCAL_SYM res_T +parse_mtl_data + (struct solparser* parser, + yaml_document_t* doc, + yaml_node_t* mtl_data, + const double lower_bound, + const double upper_bound, + struct solparser_mtl_data* data); + +extern LOCAL_SYM res_T parse_spectrum (struct solparser* parser, yaml_document_t* doc, const yaml_node_t* spectrum, + const double lower_bound, + const double upper_bound, struct solparser_spectrum_id* out_ispectrum); extern LOCAL_SYM res_T diff --git a/src/parser/solparser_medium.c b/src/parser/solparser_medium.c @@ -83,11 +83,11 @@ parse_medium } (void)0 if(!strcmp((char*)key->data.scalar.value, "absorptivity")) { SETUP_MASK(ABSORPTIVITY, "absorptivity"); - res = parse_real(parser, val, 0, DBL_MAX, &mdm->absorptivity); + res = parse_mtl_data(parser, doc, 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); + res = parse_mtl_data + (parser, doc, val, nextafter(0, 1), DBL_MAX, &mdm->refractive_index); } else { log_err(parser, key, "unknown medium parameter `%s'.\n", key->data.scalar.value); diff --git a/src/parser/solparser_medium.h b/src/parser/solparser_medium.h @@ -16,11 +16,12 @@ #ifndef SOLPARSER_MEDIUM_H #define SOLPARSER_MEDIUM_H +#include "solparser_mtl_data.h" #include <stddef.h> struct solparser_medium { - double refractive_index; - double absorptivity; + struct solparser_mtl_data refractive_index; + struct solparser_mtl_data absorptivity; }; struct solparser_medium_id { size_t i; }; diff --git a/src/parser/solparser_mtl_data.c b/src/parser/solparser_mtl_data.c @@ -0,0 +1,56 @@ +/* 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_c.h" + +/******************************************************************************* + * Local function + ******************************************************************************/ +res_T +parse_mtl_data + (struct solparser* parser, + yaml_document_t* doc, + yaml_node_t* mtl_data, + const double lower_bound, + const double upper_bound, + struct solparser_mtl_data* data) +{ + res_T res = RES_OK; + ASSERT(doc && mtl_data && data); + + if(mtl_data->type == YAML_SCALAR_NODE) { + data->type = SOLPARSER_MTL_DATA_REAL; + res = parse_real + (parser, mtl_data, lower_bound, upper_bound, &data->value.real); + } else if(mtl_data->type == YAML_SEQUENCE_NODE) { + data->type = SOLPARSER_MTL_DATA_SPECTRUM; + res = parse_spectrum + (parser, doc, mtl_data, lower_bound, upper_bound, &data->value.spectrum); + } else { + log_err(parser, mtl_data, "expect a real or a spectrum definition.\n"); + res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, mtl_data); + goto error; + } + +exit: + return res; +error: + goto exit; +} + diff --git a/src/parser/solparser_mtl_data.h b/src/parser/solparser_mtl_data.h @@ -0,0 +1,35 @@ +/* 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_MTL_DATA_H +#define SOLPARSER_MTL_DATA_H + +#include "solparser_spectrum.h" + +enum solparser_mtl_data_type { + SOLPARSER_MTL_DATA_REAL, + SOLPARSER_MTL_DATA_SPECTRUM +}; + +struct solparser_mtl_data { + enum solparser_mtl_data_type type; + union { + double real; + struct solparser_spectrum_id spectrum; + } value; +}; + +#endif /* SOLPARSER_MTL_DATA_H */ + diff --git a/src/parser/solparser_spectrum.c b/src/parser/solparser_spectrum.c @@ -36,6 +36,8 @@ parse_spectrum_data (struct solparser* parser, yaml_document_t* doc, const yaml_node_t* sdata, + const double lower_bound, + const double upper_bound, struct solparser_spectrum_data* spectrum_data) { enum { DATA, WAVELENGTH }; @@ -43,6 +45,7 @@ parse_spectrum_data int mask = 0; /* Register the parsed attributes */ res_T res = RES_OK; ASSERT(doc && sdata && spectrum_data); + ASSERT(lower_bound <= upper_bound); if(sdata->type != YAML_MAPPING_NODE) { log_err(parser, sdata, "expect the definition of a spectrum data.\n"); @@ -74,7 +77,8 @@ parse_spectrum_data } (void)0 if(!strcmp((char*)key->data.scalar.value, "data")) { SETUP_MASK(DATA, "data"); - res = parse_real(parser, val, 0, DBL_MAX, &spectrum_data->data); + res = parse_real + (parser, val, lower_bound, upper_bound, &spectrum_data->data); } else if(!strcmp((char*)key->data.scalar.value, "wavelength")) { SETUP_MASK(WAVELENGTH, "wavelength"); res = parse_real(parser, val, nextafter(0, DBL_MAX), DBL_MAX, @@ -116,6 +120,8 @@ parse_spectrum (struct solparser* parser, yaml_document_t* doc, const yaml_node_t* spectrum, + const double lower_bound, + const double upper_bound, struct solparser_spectrum_id* out_ispectrum) { struct solparser_spectrum* spec; @@ -123,6 +129,7 @@ parse_spectrum intptr_t i, n; res_T res = RES_OK; ASSERT(doc && spectrum && out_ispectrum); + ASSERT(lower_bound <= upper_bound); if(spectrum->type != YAML_SEQUENCE_NODE) { log_err(parser, spectrum, "expect a list of spectrum data.\n"); @@ -152,7 +159,8 @@ parse_spectrum sdata = yaml_document_get_node(doc, spectrum->data.sequence.items.start[i]); spectrum_data = darray_spectrum_data_data_get(&spec->data) + i; - res = parse_spectrum_data(parser, doc, sdata, spectrum_data); + res = parse_spectrum_data + (parser, doc, sdata, lower_bound, upper_bound, spectrum_data); if(res != RES_OK) goto error; } diff --git a/src/parser/solparser_sun.c b/src/parser/solparser_sun.c @@ -222,7 +222,7 @@ parse_sun res = parse_pillbox(parser, doc, val, &solsun->radang_distrib.pillbox); } else if(!strcmp((char*)key->data.scalar.value, "spectrum")) { SETUP_MASK(SPECTRUM, "spectrum"); - res = parse_spectrum(parser, doc, val, &solsun->spectrum); + res = parse_spectrum(parser, doc, val, 0, DBL_MAX, &solsun->spectrum); } else { log_err(parser, key, "unknown sun parameter `%s'.\n", key->data.scalar.value); diff --git a/src/parser/test_solparser7.c b/src/parser/test_solparser7.c @@ -33,6 +33,7 @@ main(int argc, char** argv) const struct solparser_medium* medium; const struct solparser_object* obj; const struct solparser_shape* shape; + const struct solparser_spectrum* spectrum; FILE* stream; (void)argc, (void)argv; @@ -55,8 +56,16 @@ main(int argc, char** argv) 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, " refractive_index: \n"); + fprintf(stream, " - {wavelength: 1.2, data: 2.3}\n"); + fprintf(stream, " - {wavelength: 4.5, data: 6.7}\n"); + fprintf(stream, " - {wavelength: 0.5, data: 0.25}\n"); + fprintf(stream, " absorptivity:\n"); + fprintf(stream, " - {wavelength: 3, data: 3}\n"); + fprintf(stream, " - {wavelength: 1, data: 1}\n"); + fprintf(stream, " - {wavelength: 5, data: 5}\n"); + fprintf(stream, " - {wavelength: 4, data: 4}\n"); + fprintf(stream, " - {wavelength: 2, data: 2}\n"); rewind(stream); CHECK(solparser_setup(parser, NULL, stream), RES_OK); @@ -87,11 +96,35 @@ main(int argc, char** argv) CHECK(thin->thickness, 0.123); medium = solparser_get_medium(parser, thin->medium_i); - CHECK(medium->refractive_index, 1); - CHECK(medium->absorptivity, 0); + CHECK(medium->refractive_index.type, SOLPARSER_MTL_DATA_REAL); + CHECK(medium->refractive_index.value.real, 1); + CHECK(medium->absorptivity.type, SOLPARSER_MTL_DATA_REAL); + CHECK(medium->absorptivity.value.real, 0); medium = solparser_get_medium(parser, thin->medium_t); - CHECK(medium->refractive_index, 1.5); - CHECK(medium->absorptivity, 20); + + CHECK(medium->refractive_index.type, SOLPARSER_MTL_DATA_SPECTRUM); + spectrum = solparser_get_spectrum(parser, medium->refractive_index.value.spectrum); + CHECK(darray_spectrum_data_size_get(&spectrum->data), 3); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[0].wavelength, 0.5); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[1].wavelength, 1.2); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[2].wavelength, 4.5); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[0].data, 0.25); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[1].data, 2.3); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[2].data, 6.7); + + CHECK(medium->absorptivity.type, SOLPARSER_MTL_DATA_SPECTRUM); + spectrum = solparser_get_spectrum(parser, medium->absorptivity.value.spectrum); + CHECK(darray_spectrum_data_size_get(&spectrum->data), 5); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[0].wavelength, 1); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[1].wavelength, 2); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[2].wavelength, 3); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[3].wavelength, 4); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[4].wavelength, 5); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[0].data, 1); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[1].data, 2); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[2].data, 3); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[3].data, 4); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[4].data, 5); CHECK(solparser_load(parser), RES_BAD_OP); solparser_ref_put(parser); diff --git a/src/parser/test_solparser8.c b/src/parser/test_solparser8.c @@ -27,12 +27,14 @@ main(int argc, char** argv) struct solparser_object_id obj_id; const struct solparser_entity* entity; const struct solparser_geometry* geom; - const struct solparser_medium* medium; + const struct solparser_medium* vacuum; + const struct solparser_medium* glass; 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; + const struct solparser_spectrum* spectrum; FILE* stream; (void)argc, (void)argv; @@ -44,7 +46,15 @@ main(int argc, char** argv) 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, "- medium: &glass \n"); + fprintf(stream, " refractive_index: 1.5\n"); + fprintf(stream, " absorptivity: \n"); + fprintf(stream, " - {wavelength: 1, data: 21}\n"); + fprintf(stream, " - {wavelength: 2, data: 22}\n"); + fprintf(stream, " - {wavelength: 3, data: 23}\n"); + fprintf(stream, " - {wavelength: 4, data: 24}\n"); + fprintf(stream, " - {wavelength: 5, data: 25}\n"); + fprintf(stream, " - {wavelength: 6, data: 26}\n"); fprintf(stream, "- entity:\n"); fprintf(stream, " name: test\n"); fprintf(stream, " primary: 0\n"); @@ -86,22 +96,36 @@ main(int argc, char** argv) mtl = solparser_get_material(parser, mtl2->front); CHECK(mtl->type, SOLPARSER_MATERIAL_DIELECTRIC); dielec = solparser_get_material_dielectric(parser, mtl->data.dielectric); - medium = solparser_get_medium(parser, dielec->medium_i); - CHECK(medium->refractive_index, 1); - CHECK(medium->absorptivity, 0); - medium = solparser_get_medium(parser, dielec->medium_t); - CHECK(medium->refractive_index, 1.5); - CHECK(medium->absorptivity, 20); + vacuum = solparser_get_medium(parser, dielec->medium_i); + CHECK(vacuum->refractive_index.type, SOLPARSER_MTL_DATA_REAL); + CHECK(vacuum->refractive_index.value.real, 1); + CHECK(vacuum->absorptivity.type, SOLPARSER_MTL_DATA_REAL); + CHECK(vacuum->absorptivity.value.real, 0); + + glass = solparser_get_medium(parser, dielec->medium_t); + CHECK(glass->refractive_index.type, SOLPARSER_MTL_DATA_REAL); + CHECK(glass->refractive_index.value.real, 1.5); + CHECK(glass->absorptivity.type, SOLPARSER_MTL_DATA_SPECTRUM); + spectrum = solparser_get_spectrum(parser, glass->absorptivity.value.spectrum); + CHECK(darray_spectrum_data_size_get(&spectrum->data), 6); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[0].wavelength, 1); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[1].wavelength, 2); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[2].wavelength, 3); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[3].wavelength, 4); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[4].wavelength, 5); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[5].wavelength, 6); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[0].data, 21); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[1].data, 22); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[2].data, 23); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[3].data, 24); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[4].data, 25); + CHECK(darray_spectrum_data_cdata_get(&spectrum->data)[5].data, 26); mtl = solparser_get_material(parser, mtl2->back); CHECK(mtl->type, SOLPARSER_MATERIAL_DIELECTRIC); dielec = solparser_get_material_dielectric(parser, mtl->data.dielectric); - medium = solparser_get_medium(parser, dielec->medium_i); - CHECK(medium->refractive_index, 1.5); - CHECK(medium->absorptivity, 20); - medium = solparser_get_medium(parser, dielec->medium_t); - CHECK(medium->refractive_index, 1); - CHECK(medium->absorptivity, 0); + CHECK(solparser_get_medium(parser, dielec->medium_i), glass); + CHECK(solparser_get_medium(parser, dielec->medium_t), vacuum); CHECK(solparser_load(parser), RES_BAD_OP); solparser_ref_put(parser); diff --git a/src/solstice_c.h b/src/solstice_c.h @@ -70,6 +70,12 @@ solstice_update_entities const double sun_dir[3]); extern LOCAL_SYM res_T +solstice_create_ssol_spectrum + (struct solstice* solstice, + const struct solparser_spectrum_id spectrum_id, + struct ssol_spectrum** spectrum); + +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 @@ -202,6 +202,38 @@ 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, @@ -278,8 +310,8 @@ create_material_dielectric { const struct solparser_medium* medium_i; const struct solparser_medium* medium_t; - struct ssol_medium ssol_medium_i; - struct ssol_medium ssol_medium_t; + struct ssol_medium ssol_medium_i = SSOL_MEDIUM_VACUUM; + struct ssol_medium ssol_medium_t = SSOL_MEDIUM_VACUUM; struct ssol_dielectric_shader shader = SSOL_DIELECTRIC_SHADER_NULL; struct ssol_image* img = NULL; struct ssol_material* mtl = NULL; @@ -326,13 +358,20 @@ create_material_dielectric SSOL(material_set_param_buffer(mtl, pbuf)); } - ssol_data_set_real(&ssol_medium_i.refractive_index, medium_i->refractive_index); - ssol_data_set_real(&ssol_medium_t.refractive_index, medium_t->refractive_index); - ssol_data_set_real(&ssol_medium_i.absorptivity, medium_i->absorptivity); - ssol_data_set_real(&ssol_medium_t.absorptivity, medium_t->absorptivity); + #define SET_SSOL_DATA(Medium, Name) { \ + res = mtl_to_ssol_data(solstice, &Medium->Name, &ssol_## Medium.Name); \ + if(res != RES_OK) goto error; \ + } (void)0 + SET_SSOL_DATA(medium_i, refractive_index); + SET_SSOL_DATA(medium_t, refractive_index); + SET_SSOL_DATA(medium_i, absorptivity); + SET_SSOL_DATA(medium_t, absorptivity); + #undef SET_SSOL_DATA SSOL(dielectric_setup(mtl, &shader, &ssol_medium_i, &ssol_medium_t)); exit: + ssol_medium_clear(&ssol_medium_i); + ssol_medium_clear(&ssol_medium_t); if(pbuf) SSOL(param_buffer_ref_put(pbuf)); *out_mtl = mtl; return res; @@ -476,10 +515,10 @@ create_material_thin_dielectric { struct ssol_image* img = NULL; struct ssol_thin_dielectric_shader shader = SSOL_THIN_DIELECTRIC_SHADER_NULL; - const struct solparser_medium* medium_i; - const struct solparser_medium* medium_t; - struct ssol_medium ssol_medium_i; - struct ssol_medium ssol_medium_t; + const struct solparser_medium* medium_i = NULL; + const struct solparser_medium* medium_t = NULL; + struct ssol_medium ssol_medium_i = SSOL_MEDIUM_VACUUM; + struct ssol_medium ssol_medium_t = SSOL_MEDIUM_VACUUM; struct ssol_material* mtl = NULL; struct ssol_param_buffer* pbuf = NULL; res_T res = RES_OK; @@ -526,14 +565,21 @@ create_material_thin_dielectric SSOL(material_set_param_buffer(mtl, pbuf)); } - ssol_data_set_real(&ssol_medium_i.refractive_index, medium_i->refractive_index); - ssol_data_set_real(&ssol_medium_t.refractive_index, medium_t->refractive_index); - ssol_data_set_real(&ssol_medium_i.absorptivity, medium_i->absorptivity); - ssol_data_set_real(&ssol_medium_t.absorptivity, medium_t->absorptivity); + #define SET_SSOL_DATA(Medium, Name) { \ + res = mtl_to_ssol_data(solstice, &Medium->Name, &ssol_## Medium.Name); \ + if(res != RES_OK) goto error; \ + } (void)0 + SET_SSOL_DATA(medium_i, refractive_index); + SET_SSOL_DATA(medium_t, refractive_index); + SET_SSOL_DATA(medium_i, absorptivity); + SET_SSOL_DATA(medium_t, absorptivity); + #undef SET_SSOL_DATA SSOL(thin_dielectric_setup (mtl, &shader, &ssol_medium_i, &ssol_medium_t, thin->thickness)); exit: + ssol_medium_clear(&ssol_medium_i); + ssol_medium_clear(&ssol_medium_t); if(pbuf) SSOL(param_buffer_ref_put(pbuf)); *out_mtl = mtl; return res; @@ -543,7 +589,6 @@ error: goto exit; } - /******************************************************************************* * Local functions ******************************************************************************/ diff --git a/src/solstice_spectrum.c b/src/solstice_spectrum.c @@ -0,0 +1,71 @@ +/* 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" + +/******************************************************************************* + * Helper function + ******************************************************************************/ +static void +get_wavelength(const size_t i, double* wlen, double* data, void* ctx) +{ + const struct solparser_spectrum_data* specdata = ctx; + ASSERT(wlen && data && ctx); + *wlen = specdata[i].wavelength; + *data = specdata[i].data; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +solstice_create_ssol_spectrum + (struct solstice* solstice, + const struct solparser_spectrum_id spectrum_id, + struct ssol_spectrum** out_spectrum) +{ + struct ssol_spectrum* spectrum = NULL; + const struct solparser_spectrum_data* data; + const struct solparser_spectrum* spec; + size_t nwlens; + res_T res = RES_OK; + ASSERT(solstice && SOLPARSER_ID_IS_VALID(spectrum_id) && out_spectrum); + + res = ssol_spectrum_create(solstice->ssol, &spectrum); + if(res != RES_OK) { + fprintf(stderr, "Could not create the Solstice Solver spectrum.\n"); + goto error; + } + + spec = solparser_get_spectrum(solstice->parser, spectrum_id); + nwlens = darray_spectrum_data_size_get(&spec->data); + data = darray_spectrum_data_cdata_get(&spec->data); + res = ssol_spectrum_setup(spectrum, get_wavelength, nwlens, (void*)data); + if(res != RES_OK) { + fprintf(stderr, "Could not setup the Solstice Solver spectrum.\n"); + goto error; + } + +exit: + *out_spectrum = spectrum; + return res; +error: + if(spectrum) { + SSOL(spectrum_ref_put(spectrum)); + spectrum = NULL; + } + goto exit; +} + diff --git a/src/solstice_sun.c b/src/solstice_sun.c @@ -126,15 +126,6 @@ error: static void get_wavelength(const size_t i, double* wlen, double* data, void* ctx) { - const struct solparser_spectrum_data* specdata = ctx; - ASSERT(wlen && data && ctx); - *wlen = specdata[i].wavelength; - *data = specdata[i].data; -} - -static void -get_wavelength_builtin(const size_t i, double* wlen, double* data, void* ctx) -{ const double* spectrum = ctx; ASSERT(wlen && data && ctx); *wlen = spectrum[i*2+0]; @@ -142,45 +133,6 @@ get_wavelength_builtin(const size_t i, double* wlen, double* data, void* ctx) } static res_T -create_sun_spectrum - (struct solstice* solstice, - const struct solparser_sun* solparser_sun, - struct ssol_spectrum** out_spectrum) -{ - struct ssol_spectrum* spectrum = NULL; - const struct solparser_spectrum_data* data; - const struct solparser_spectrum* spec; - size_t nwlens; - res_T res = RES_OK; - ASSERT(solstice && solparser_sun && out_spectrum); - - res = ssol_spectrum_create(solstice->ssol, &spectrum); - if(res != RES_OK) { - fprintf(stderr, "Could not create the spectrum of the solver sun.\n"); - goto error; - } - - spec = solparser_get_spectrum(solstice->parser, solparser_sun->spectrum); - nwlens = darray_spectrum_data_size_get(&spec->data); - data = darray_spectrum_data_cdata_get(&spec->data); - res = ssol_spectrum_setup(spectrum, get_wavelength, nwlens, (void*)data); - if(res != RES_OK) { - fprintf(stderr, "Could not setup the spectrum of the solver sun.\n"); - goto error; - } - -exit: - *out_spectrum = spectrum; - return res; -error: - if(spectrum) { - SSOL(spectrum_ref_put(spectrum)); - spectrum = NULL; - } - goto exit; -} - -static res_T create_default_sun_spectrum (struct solstice* solstice, const struct solparser_sun* solparser_sun, @@ -193,7 +145,7 @@ create_default_sun_spectrum /* The solparser_sun may be used if the defautl spectrum is defined wrt the * sun type */ - (void)solparser_sun; + (void)solparser_sun; res = ssol_spectrum_create(solstice->ssol, &spectrum); if(res != RES_OK) { @@ -209,8 +161,7 @@ create_default_sun_spectrum size = solstice_sun_spectrum_dummy_size; } - res = ssol_spectrum_setup - (spectrum, get_wavelength_builtin, size, (void*)data); + res = ssol_spectrum_setup(spectrum, get_wavelength, size, (void*)data); if(res != RES_OK) { fprintf(stderr, "Coul not setup the default spectrum of the solver sun.\n"); goto error; @@ -258,7 +209,8 @@ solstice_create_sun(struct solstice* solstice) res = create_default_sun_spectrum(solstice, solparser_sun, &spectrum); if(res != RES_OK) goto error; } else { - res = create_sun_spectrum(solstice, solparser_sun, &spectrum); + res = solstice_create_ssol_spectrum + (solstice, solparser_sun->spectrum, &spectrum); if(res != RES_OK) goto error; }