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 969b4eab6f6174fcc569a8bbd73b6493d333b5da
parent 288740d34ef6ae423beca6fdde8bc060e242eca8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 24 Mar 2017 14:50:17 +0100

Update the specification of the dielectric materials

Diffstat:
Mdoc/input | 8++++++--
Msrc/parser/solparser.c | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/parser/solparser.h | 5+++++
Msrc/parser/solparser_material.h | 11+++++++++--
Msrc/parser/test_solparser8.c | 31+++++++++++++++++++++++++------
Msrc/parser/yaml/test_ko_0.yaml | 37++++++++++++++++++++++++-------------
Msrc/solstice_material.c | 73+++++++++----------------------------------------------------------------
7 files changed, 198 insertions(+), 96 deletions(-)

diff --git a/doc/input b/doc/input @@ -223,8 +223,12 @@ <dielectric> ::= dielectric: - eta_i: REAL # in ]0, INF) - eta_t: REAL # in ]0, INF) + medium_i: <dielectric-medium> + medium_t: <dielectric-medium> + +<dielectric-medium> ::= + refractive_index: REAL # in ]0, INF) + absorptivity: REAL # in [0, INF) <matte> ::= matte: 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 mediums */ +#define DARRAY_NAME medium +#define DARRAY_DATA struct solparser_medium +#include <rsys/dynamic_array.h> + /* Declare the array of dielectric materials */ #define DARRAY_NAME dielectric #define DARRAY_DATA struct solparser_material_dielectric @@ -193,6 +198,7 @@ struct solparser { struct htable_yaml2sols yaml2mtls; /* Cache of materials */ struct darray_material mtls; struct darray_material2 mtls2; /* Double sided materials */ + struct darray_medium mediums; struct darray_dielectric dielectrics; struct darray_matte mattes; struct darray_mirror mirrors; @@ -392,6 +398,7 @@ parser_clear(struct solparser* parser) htable_yaml2sols_clear(&parser->yaml2mtls); darray_material_clear(&parser->mtls); darray_material2_clear(&parser->mtls2); + darray_medium_clear(&parser->mediums); darray_dielectric_clear(&parser->dielectrics); darray_matte_clear(&parser->mattes); darray_mirror_clear(&parser->mirrors); @@ -445,6 +452,7 @@ parser_release(ref_T* ref) htable_yaml2sols_release(&parser->yaml2mtls); darray_material_release(&parser->mtls); darray_material2_release(&parser->mtls2); + darray_medium_release(&parser->mediums); darray_dielectric_release(&parser->dielectrics); darray_matte_release(&parser->mattes); darray_mirror_release(&parser->mirrors); @@ -867,13 +875,105 @@ error: * Material ******************************************************************************/ static res_T +parse_medium + (struct solparser* parser, + yaml_document_t* doc, + const yaml_node_t* medium, + struct solparser_medium_id* out_imedium) +{ + enum { ABSORPTIVITY, REFRACTIVE_INDEX }; + struct solparser_medium* mdm = NULL; + size_t imedium = SIZE_MAX; + int mask = 0; /* Register the parsed attributes */ + intptr_t i, n; + res_T res = RES_OK; + ASSERT(doc && medium && out_imedium); + + if(medium->type != YAML_MAPPING_NODE) { + log_err(parser, medium, "expect a mapping of medium attributes.\n"); + res = RES_BAD_ARG; + goto error; + } + + /* Allocate the medium */ + imedium = darray_medium_size_get(&parser->mediums); + res = darray_medium_resize(&parser->mediums, imedium + 1); + if(res != RES_OK) { + log_err(parser, medium, "could not allocate the medium.\n"); + res = RES_BAD_ARG; + goto error; + } + mdm = darray_medium_data_get(&parser->mediums) + imedium; + + n = medium->data.mapping.pairs.top - medium->data.mapping.pairs.start; + FOR_EACH(i, 0, n) { + yaml_node_t* key; + yaml_node_t* val; + + key = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].value); + if(key->type != YAML_SCALAR_NODE) { + log_err(parser, key, "expect a medium 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 medium is already defined.\n");\ + res = RES_BAD_ARG; \ + goto error; \ + } \ + mask |= BIT(Flag); \ + } (void)0 + if(!strcmp((char*)key->data.scalar.value, "absorptivity")) { + SETUP_MASK(ABSORPTIVITY, "absorptivity"); + res = parse_real(parser, 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); + } else { + log_err(parser, key, "unknown medium 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, medium, "the "Name" of the medium is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(ABSORPTIVITY, "absorptivity"); + CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index"); + #undef CHECK_PARAM + +exit: + out_imedium->i = imedium; + return res; +error: + if(imedium) { + darray_medium_pop_back(&parser->mediums); + imedium = SIZE_MAX; + } + goto exit; +} + +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 }; + enum { MEDIUM_I, MEDIUM_T }; struct solparser_material_dielectric* mtl = NULL; size_t imtl = SIZE_MAX; int mask = 0; /* Register the parsed attributes */ @@ -919,12 +1019,12 @@ parse_material_dielectric } \ 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); + if(!strcmp((char*)key->data.scalar.value, "medium_i")) { + SETUP_MASK(MEDIUM_I, "medium_i"); + res = parse_medium(parser, doc, val, &mtl->medium_i); + } else if(!strcmp((char*)key->data.scalar.value, "medium_t")) { + SETUP_MASK(MEDIUM_T, "medium_t"); + res = parse_medium(parser, doc, val, &mtl->medium_t); } else { log_err(parser, key, "unknown dielectric parameter `%s'.\n", key->data.scalar.value); @@ -945,9 +1045,10 @@ parse_material_dielectric res = RES_BAD_ARG; \ goto error; \ } (void)0 - CHECK_PARAM(ETA_I, "eta_i"); - CHECK_PARAM(ETA_T, "eta_t"); + CHECK_PARAM(MEDIUM_I, "medium_i"); + CHECK_PARAM(MEDIUM_T, "medium_t"); #undef CHECK_PARAM + exit: out_imtl->i = imtl; return res; @@ -3732,6 +3833,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_medium_init(mem_allocator, &parser->mediums); darray_dielectric_init(mem_allocator, &parser->dielectrics); darray_matte_init(mem_allocator, &parser->mattes); darray_mirror_init(mem_allocator, &parser->mirrors); @@ -4052,6 +4154,15 @@ solparser_get_geometry return darray_geometry_cdata_get(&parser->geometries) + geom.i; } +const struct solparser_medium* +solparser_get_medium + (const struct solparser* parser, + const struct solparser_medium_id medium) +{ + ASSERT(parser && medium.i < darray_medium_size_get(&parser->mediums)); + return darray_medium_cdata_get(&parser->mediums) + medium.i; +} + const struct solparser_material* solparser_get_material (const struct solparser* parser, diff --git a/src/parser/solparser.h b/src/parser/solparser.h @@ -92,6 +92,11 @@ solparser_get_geometry (const struct solparser* parser, const struct solparser_geometry_id geom); +extern LOCAL_SYM const struct solparser_medium* +solparser_get_medium + (const struct solparser* parser, + const struct solparser_medium_id medium); + extern LOCAL_SYM const struct solparser_material* solparser_get_material (const struct solparser* parser, diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h @@ -26,9 +26,16 @@ enum solparser_material_type { SOLPARSER_MATERIAL_VIRTUAL }; +struct solparser_medium { + double refractive_index; + double absorptivity; +}; + +struct solparser_medium_id { size_t i; }; + 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_medium_id medium_i; /* Medium the material "looks at" */ + struct solparser_medium_id medium_t; /* Opposite medium */ }; struct solparser_material_dielectric_id { size_t i; }; diff --git a/src/parser/test_solparser8.c b/src/parser/test_solparser8.c @@ -27,6 +27,7 @@ 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_material_double_sided* mtl2; const struct solparser_material* mtl; const struct solparser_material_dielectric* dielec; @@ -48,8 +49,18 @@ main(int argc, char** argv) 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"); + fprintf(stream, " front:\n"); + fprintf(stream, " dielectric:\n"); + fprintf(stream, " medium_i: &outside\n"); + 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, " back:\n"); + fprintf(stream, " dielectric:\n"); + fprintf(stream, " medium_i: *inside\n"); + fprintf(stream, " medium_t: *outside\n"); rewind(stream); CHECK(solparser_setup(parser, NULL, stream), RES_OK); @@ -77,14 +88,22 @@ 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); - CHECK(dielec->eta_i, 1.0); - CHECK(dielec->eta_t, 1.5); + 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); 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); + 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_load(parser), RES_BAD_OP); solparser_ref_put(parser); diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml @@ -251,32 +251,43 @@ # # <dielectric> ::= # dielectric: -# eta_i: REAL # in ]0, INF) -# eta_t: REAL # in ]0, INF) +# medium_i: <dielectric-medium> +# medium_t: <dielectric-medium> # -# invalid eta_i +# invalid refractive_index - material: - dielectric: { eta_i: -1, eta_t: 1 } + dielectric: + medium_i: &m { refractive_index: 0, absorptivity: 0 } + medium_t: *m --- +# invalid absorptivity - material: - dielectric: { eta_i: 0, eta_t: 1 } + dielectric: + medium_i: &m { refractive_index: 1, absorptivity: -1 } + medium_t: *m --- -# invalid eta_t +# missing refractive_index - material: - dielectric: { eta_i: 1, eta_t: -1 } + dielectric: + medium_i: &m { absorptivity: 0 } + medium_t: *m --- -# invalid eta_t +# missing absorptivity - material: - dielectric: { eta_i: 1, eta_t: 0 } + dielectric: + medium_i: &m { refractive_index: 1 } + medium_t: *m --- -# missing eta_t +# missing medium_i - material: - dielectric: { eta_i: 1 } + dielectric: + medium_t: { refractive_index: 1, absorptivity: 0 } --- -# missing eta_i +# missing medium_t - material: - dielectric: { eta_t: 1 } + dielectric: + medium_i: { refractive_index: 1, absorptivity: 0 } --- # diff --git a/src/solstice_material.c b/src/solstice_material.c @@ -18,11 +18,6 @@ #include <solstice/ssol.h> -struct dielectric_param { - double eta_i; - double eta_t; -}; - struct matte_param { double reflectivity; }; @@ -60,40 +55,6 @@ mtl_get_normal } static void -dielectric_get_eta_i - (struct ssol_device* dev, - struct ssol_param_buffer* buf, - const double wavelength, - const double P[3], - const double Ng[3], - const double Ns[3], - const double uv[2], - const double w[3], - double* val) -{ - const struct dielectric_param* param = ssol_param_buffer_get(buf); - (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w; - *val = param->eta_i; -} - -static void -dielectric_get_eta_t - (struct ssol_device* dev, - struct ssol_param_buffer* buf, - const double wavelength, - const double P[3], - const double Ng[3], - const double Ns[3], - const double uv[2], - const double w[3], - double* val) -{ - const struct dielectric_param* param = ssol_param_buffer_get(buf); - (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w; - *val = param->eta_t; -} - -static void matte_get_reflectivity (struct ssol_device* dev, struct ssol_param_buffer* buf, @@ -201,10 +162,10 @@ create_material_dielectric const struct solparser_material_dielectric* dielectric, struct ssol_material** out_mtl) { + const struct solparser_medium* medium_i; + const struct solparser_medium* medium_t; struct ssol_dielectric_shader shader = SSOL_DIELECTRIC_SHADER_NULL; struct ssol_material* mtl = NULL; - struct ssol_param_buffer* pbuf = NULL; - struct dielectric_param* param; res_T res = RES_OK; ASSERT(solstice && dielectric && out_mtl); @@ -215,32 +176,16 @@ create_material_dielectric goto error; } - res = ssol_param_buffer_create - (solstice->ssol, sizeof(struct dielectric_param), &pbuf); - if(res != RES_OK) { - fprintf(stderr, "Could not create the Solstice Solver parameter buffer.\n"); - goto error; - } - - param = ssol_param_buffer_allocate(pbuf, sizeof(struct dielectric_param), - ALIGNOF(struct dielectric_param)); - if(!param) { - fprintf(stderr, "Could not allocate the dielectric parameters.\n"); - res = RES_MEM_ERR; - goto error; - } - - param->eta_i = dielectric->eta_i; - param->eta_t = dielectric->eta_t; - + medium_i = solparser_get_medium(solstice->parser, dielectric->medium_i); + medium_t = solparser_get_medium(solstice->parser, dielectric->medium_t); shader.normal = mtl_get_normal; - shader.eta_i = dielectric_get_eta_i; - shader.eta_t = dielectric_get_eta_t; - SSOL(dielectric_set_shader(mtl, &shader)); - SSOL(material_set_param_buffer(mtl, pbuf)); + SSOL(dielectric_setup(mtl, &shader, + medium_i->refractive_index, + medium_t->refractive_index, + medium_i->absorptivity, + medium_t->absorptivity)); exit: - if(pbuf) SSOL(param_buffer_ref_put(pbuf)); *out_mtl = mtl; return res; error: