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 a70f6980466a749df919c96260aa64417d4982d6
parent 51d09a5957c43d7c5764a05964cec8f75c93831f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 15 Dec 2017 11:43:30 +0100

Replace the roughness parameter by the slope_error one

For pillbox distribution there is a direct correspondence between the
mirror slope_error and the mirror roughness on the solver side. For
Beckmann distribution, the roughness is equal to sqrt(2) times the
slope_error.

Diffstat:
Mdoc/solstice-input.5.txt | 21+++++++++++----------
Msrc/parser/solparser_material.c | 10+++++-----
Msrc/parser/solparser_material.h | 6+++---
Msrc/parser/test_solparser2.c | 6+++---
Msrc/parser/test_solparser4.c | 6+++---
Msrc/parser/test_solparser_mirror.c | 12++++++------
Msrc/parser/test_solparser_normal_map.c | 6+++---
Msrc/parser/test_solparser_spectrum.c | 6+++---
Msrc/parser/yaml/test_ko_0.yaml | 26+++++++++++++-------------
Msrc/parser/yaml/test_ok_1.yaml | 10+++++-----
Msrc/parser/yaml/test_ok_6.yaml | 20++++++++++----------
Msrc/solstice_c.h | 14++++++++++++++
Msrc/solstice_material.c | 49++++++++++++++++++++++++++++++++++++-------------
Msrc/solstice_spectrum.c | 33+++++++++++++++++++++++++--------
Myaml/beam_down.yaml | 5++---
Myaml/test01.yaml | 4++--
Myaml/test02.yaml | 2+-
Myaml/test03.yaml | 4++--
Myaml/test04.yaml | 4++--
Myaml/test06.yaml | 2+-
Myaml/test07.yaml | 4++--
Myaml/test08.yaml | 2+-
22 files changed, 153 insertions(+), 99 deletions(-)

diff --git a/doc/solstice-input.5.txt b/doc/solstice-input.5.txt @@ -186,7 +186,7 @@ _______ <mirror> ::= mirror: reflectivity: <mtl-data> # in [0, 1] - roughness: <mtl-data> + slope_error: <mtl-data> [ microfacet: <normal-distrib> ] # Default is BECKMANN [ <normal-map> ] @@ -426,24 +426,25 @@ Diffuse surface. Reflects the same intensity in all directions independently of the incoming direction. *mirror*:: -Specular or glossy reflection whether the *roughness* parameter is 0 or not, +Specular or glossy reflection whether the *slope_error* parameter is 0 or not, respectively. Glossy reflections are controlled by a microfacet BRDF. The microfacet normals are distributed with respect to the Beckmann or the Pillbox distribution according to the *normal-distrib* attribute. + -Let m the *roughness* parameter in ]0, 1]. The Beckmann distribution is +Let S the *slope_error* parameter in ]0, 1]. The Beckmann distribution is defined as: + ....... D(wh) = exp(-tan^2(a) / m^2) / (PI * m^2 * cos^4(a)) ....... + -with a = arccos(wh.N), while the pillbox distribution is defined as: +with a = arccos(wh.N), and m = sqrt(2)*S while the pillbox distribution is +defined as: + ....... - | 0; if |wh.N| >= m + | 0; if |wh.N| >= S D(wh) = | - | 1 / (PI * (1 - cos^2(m))); if |wh.N| < m + | 1 / (PI * (1 - cos^2(S))); if |wh.N| < S ....... *thin-dielectric*:: @@ -873,7 +874,7 @@ is 1 and its center is positioned at {0,0,2}: - material: mirror: reflectivity: 1 - roughness: 0 + slope_error: 0 plane: clip: - operation: AND @@ -949,7 +950,7 @@ position is defined relatively to the receiver: transform: {rotation: [-90, 0, 0]} primary: 1 geometry: - - material: {mirror: {reflectivity: 1, roughness: 0}} + - material: {mirror: {reflectivity: 1, slope_error: 0}} parabol: focal: 100 clip: @@ -977,7 +978,7 @@ purely specular while the back faces are diffuse: - sun: {dni: 1000} - material: &specular - front: {mirror: {reflectivity: 1, roughness: 0}} + front: {mirror: {reflectivity: 1, slope_error: 0}} back: {matte: {reflectivity: 1}} - template: &H # Template of an heliostat @@ -1085,7 +1086,7 @@ glass. Furthermore, this example illustrates the use of a *spectrum* for - atmosphere: {extinction: *air_kabs} # Materials -- material: &specular {mirror: {reflectivity: 1, roughness: 0}} +- material: &specular {mirror: {reflectivity: 1, slope_error: 0}} - material: &black {matte: {reflectivity: 0}} - material: &glass front: {dielectric: {medium_i: *air_medium, medium_t: *glass_medium}} diff --git a/src/parser/solparser_material.c b/src/parser/solparser_material.c @@ -245,7 +245,7 @@ parse_material_mirror const yaml_node_t* mirror, struct solparser_material_mirror_id* out_imtl) { - enum { MICROFACET, NORMAL_MAP, REFLECTIVITY, ROUGHNESS }; + enum { MICROFACET, NORMAL_MAP, REFLECTIVITY, SLOPE_ERROR }; struct solparser_material_mirror* mtl = NULL; size_t imtl = SIZE_MAX; int mask = 0; /* Register the parsed attributes */ @@ -300,9 +300,9 @@ parse_material_mirror } else if(!strcmp((char*)key->data.scalar.value, "reflectivity")) { SETUP_MASK(REFLECTIVITY, "reflectivity"); res = parse_mtl_data(parser, doc, val, 0, 1, &mtl->reflectivity); - } else if(!strcmp((char*)key->data.scalar.value, "roughness")) { - SETUP_MASK(ROUGHNESS, "roughness"); - res = parse_mtl_data(parser, doc, val, 0, 1, &mtl->roughness); + } else if(!strcmp((char*)key->data.scalar.value, "slope_error")) { + SETUP_MASK(SLOPE_ERROR, "slope_error"); + res = parse_mtl_data(parser, doc, val, 0, 1, &mtl->slope_error); } else { log_err(parser, key, "unknown mirror attribute `%s'.\n", key->data.scalar.value); @@ -323,7 +323,7 @@ parse_material_mirror goto error; \ } (void)0 CHECK_PARAM(REFLECTIVITY, "reflectivity"); - CHECK_PARAM(ROUGHNESS, "roughness"); + CHECK_PARAM(SLOPE_ERROR, "slope_error"); #undef CHECK_PARAM exit: diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h @@ -68,7 +68,7 @@ solparser_material_matte_init } struct solparser_material_mirror { - struct solparser_mtl_data roughness; /* In [0, 1] */ + struct solparser_mtl_data slope_error; /* In [0, 1] */ struct solparser_mtl_data reflectivity; /* In [0, 1] */ enum solparser_microfacet_distribution ufacet_distrib; struct solparser_image_id normal_map; @@ -83,8 +83,8 @@ solparser_material_mirror_init { ASSERT(mirror); (void)allocator; - mirror->roughness.type = SOLPARSER_MTL_DATA_REAL; - mirror->roughness.value.real = 0; + mirror->slope_error.type = SOLPARSER_MTL_DATA_REAL; + mirror->slope_error.value.real = 0; mirror->ufacet_distrib = SOLPARSER_MICROFACET_BECKMANN; mirror->normal_map.i = SIZE_MAX; } diff --git a/src/parser/test_solparser2.c b/src/parser/test_solparser2.c @@ -88,7 +88,7 @@ main(int argc, char** argv) fprintf(stream, " geometry: \n"); fprintf(stream, " - sphere: {radius: 2}\n"); fprintf(stream, " material:\n"); - fprintf(stream, " mirror: { reflectivity: 0.9, roughness: 0.1 }\n"); + fprintf(stream, " mirror: { reflectivity: 0.9, slope_error: 0.1 }\n"); fprintf(stream, " - name: lvl1b\n"); fprintf(stream, " primary: 0\n"); fprintf(stream, " geometry: *sphere\n"); @@ -191,8 +191,8 @@ main(int argc, char** argv) mirror = solparser_get_material_mirror(parser, mtl->data.mirror); CHK(mirror->reflectivity.type == SOLPARSER_MTL_DATA_REAL); CHK(mirror->reflectivity.value.real == 0.9); - CHK(mirror->roughness.type == SOLPARSER_MTL_DATA_REAL); - CHK(mirror->roughness.value.real == 0.1); + CHK(mirror->slope_error.type == SOLPARSER_MTL_DATA_REAL); + CHK(mirror->slope_error.value.real == 0.1); entity_id = solparser_entity_get_child(entity, 1); entity1b = solparser_get_entity(parser, entity_id); diff --git a/src/parser/test_solparser4.c b/src/parser/test_solparser4.c @@ -23,7 +23,7 @@ static const char* input[] = { " dni: 1\n", " spectrum: [{wavelength: 1, data: 1}]\n", "- material: &lambertian\n", - " mirror: { reflectivity: 0.2, roughness: 0.1 }\n", + " mirror: { reflectivity: 0.2, slope_error: 0.1 }\n", "- geometry: &cuboid\n", " - cuboid: { size: [1, 2, 3] }\n", " material: *lambertian\n", @@ -161,8 +161,8 @@ main(int argc, char** argv) mirror = solparser_get_material_mirror(parser, mtl->data.mirror); CHK(mirror->reflectivity.type == SOLPARSER_MTL_DATA_REAL); CHK(mirror->reflectivity.value.real == 0.2); - CHK(mirror->roughness.type == SOLPARSER_MTL_DATA_REAL); - CHK(mirror->roughness.value.real == 0.1); + CHK(mirror->slope_error.type == SOLPARSER_MTL_DATA_REAL); + CHK(mirror->slope_error.value.real == 0.1); CHK(mirror->ufacet_distrib == SOLPARSER_MICROFACET_BECKMANN); shape = solparser_get_shape(parser, obj->shape); diff --git a/src/parser/test_solparser_mirror.c b/src/parser/test_solparser_mirror.c @@ -21,7 +21,7 @@ check_object (struct solparser* parser, const struct solparser_object* obj, const double reflectivity, - const double roughness, + const double slope_error, const enum solparser_microfacet_distribution distrib) { const struct solparser_shape* shape; @@ -44,8 +44,8 @@ check_object mirror = solparser_get_material_mirror(parser, mtl->data.mirror); CHK(mirror->reflectivity.type == SOLPARSER_MTL_DATA_REAL); CHK(mirror->reflectivity.value.real == reflectivity); - CHK(mirror->roughness.type == SOLPARSER_MTL_DATA_REAL); - CHK(mirror->roughness.value.real == roughness); + CHK(mirror->slope_error.type == SOLPARSER_MTL_DATA_REAL); + CHK(mirror->slope_error.value.real == slope_error); CHK(mirror->ufacet_distrib == distrib); } @@ -67,16 +67,16 @@ main(int argc, char** argv) fprintf(stream, "- material: &specular\n"); fprintf(stream, " mirror:\n"); fprintf(stream, " reflectivity: 1\n"); - fprintf(stream, " roughness: 0\n"); + fprintf(stream, " slope_error: 0\n"); fprintf(stream, "- material: &beckmann\n"); fprintf(stream, " mirror:\n"); fprintf(stream, " reflectivity: 0.5\n"); - fprintf(stream, " roughness: 0.5\n"); + fprintf(stream, " slope_error: 0.5\n"); fprintf(stream, " microfacet: BECKMANN\n"); fprintf(stream, "- material: &pillbox\n"); fprintf(stream, " mirror:\n"); fprintf(stream, " reflectivity: 0.2\n"); - fprintf(stream, " roughness: 0.2\n"); + fprintf(stream, " slope_error: 0.2\n"); fprintf(stream, " microfacet: PILLBOX\n"); fprintf(stream, "\n"); fprintf(stream, "- entity:\n"); diff --git a/src/parser/test_solparser_normal_map.c b/src/parser/test_solparser_normal_map.c @@ -193,7 +193,7 @@ test_mirror(struct solparser* parser) fprintf(stream, " material: \n"); fprintf(stream, " mirror:\n"); fprintf(stream, " reflectivity: 1\n"); - fprintf(stream, " roughness: 0.1\n"); + fprintf(stream, " slope_error: 0.1\n"); fprintf(stream, " normal_map: { path: Normal map } \n"); rewind(stream); @@ -225,8 +225,8 @@ test_mirror(struct solparser* parser) mirror = solparser_get_material_mirror(parser, mtl->data.mirror); CHK(mirror->reflectivity.type == SOLPARSER_MTL_DATA_REAL); CHK(mirror->reflectivity.value.real == 1); - CHK(mirror->roughness.type == SOLPARSER_MTL_DATA_REAL); - CHK(mirror->roughness.value.real == 0.1); + CHK(mirror->slope_error.type == SOLPARSER_MTL_DATA_REAL); + CHK(mirror->slope_error.value.real == 0.1); CHK(SOLPARSER_ID_IS_VALID(mirror->normal_map) == 1); img = solparser_get_image(parser, mirror->normal_map); CHK(strcmp(str_cget(&img->filename), "Normal map") == 0); diff --git a/src/parser/test_solparser_spectrum.c b/src/parser/test_solparser_spectrum.c @@ -145,7 +145,7 @@ test_mirror(struct solparser* parser) fprintf(stream, " - { wavelength: 3.4, data: 0.5 }\n"); fprintf(stream, " - { wavelength: 1.2, data: 0.25 }\n"); fprintf(stream, " - { wavelength: 6.7, data: 0.125 }\n"); - fprintf(stream, " roughness:\n"); + fprintf(stream, " slope_error:\n"); fprintf(stream, " - { wavelength: 123, data: 0 }\n"); fprintf(stream, " - { wavelength: 456, data: 1 }\n"); rewind(stream); @@ -161,7 +161,7 @@ test_mirror(struct solparser* parser) CHK(mtl->type == SOLPARSER_MATERIAL_MIRROR); mirror = solparser_get_material_mirror(parser, mtl->data.mirror); CHK(mirror->reflectivity.type == SOLPARSER_MTL_DATA_SPECTRUM); - CHK(mirror->roughness.type == SOLPARSER_MTL_DATA_SPECTRUM); + CHK(mirror->slope_error.type == SOLPARSER_MTL_DATA_SPECTRUM); CHK(SOLPARSER_ID_IS_VALID(mirror->normal_map) == 0); spectrum = solparser_get_spectrum(parser, mirror->reflectivity.value.spectrum); @@ -173,7 +173,7 @@ test_mirror(struct solparser* parser) CHK(darray_spectrum_data_cdata_get(&spectrum->data)[1].data == 0.5); CHK(darray_spectrum_data_cdata_get(&spectrum->data)[2].data == 0.125); - spectrum = solparser_get_spectrum(parser, mirror->roughness.value.spectrum); + spectrum = solparser_get_spectrum(parser, mirror->slope_error.value.spectrum); CHK(darray_spectrum_data_size_get(&spectrum->data) == 2); CHK(darray_spectrum_data_cdata_get(&spectrum->data)[0].wavelength == 123); CHK(darray_spectrum_data_cdata_get(&spectrum->data)[1].wavelength == 456); diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml @@ -185,7 +185,7 @@ # <mirror> ::= # mirror: # reflectivity: REAL # in [0, 1] -# roughness: REAL # in [0, 1] +# slope_error: REAL # in [0, 1] # [ microfacet: <BECKMANN|PILLBOX> ] # @@ -196,42 +196,42 @@ - material: { mirror: { dummy: 0 } } --- # missing reflectivity parameter -- material: { mirror: { roughness: 0 } } +- material: { mirror: { slope_error: 0 } } --- -# missing roughness parameter +# missing slope_error parameter - material: { mirror: { reflectivity: 1 } } --- -# roughness should be a number -- material: { mirror: { roughness: "dummy" } } +# slope_error should be a number +- material: { mirror: { slope_error: "dummy" } } --- # reflectivity should be a number - material: { mirror: { reflectivity: "dummy" } } --- # -1 invalid -- material: { mirror: { reflectivity: -1, roughness: 0 } } +- material: { mirror: { reflectivity: -1, slope_error: 0 } } --- # 1.5 invalid -- material: { mirror: { reflectivity: 1.5, roughness: 0 } } +- material: { mirror: { reflectivity: 1.5, slope_error: 0 } } --- # -1 invalid -- material: { mirror: { reflectivity: 1, roughness: -1 } } +- material: { mirror: { reflectivity: 1, slope_error: -1 } } --- # 1.5 invalid -- material: { mirror: { reflectivity: 1, roughness: 1.5 } } +- material: { mirror: { reflectivity: 1, slope_error: 1.5 } } --- # 2x reflectivity - material: { mirror: { reflectivity: 1, reflectivity: 1 } } --- -# 2x roughness -- material: { mirror: { roughness: 1, roughness: 1 } } +# 2x slope_error +- material: { mirror: { slope_error: 1, slope_error: 1 } } --- # unknown microfacet -- material: { mirror: { roughness: 1, reflectivity: 1, microfacet: BECKBOX }} +- material: { mirror: { slope_error: 1, reflectivity: 1, microfacet: BECKBOX }} --- # 2x microfacet - material: mirror: - roughness: 1 + slope_error: 1 reflectivity: 1 microfacet: BECKMANN microfacet: PILLBOX diff --git a/src/parser/yaml/test_ok_1.yaml b/src/parser/yaml/test_ok_1.yaml @@ -3,7 +3,7 @@ - material: &mirror mirror: reflectivity: 1 - roughness: 0 + slope_error: 0 - geometry: &cylinder - material: *mirror @@ -25,7 +25,7 @@ - material: &mirror mirror: reflectivity: 1 - roughness: 0 + slope_error: 0 microfacet: BECKMANN - geometry: &cylinder @@ -47,7 +47,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0.314, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0.314, slope_error: 0.5 } } cylinder: { height: 10.12, radius: 0.32 } --- - sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] } @@ -55,7 +55,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } cylinder: { height: 1, radius: 1 } --- - sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] } @@ -68,5 +68,5 @@ mirror: microfacet: PILLBOX reflectivity: 0 - roughness: 0.5 + slope_error: 0.5 diff --git a/src/parser/yaml/test_ok_6.yaml b/src/parser/yaml/test_ok_6.yaml @@ -3,7 +3,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } plane: slices: 4 clip: @@ -19,7 +19,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } plane: clip: - operation: AND @@ -34,7 +34,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } parabol: slices: 40 focal: 18 @@ -47,7 +47,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } parabol: focal: 18 clip: @@ -59,7 +59,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } parabolic-cylinder: slices: 40 focal: 18 @@ -72,7 +72,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } parabolic-cylinder: focal: 18 clip: @@ -85,7 +85,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } hyperbol: slices: 40 focals: { real: 1, image: 1 } @@ -98,7 +98,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } hyperbol: focals: { real: 1, image: 1 } clip: @@ -110,7 +110,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } hyperbol: focals: { real: 1, image: 1 } clip: @@ -122,7 +122,7 @@ name: entity primary: 1 geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + - material: { mirror: { reflectivity: 0, slope_error: 0.5 } } hyperbol: focals: { real: 1, image: 1 } clip: diff --git a/src/solstice_c.h b/src/solstice_c.h @@ -80,12 +80,26 @@ solstice_create_ssol_spectrum struct ssol_spectrum** spectrum); extern LOCAL_SYM res_T +solstice_create_scaled_ssol_spectrum + (struct solstice* solstice, + const struct solparser_spectrum_id spectrum_id, + double scale_factor, /* Scale factor applied to the spectrum data */ + 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 +scaled_mtl_to_ssol_data + (struct solstice* solstice, + const struct solparser_mtl_data* mtl_data, + const double scale_factor, + 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 @@ -472,8 +472,21 @@ create_material_mirror res = mtl_to_ssol_data(solstice, &mirror->reflectivity, &param->reflectivity); if(res != RES_OK) goto error; - res = mtl_to_ssol_data(solstice, &mirror->roughness, &param->roughness); - if(res != RES_OK) goto error; + + switch(mirror->ufacet_distrib) { + case SOLPARSER_MICROFACET_BECKMANN: + /* For the beckmann distribution, convert the slope error to the + * corresponding beckmann rougness by multiplying it by sqrt(2) */ + res = scaled_mtl_to_ssol_data + (solstice, &mirror->slope_error, sqrt(2), &param->roughness); + break; + case SOLPARSER_MICROFACET_PILLBOX: + /* Direct correspondance between the solver roughness parameter and the + * provided slope error */ + res = mtl_to_ssol_data(solstice, &mirror->slope_error, &param->roughness); + break; + default: FATAL("Unreachable code.\n"); break; + } if(!SOLPARSER_ID_IS_VALID(mirror->normal_map)) { shader.normal = mtl_get_normal; @@ -589,9 +602,10 @@ error: * Local functions ******************************************************************************/ res_T -mtl_to_ssol_data +scaled_mtl_to_ssol_data (struct solstice* solstice, const struct solparser_mtl_data* mtl_data, + const double scale_factor, struct ssol_data* data) { struct ssol_spectrum* spectrum = NULL; @@ -600,16 +614,16 @@ mtl_to_ssol_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; + case SOLPARSER_MTL_DATA_REAL: + ssol_data_set_real(data, mtl_data->value.real*scale_factor); + break; + case SOLPARSER_MTL_DATA_SPECTRUM: + res = solstice_create_scaled_ssol_spectrum + (solstice, mtl_data->value.spectrum, scale_factor, &spectrum); + if(res != RES_OK) goto error; + ssol_data_set_spectrum(data, spectrum); + break; + default: FATAL("Unreachable code.\n"); break; } exit: @@ -620,6 +634,15 @@ error: goto exit; } +extern LOCAL_SYM res_T +mtl_to_ssol_data + (struct solstice* solstice, + const struct solparser_mtl_data* mtl_data, + struct ssol_data* data) +{ + return scaled_mtl_to_ssol_data(solstice, mtl_data, 1.0, data); +} + res_T solstice_create_ssol_material (struct solstice* solstice, diff --git a/src/solstice_spectrum.c b/src/solstice_spectrum.c @@ -15,16 +15,21 @@ #include "solstice_c.h" +struct context { + double scale_factor; + const struct solparser_spectrum_data* spectrum_data; +}; + /******************************************************************************* * Helper function ******************************************************************************/ static void -get_wavelength(const size_t i, double* wlen, double* data, void* ctx) +get_wavelength(const size_t i, double* wlen, double* data, void* context) { - const struct solparser_spectrum_data* specdata = ctx; - ASSERT(wlen && data && ctx); - *wlen = specdata[i].wavelength; - *data = specdata[i].data; + const struct context* ctx = context; + ASSERT(wlen && data && context); + *wlen = ctx->spectrum_data[i].wavelength; + *data = ctx->spectrum_data[i].data * ctx->scale_factor; } /******************************************************************************* @@ -36,8 +41,19 @@ solstice_create_ssol_spectrum const struct solparser_spectrum_id spectrum_id, struct ssol_spectrum** out_spectrum) { + return solstice_create_scaled_ssol_spectrum + (solstice, spectrum_id, 1, out_spectrum); +} + +res_T +solstice_create_scaled_ssol_spectrum + (struct solstice* solstice, + const struct solparser_spectrum_id spectrum_id, + const double scale_factor, + struct ssol_spectrum** out_spectrum) +{ + struct context ctx; struct ssol_spectrum* spectrum = NULL; - const struct solparser_spectrum_data* data; const struct solparser_spectrum* spec; size_t nwlens; res_T res = RES_OK; @@ -51,8 +67,9 @@ solstice_create_ssol_spectrum 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); + ctx.spectrum_data = darray_spectrum_data_cdata_get(&spec->data); + ctx.scale_factor = scale_factor; + res = ssol_spectrum_setup(spectrum, get_wavelength, nwlens, &ctx); if(res != RES_OK) { fprintf(stderr, "Could not setup the Solstice Solver spectrum.\n"); goto error; diff --git a/yaml/beam_down.yaml b/yaml/beam_down.yaml @@ -9,7 +9,7 @@ - sun: &sun { dni: 1 } -- material: &mirror { mirror: { reflectivity: 1, roughness: 0 } } +- material: &mirror { mirror: { reflectivity: 1, slope_error: 0 } } - material: &black { matte: { reflectivity: 0 } } - material: &virtual { virtual: } @@ -105,4 +105,4 @@ name: "heliostat5" transform: { translation: [100, 30, 0] } children: [ *temp_heliostat150 ] - -\ No newline at end of file + diff --git a/yaml/test01.yaml b/yaml/test01.yaml @@ -2,9 +2,9 @@ - material: &specular front: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } back: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } - geometry: &small_square diff --git a/yaml/test02.yaml b/yaml/test02.yaml @@ -1,7 +1,7 @@ - sun: &sun { dni: 1 } - material: &specular - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } - geometry: &small_square diff --git a/yaml/test03.yaml b/yaml/test03.yaml @@ -2,9 +2,9 @@ - material: &specular front: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } back: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } - geometry: &small_square - material: *specular diff --git a/yaml/test04.yaml b/yaml/test04.yaml @@ -2,9 +2,9 @@ - material: &specular front: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } back: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } - material: &black matte: { reflectivity: 0 } diff --git a/yaml/test06.yaml b/yaml/test06.yaml @@ -7,7 +7,7 @@ matte: { reflectivity: 1 } - material: &specular - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } - template: &self_oriented_parabol diff --git a/yaml/test07.yaml b/yaml/test07.yaml @@ -5,9 +5,9 @@ - material: &specular front: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } back: - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } - geometry: &hemisphere - material: *specular diff --git a/yaml/test08.yaml b/yaml/test08.yaml @@ -10,7 +10,7 @@ matte: { reflectivity: 1 } - material: &specular - mirror: { reflectivity: 1, roughness: 0 } + mirror: { reflectivity: 1, slope_error: 0 } - template: &self_oriented_parabol name: "pivot"