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 21dd82121e9c7e88a897cfff52647d5aeb4a7843
parent 81b84a2d012892840aa5c9810ee07b1de38cf335
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu,  9 Mar 2017 16:39:58 +0100

Merge remote-tracking branch 'origin/develop' into feature_path_tracing

Diffstat:
Mcmake/CMakeLists.txt | 16++++++++++++++++
Mcmake/parser/CMakeLists.txt | 2+-
Mcmake/receivers/CMakeLists.txt | 1+
Mdoc/input | 16+++++++++++++++-
Msrc/parser/solparser.c | 204++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/parser/solparser.h | 5+++++
Msrc/parser/solparser_shape.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/parser/test_solparser3.c | 48+++++++++++++++++++++++++++++++++++++++++++++---
Msrc/parser/test_solparser6.c | 41++++++++++++++++++++++++++++++++++++++---
Msrc/parser/yaml/test_ko_0.yaml | 149++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/solstice.c | 22+++++++++++++++++++---
Msrc/solstice.h | 1+
Msrc/solstice_entity.c | 2+-
Msrc/solstice_object.c | 26++++++++++++++++++++++++++
Asrc/test_solstice_simulation.c | 327+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/beam_down.ref | 12++++++++++++
Ayaml/beam_down.yaml | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/beam_down_receiver.yaml | 3+++
Ayaml/test01.ref | 5+++++
Ayaml/test01.yaml | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/test01_receiver.yaml | 1+
Ayaml/test02.ref | 5+++++
Ayaml/test02.yaml | 47+++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/test02_receiver.yaml | 1+
Ayaml/test03.ref | 5+++++
Ayaml/test03.yaml | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/test03_receiver.yaml | 1+
Ayaml/test04.ref | 4++++
Ayaml/test04.yaml | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayaml/test04_receiver.yaml | 1+
Ayaml/test05.ref | 5+++++
Ayaml/test05.yaml | 44++++++++++++++++++++++++++++++++++++++++++++
Ayaml/test05_receiver.yaml | 1+
33 files changed, 1287 insertions(+), 23 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -140,6 +140,22 @@ if(NOT NO_TEST) new_test(test_solstice_args) + build_test(test_solstice_simulation) + function(add_test_simulation _name) + add_test(NAME test_solstice_simulation_${_name} + COMMAND test_solstice_simulation + $<TARGET_FILE:solstice> + ${SOLSTICE_SOURCE_DIR}/../yaml/ + ${_name}) + endfunction() + + add_test_simulation(beam_down) + add_test_simulation(test01) + add_test_simulation(test02) + add_test_simulation(test03) + add_test_simulation(test04) + add_test_simulation(test05) + endif() ################################################################################ diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -39,7 +39,7 @@ set(SOLPARSER_FILES_INC solparser_shape.h solparser_sun.h) -# Prepend each file in the `SOLSTICE_FILES_<SRC|INC>' list by `SOLSTICE_SOURCE_DIR' +# Prepend each file in the `SOLPARSER_FILES_<SRC|INC>' list by `SOLPARSER_SOURCE_DIR' rcmake_prepend_path(SOLPARSER_FILES_SRC ${SOLPARSER_SOURCE_DIR}) rcmake_prepend_path(SOLPARSER_FILES_INC ${SOLPARSER_SOURCE_DIR}) rcmake_prepend_path(SOLPARSER_FILES_DOC ${PROJECT_SOURCE_DIR}/../) diff --git a/cmake/receivers/CMakeLists.txt b/cmake/receivers/CMakeLists.txt @@ -65,6 +65,7 @@ if(NOT NO_TEST) ${SRCVL_SOURCE_DIR}/yaml/test_ko.yaml) new_test(test_srcvl2) + rcmake_copy_runtime_libraries(test_srcvl) endif() diff --git a/doc/input b/doc/input @@ -130,6 +130,7 @@ # | <obj> # | <parabol> # | <parabolic-cylinder> +# | <hyperbol> # | <plane> # | <sphere> # | <stl> @@ -158,6 +159,16 @@ # focal: REAL # in ]0, INF) # clip: <polyclip-list> # +# <hyperbol> ::= # (x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0 +# hyperbol: # with g = img_focal + real_focal; f = real_focal / g; +# # a^2 = g^2(f - f^2); b = g(f - 1/2); z0 = |b| + g/2 +# focals: <hyperboloid_focals> +# clip: <polyclip-list> +# +# <hyperboloid_focals> ::= +# real: REAL # in ]0, INF) +# image: REAL # in ]0, INF) +# # <plane> ::= # plane: # clip: <polyclip-list> @@ -247,7 +258,10 @@ # # <anchor-data> ::= # name: STRING -# position: <real3> +# <position-description> +# +# <position-description> ::= +# position: <real3> | hyperboloid_image_focals: <hyperboloid_focals> # # # "self" references the first level entity # <entity-identifier> ::= diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -104,6 +104,16 @@ struct target_alias { solparser_shape_paraboloid_copy_and_release #include <rsys/dynamic_array.h> +/* Declare the array of hyperboloids */ +#define DARRAY_NAME hyperboloid +#define DARRAY_DATA struct solparser_shape_hyperboloid +#define DARRAY_FUNCTOR_INIT solparser_shape_hyperboloid_init +#define DARRAY_FUNCTOR_RELEASE solparser_shape_hyperboloid_release +#define DARRAY_FUNCTOR_COPY solparser_shape_hyperboloid_copy +#define DARRAY_FUNCTOR_COPY_AND_RELEASE \ + solparser_shape_hyperboloid_copy_and_release +#include <rsys/dynamic_array.h> + /* Declare the array of planes */ #define DARRAY_NAME plane #define DARRAY_DATA struct solparser_shape_plane @@ -192,6 +202,7 @@ struct solparser { struct darray_impgeom objs; struct darray_paraboloid parabols; struct darray_paraboloid parabolic_cylinders; + struct darray_hyperboloid hyperbols; struct darray_plane planes; struct darray_sphere spheres; struct darray_impgeom stls; @@ -389,6 +400,7 @@ parser_clear(struct solparser* parser) darray_impgeom_clear(&parser->objs); darray_paraboloid_clear(&parser->parabols); darray_paraboloid_clear(&parser->parabolic_cylinders); + darray_hyperboloid_clear(&parser->hyperbols); darray_plane_clear(&parser->planes); darray_sphere_clear(&parser->spheres); darray_impgeom_clear(&parser->stls); @@ -440,6 +452,7 @@ parser_release(ref_T* ref) darray_impgeom_release(&parser->objs); darray_paraboloid_release(&parser->parabols); darray_paraboloid_release(&parser->parabolic_cylinders); + darray_hyperboloid_release(&parser->hyperbols); darray_plane_release(&parser->planes); darray_sphere_release(&parser->spheres); darray_impgeom_release(&parser->stls); @@ -1925,6 +1938,170 @@ error: } static res_T +parse_focals_description + (struct solparser* parser, + yaml_document_t* doc, + const yaml_node_t* desc, + struct hyperboloid_focals* focals) +{ + enum { REAL, IMAGE }; + intptr_t i, n; + int mask = 0; /* Register the parsed attributes */ + res_T res = RES_OK; + ASSERT(doc && desc && focals); + + if (desc->type != YAML_MAPPING_NODE) { + log_err(parser, desc, "expect a mapping of focal parameters.\n"); + res = RES_BAD_ARG; + goto error; + } + + n = desc->data.mapping.pairs.top - desc->data.mapping.pairs.start; + FOR_EACH(i, 0, n) { + yaml_node_t* key; + yaml_node_t* val; + + key = yaml_document_get_node(doc, desc->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, desc->data.mapping.pairs.start[i].value); + if (key->type != YAML_SCALAR_NODE) { + log_err(parser, key, "expect focal parameters.\n"); + res = RES_BAD_ARG; + goto error; + } + #define SETUP_MASK(Flag, Name) { \ + if(mask & BIT(Flag)) { \ + log_err(parser, key, \ + "the focal parameter `"Name"' is already defined.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } \ + mask |= BIT(Flag); \ + } (void)0 + if (!strcmp((char*) key->data.scalar.value, "real")) { + SETUP_MASK(REAL, "real"); + res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &focals->real); + } + else if (!strcmp((char*) key->data.scalar.value, "image")) { + SETUP_MASK(IMAGE, "image"); + res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &focals->image); + } + 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, desc, \ + "the focal parameter `"Name"' is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(REAL, "real"); + CHECK_PARAM(IMAGE, "image"); + #undef CHECK_PARAM + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_hyperboloid + (struct solparser* parser, + yaml_document_t* doc, + const yaml_node_t* hyperboloid, + struct solparser_shape_hyperboloid_id* out_ishape) +{ + enum { CLIP, FOCAL }; + struct solparser_shape_hyperboloid* shape = NULL; + size_t ishape = SIZE_MAX; + intptr_t i, n; + int mask = 0; /* Register the parsed attributes */ + res_T res = RES_OK; + ASSERT(doc && hyperboloid && out_ishape); + + if (hyperboloid->type != YAML_MAPPING_NODE) { + log_err(parser, hyperboloid, "expect a mapping of hyperbol parameters.\n"); + res = RES_BAD_ARG; + goto error; + } + + /* Allocate a hyperboloid shape */ + ishape = darray_hyperboloid_size_get(&parser->hyperbols); + res = darray_hyperboloid_resize(&parser->hyperbols, ishape + 1); + if (res != RES_OK) { + log_err(parser, hyperboloid, "could not allocate the hyperbol shape.\n"); + goto error; + } + shape = darray_hyperboloid_data_get(&parser->hyperbols) + ishape; + + n = hyperboloid->data.mapping.pairs.top - hyperboloid->data.mapping.pairs.start; + FOR_EACH(i, 0, n) { + yaml_node_t* key; + yaml_node_t* val; + + key = yaml_document_get_node(doc, hyperboloid->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, hyperboloid->data.mapping.pairs.start[i].value); + if (key->type != YAML_SCALAR_NODE) { + log_err(parser, key, "expect hyperbol parameters.\n"); + res = RES_BAD_ARG; + goto error; + } + #define SETUP_MASK(Flag, Name) { \ + if(mask & BIT(Flag)) { \ + log_err(parser, key, \ + "the hyperbol parameter `"Name"' is already defined.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } \ + mask |= BIT(Flag); \ + } (void)0 + if (!strcmp((char*) key->data.scalar.value, "clip")) { + SETUP_MASK(CLIP, "clip"); + res = parse_clip(parser, doc, val, &shape->polyclips); + } + else if (!strcmp((char*) key->data.scalar.value, "focals")) { + SETUP_MASK(FOCAL, "focals"); + res = parse_focals_description(parser, doc, val, &shape->focals); + } + else { + log_err(parser, key, "unknown hyperbol 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, hyperboloid, \ + "the hyperbol parameter `"Name"' is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(CLIP, "clip"); + CHECK_PARAM(FOCAL, "focals"); + #undef CHECK_PARAM + +exit : + out_ishape->i = ishape; + return res; +error: + if (shape) { + darray_hyperboloid_pop_back(&parser->hyperbols); + ishape = SIZE_MAX; + } + goto exit; +} + +static res_T parse_plane (struct solparser* parser, yaml_document_t* doc, @@ -2197,6 +2374,11 @@ parse_object shape->type = SOLPARSER_SHAPE_PARABOLIC_CYLINDER; res = parse_paraboloid (parser, doc, val, shape->type, &shape->data.parabolic_cylinder); + } + else if (!strcmp((char*) key->data.scalar.value, "hyperbol")) { + SETUP_MASK(SHAPE, "shape"); + shape->type = SOLPARSER_SHAPE_HYPERBOL; + res = parse_hyperboloid(parser, doc, val, &shape->data.hyperbol); } else if(!strcmp((char*)key->data.scalar.value, "plane")) { SETUP_MASK(SHAPE, "shape"); shape->type = SOLPARSER_SHAPE_PLANE; @@ -2466,8 +2648,16 @@ parse_anchor SETUP_MASK(NAME, "name"); res = parse_identifier_string(parser, val, &solanchor->name); } else if(!strcmp((char*)key->data.scalar.value, "position")) { - SETUP_MASK(POSITION, "position"); + SETUP_MASK(POSITION, "position description"); res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solanchor->position); + } + else if (!strcmp((char*) key->data.scalar.value, "hyperboloid_image_focals")) + { + struct hyperboloid_focals focals; + SETUP_MASK(POSITION, "position description"); + res = parse_focals_description(parser, doc, val, &focals); + if (res != RES_OK) goto error; + d3(solanchor->position, 0, 0, focals.image); } else { log_err(parser, key, "unknown anchor parameter `%s'.\n", key->data.scalar.value); @@ -2488,7 +2678,7 @@ parse_anchor goto error; \ } (void)0 CHECK_PARAM(NAME, "name"); - CHECK_PARAM(POSITION, "position"); + CHECK_PARAM(POSITION, "position description"); #undef CHECK_PARAM res = anchor_register_name(parser, anchor, htable, isolanchor); @@ -3442,6 +3632,7 @@ solparser_create darray_impgeom_init(mem_allocator, &parser->objs); darray_paraboloid_init(mem_allocator, &parser->parabols); darray_paraboloid_init(mem_allocator, &parser->parabolic_cylinders); + darray_hyperboloid_init(mem_allocator, &parser->hyperbols); darray_plane_init(mem_allocator, &parser->planes); darray_sphere_init(mem_allocator, &parser->spheres); darray_impgeom_init(mem_allocator, &parser->stls); @@ -3874,6 +4065,15 @@ solparser_get_shape_parabolic_cylinder return darray_paraboloid_cdata_get(&parser->parabolic_cylinders)+paraboloid.i; } +const struct solparser_shape_hyperboloid* +solparser_get_shape_hyperbol + (const struct solparser* parser, + const struct solparser_shape_hyperboloid_id hyperboloid) +{ + ASSERT(parser && hyperboloid.i < darray_hyperboloid_size_get(&parser->hyperbols)); + return darray_hyperboloid_cdata_get(&parser->hyperbols) + hyperboloid.i; +} + const struct solparser_shape_plane* solparser_get_shape_plane (const struct solparser* parser, diff --git a/src/parser/solparser.h b/src/parser/solparser.h @@ -162,6 +162,11 @@ solparser_get_shape_parabolic_cylinder (const struct solparser* parser, const struct solparser_shape_paraboloid_id paraboloid); +extern LOCAL_SYM const struct solparser_shape_hyperboloid* +solparser_get_shape_hyperbol + (const struct solparser* parser, + const struct solparser_shape_hyperboloid_id hyperboloid); + extern LOCAL_SYM const struct solparser_shape_plane* solparser_get_shape_plane (const struct solparser* parser, diff --git a/src/parser/solparser_shape.h b/src/parser/solparser_shape.h @@ -32,6 +32,7 @@ enum solparser_shape_type { SOLPARSER_SHAPE_OBJ, /* Imported Alias Wavefront obj */ SOLPARSER_SHAPE_PARABOL, SOLPARSER_SHAPE_PARABOLIC_CYLINDER, + SOLPARSER_SHAPE_HYPERBOL, SOLPARSER_SHAPE_PLANE, SOLPARSER_SHAPE_SPHERE, SOLPARSER_SHAPE_STL /* Imported STereo Lithography */ @@ -198,6 +199,58 @@ solparser_shape_paraboloid_copy_and_release } /******************************************************************************* +* Hyperboloid shape +******************************************************************************/ +struct hyperboloid_focals { + double real, image; +}; + +#define HYPERBOLOID_FOCALS_NULL__ { 0, 0 } +static const struct hyperboloid_focals +HYPERBOLOID_FOCALS_NULL = HYPERBOLOID_FOCALS_NULL__; + +struct solparser_shape_hyperboloid { + struct hyperboloid_focals focals; + struct darray_polyclip polyclips; +}; + +static INLINE void +solparser_shape_hyperboloid_init + (struct mem_allocator* allocator, + struct solparser_shape_hyperboloid* hyperboloid) +{ + ASSERT(hyperboloid); + darray_polyclip_init(allocator, &hyperboloid->polyclips); +} + +static INLINE void +solparser_shape_hyperboloid_release(struct solparser_shape_hyperboloid* hyperboloid) +{ + ASSERT(hyperboloid); + darray_polyclip_release(&hyperboloid->polyclips); +} + +static INLINE res_T +solparser_shape_hyperboloid_copy + (struct solparser_shape_hyperboloid* dst, + const struct solparser_shape_hyperboloid* src) +{ + ASSERT(dst && src); + dst->focals = src->focals; + return darray_polyclip_copy(&dst->polyclips, &src->polyclips); +} + +static INLINE res_T +solparser_shape_hyperboloid_copy_and_release + (struct solparser_shape_hyperboloid* dst, + struct solparser_shape_hyperboloid* src) +{ + ASSERT(dst && src); + dst->focals = src->focals; + return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips); +} + +/******************************************************************************* * Plane shape ******************************************************************************/ struct solparser_shape_plane { @@ -260,6 +313,7 @@ struct solparser_shape_cuboid_id { size_t i; }; struct solparser_shape_cylinder_id { size_t i; }; struct solparser_shape_imported_geometry_id { size_t i; }; struct solparser_shape_paraboloid_id { size_t i; }; +struct solparser_shape_hyperboloid_id { size_t i; }; struct solparser_shape_plane_id { size_t i; }; struct solparser_shape_sphere_id { size_t i; }; @@ -271,6 +325,7 @@ struct solparser_shape { struct solparser_shape_imported_geometry_id obj; struct solparser_shape_paraboloid_id parabol; struct solparser_shape_paraboloid_id parabolic_cylinder; + struct solparser_shape_hyperboloid_id hyperbol; struct solparser_shape_plane_id plane; struct solparser_shape_sphere_id sphere; struct solparser_shape_imported_geometry_id stl; diff --git a/src/parser/test_solparser3.c b/src/parser/test_solparser3.c @@ -25,6 +25,13 @@ static const char* input[] = { "- geometry: &cylinder2\n", " - cylinder: { radius: 1, height: 10 }\n", " material: *lambertian\n", + "- geometry: &hyperbol1\n", + " - hyperbol:\n", + " focals: &hyp1_focals { real: 4, image: 1 }\n", + " clip:\n", + " - operation : AND\n", + " vertices : [[1, 2],[3, 4],[6, 7]]\n", + " material: *lambertian\n", "- sun: \n", " dni: 1\n", " spectrum: [{wavelength: 1, data: 1}]\n", @@ -37,6 +44,8 @@ static const char* input[] = { " position: [1, 2, 3]\n", " - name: anchor1\n", " position: [4, 5, 6]\n", + " - name: anchor2\n", + " hyperboloid_image_focals: *hyp1_focals\n", " children:\n", " - name: entity0a\n", " primary: 1\n", @@ -49,6 +58,9 @@ static const char* input[] = { " position: [4, 5, 6]\n", " - name: entity0b\n", " position: [7, 8, 9]\n", + " - name: entity0c\n", + " primary: 0\n", + " geometry: *hyperbol1\n", "- entity:\n", " name: entity1\n", " x_pivot:\n", @@ -60,6 +72,11 @@ static const char* input[] = { " spacing: 1\n", " ref_point: [1, 2, 3]\n", " target: { anchor: \"entity0.entity0b.anchor0\" }\n", + "- entity:\n", + " name: entity3\n", + " x_pivot:\n", + " ref_point: [4, 2, 3]\n", + " target: { anchor: \"entity0.anchor2\" }\n", NULL }; @@ -120,8 +137,8 @@ check_entity0 matte = solparser_get_material_matte(parser, mtl->data.matte); CHECK(matte->reflectivity, 0.5); - CHECK(solparser_entity_get_children_count(entity0), 2); - CHECK(solparser_entity_get_anchors_count(entity0), 2); + CHECK(solparser_entity_get_children_count(entity0), 3); + CHECK(solparser_entity_get_anchors_count(entity0), 3); anchor_id = solparser_entity_get_anchor(entity0, 0); entity0_anchor0 = solparser_get_anchor(parser, anchor_id); @@ -186,13 +203,14 @@ check_entity1 CHECK(solparser_entity_get_children_count(entity1), 0); x_pivot = solparser_get_x_pivot(parser, entity1->data.x_pivot); + NCHECK(x_pivot, NULL); CHECK(d3_eq(x_pivot->ref_point, d3(tmp, 1, 2, 3)), 1); CHECK(x_pivot->target.type, SOLPARSER_TARGET_ANCHOR); } static void check_entity2 -(struct solparser* parser, const struct solparser_entity* entity2) + (struct solparser* parser, const struct solparser_entity* entity2) { double tmp[3]; @@ -205,11 +223,32 @@ check_entity2 CHECK(solparser_entity_get_children_count(entity2), 0); zx_pivot = solparser_get_zx_pivot(parser, entity2->data.zx_pivot); + NCHECK(zx_pivot, NULL); CHECK(zx_pivot->spacing, 1); CHECK(d3_eq(zx_pivot->ref_point, d3(tmp, 1, 2, 3)), 1); CHECK(zx_pivot->target.type, SOLPARSER_TARGET_ANCHOR); } +static void +check_entity3 + (struct solparser* parser, const struct solparser_entity* entity3) +{ + double tmp[3]; + + NCHECK(parser, NULL); + NCHECK(entity3, NULL); + + CHECK(strcmp(str_cget(&entity3->name), "entity3"), 0); + CHECK(entity3->type, SOLPARSER_ENTITY_X_PIVOT); + CHECK(solparser_entity_get_anchors_count(entity3), 0); + CHECK(solparser_entity_get_children_count(entity3), 0); + + x_pivot = solparser_get_x_pivot(parser, entity3->data.x_pivot); + NCHECK(x_pivot, NULL); + CHECK(d3_eq(x_pivot->ref_point, d3(tmp, 4, 2, 3)), 1); + CHECK(x_pivot->target.type, SOLPARSER_TARGET_ANCHOR); +} + int main(int argc, char** argv) { @@ -256,6 +295,9 @@ main(int argc, char** argv) } else if(!strcmp(str_cget(&entity->name), "entity2")) { check_entity2(parser, entity); + } + else if (!strcmp(str_cget(&entity->name), "entity3")) { + check_entity3(parser, entity); } else { FATAL("Unexpected entity name.\n"); } diff --git a/src/parser/test_solparser6.c b/src/parser/test_solparser6.c @@ -31,6 +31,9 @@ main(int argc, char** argv) const struct solparser_material* mtl; const struct solparser_object* obj; const struct solparser_shape* shape; + const struct solparser_shape_sphere* sphere; + const struct solparser_shape_paraboloid* parabol; + const struct solparser_shape_hyperboloid* hyperbol; FILE* stream; (void)argc, (void)argv; @@ -45,8 +48,20 @@ main(int argc, char** argv) fprintf(stream, " name: test\n"); fprintf(stream, " primary: 0\n"); fprintf(stream, " geometry:\n"); - fprintf(stream, " - sphere: { radius: 1 }\n"); - fprintf(stream, " material: { ?virtual }\n"); + fprintf(stream, " - sphere: { radius: 1 }\n"); + fprintf(stream, " material: { ?virtual }\n"); + fprintf(stream, " - parabol:\n"); + fprintf(stream, " focal: 10\n"); + fprintf(stream, " clip :\n"); + fprintf(stream, " - operation : AND\n"); + fprintf(stream, " vertices : [[1, 2], [3, 4], [6, 7]]\n"); + fprintf(stream, " material: { ?virtual }\n"); + fprintf(stream, " - hyperbol:\n"); + fprintf(stream, " focals: { real: 10, image: 2 }\n"); + fprintf(stream, " clip :\n"); + fprintf(stream, " - operation : AND\n"); + fprintf(stream, " vertices : [[1, 2], [3, 4], [6, 7]]\n"); + fprintf(stream, " material: { ?virtual }\n"); rewind(stream); CHECK(solparser_setup(parser, NULL, stream), RES_OK); @@ -63,11 +78,31 @@ main(int argc, char** argv) CHECK(solparser_entity_get_children_count(entity), 0); CHECK(entity->type, SOLPARSER_ENTITY_GEOMETRY); geom = solparser_get_geometry(parser, entity->data.geometry); - CHECK(solparser_geometry_get_objects_count(geom), 1); + CHECK(solparser_geometry_get_objects_count(geom), 3); + obj_id = solparser_geometry_get_object(geom, 0); obj = solparser_get_object(parser, obj_id); shape = solparser_get_shape(parser, obj->shape); CHECK(shape->type, SOLPARSER_SHAPE_SPHERE); + sphere = solparser_get_shape_sphere(parser, shape->data.sphere); + CHECK(sphere->radius, 1); + CHECK(sphere->nslices, 16); + + obj_id = solparser_geometry_get_object(geom, 1); + obj = solparser_get_object(parser, obj_id); + shape = solparser_get_shape(parser, obj->shape); + CHECK(shape->type, SOLPARSER_SHAPE_PARABOL); + parabol = solparser_get_shape_parabol(parser, shape->data.parabol); + CHECK(parabol->focal, 10); + + obj_id = solparser_geometry_get_object(geom, 2); + obj = solparser_get_object(parser, obj_id); + shape = solparser_get_shape(parser, obj->shape); + CHECK(shape->type, SOLPARSER_SHAPE_HYPERBOL); + hyperbol = solparser_get_shape_hyperbol(parser, shape->data.hyperbol); + CHECK(hyperbol->focals.real, 10); + CHECK(hyperbol->focals.image, 2); + mtl2 = solparser_get_material_double_sided(parser, obj->mtl2); CHECK(mtl2->front.i, mtl2->back.i); mtl = solparser_get_material(parser, mtl2->front); diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml @@ -624,6 +624,96 @@ --- # +# <hyperbol> ::= +# hyperbol: # (x^2 + y^2) / a^2 - (z + z0 - 1/2)^2 / b^2 + 1 = 0 +# # with g = img_focal + real_focal; f = real_focal / g; +# # a^2 = g^2(f - f^2); b = g(f - 1/2); z0 = |b| + g/2 +# focals: <hyperboloid_focals> +# clip: <polyclip-list> +# +# <hyperboloid_focals> ::= +# real: REAL # in ]0, INF) +# image: REAL # in ]0, INF) +# +# missing hyperbol definition +- geometry: [ { hyperbol: } ] +--- +# unknown dummy parameter +- geometry: [ { hyperbol: { dummy: 1 } } ] +--- +# missing focals definition +- geometry: [ { hyperbol: { focals: } } ] +--- +# missing real value +- geometry: [ { hyperbol: { focals: { real: } } } ] +--- +# missing image value +- geometry: [ { hyperbol: { focals: { image: } } } ] +--- +# missing clip value +- geometry: [ { hyperbol: { clip: } } ] +--- +# real should be a number +- geometry: [ { hyperbol: { focals: { real: "dummy" } } } ] +--- +# -1 invalid +- geometry: [ { hyperbol: { focals: { real: -1 } } } ] +--- +# 0 invalid +- geometry: [ { hyperbol: { focals: { real: 0 } } } ] +--- +# image should be a number +- geometry: [ { hyperbol: { focals: { image: "dummy" } } } ] +--- +# -1 invalid +- geometry: [ { hyperbol: { focals: { image: -1 } } } ] +--- +# 0 invalid +- geometry: [ { hyperbol: { focals: { image: 0 } } } ] +--- +# missing clip parameter +- geometry: [ { hyperbol: { focals: { real: 1, image: 1 } } } ] +--- +# missing real parameter +- geometry: + - hyperbol: + focals: { image: 1 } + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- +# missing image parameter +- geometry: + - hyperbol: + focals: { real: 10 } + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- +# 2x focals +- geometry: + - hyperbol: + focals: { real: 1, image: 1 } + focals: { real: 1, image: 1 } +--- +# 2x real +- geometry: [ { hyperbol: { focals: { real: 1, real: 1 } } } ] +--- +# 2x image +- geometry: [ { hyperbol: { focals: { image: 1, image: 1 } } } ] +--- +# 2x clip +- geometry: + - hyperbol: + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- + +# # <plane> ::= # plane: # clip: <polyclip-list> @@ -1066,30 +1156,71 @@ # # <anchor-data> ::= # name: STRING -# position: <real3> +# <position-description> # +# <position-description> ::= +# position: <real3> | hyperboloid_image_focals: <hyperboloid_focals> +# # missing anchors definition - entity: anchors: --- -# missing position +# missing name definition - entity: - anchors: - - name: "anchor" + anchors: [ name: ] +--- +# missing position definition +- entity: + anchors: [ position: ] +--- +# missing hyperboloid_image_focals definition +- entity: + anchors: [ { hyperboloid_image_focals: } ] +--- +# missing position-description +- entity: + anchors: [ { name: "anchor" } ] +--- +# position should have 3 values +- entity: + anchors: [ { name: "anchor", position: [ -4, 5.2 ] } ] +--- +# position should have 3 values +- entity: + anchors: [ { name: "anchor", position: [ -4, 5.2, 0, 5 ] } ] --- # missing name - entity: + anchors: [ { position: [ -4, 5.2, 0 ] } ] +--- +# 2x name +- entity: + anchors: [ { name: "anchor", name: "anchor" } ] +--- +# 2x position-description +- entity: + anchors: [ { position: [ -4, 5.2, 0 ], position: [ -4, 5.2, 0 ] } ] +--- +# 2x position-description +- entity: anchors: - - position: [ -4, 5.2, 0 ] + - hyperboloid_image_focals: { real: 1, image: 1 } + hyperboloid_image_focals: { real: 1, image: 1 } +--- +# 2x position-description +- entity: + anchors: + - hyperboloid_image_focals: { real: 1, image: 1 } + position: [ -4, 5.2, 0 ] --- # 2 anchors with same name - entity: anchors: - - name: "anchor" - position: [ -4, 5.2, 0 ] - - name: "anchor" - position: [ -4, 5.2, 0 ] + - name: "anchor" + position: [ -4, 5.2, 0 ] + - name: "anchor" + position: [ -4, 5.2, 0 ] --- # diff --git a/src/solstice.c b/src/solstice.c @@ -20,6 +20,8 @@ #include "solstice_args.h" #include "parser/solparser.h" +#include <rsys/double2.h> + #include <sys/stat.h> #include <sys/types.h> @@ -306,6 +308,7 @@ static res_T setup_sun_dirs(struct solstice* solstice, const struct solstice_args* args) { double* sun_dirs = NULL; + double* sun_angles = NULL; size_t i; res_T res = RES_OK; ASSERT(solstice && args); @@ -316,18 +319,26 @@ setup_sun_dirs(struct solstice* solstice, const struct solstice_args* args) "Could not reserve the list of %lu sun directions.\n", (unsigned long)args->nsun_dirs); goto error; - } - + res = darray_double_resize(&solstice->sun_angles, args->nsun_dirs*2/*#dims*/); + if (res != RES_OK) { + fprintf(stderr, + "Could not reserve the list of %lu sun angles.\n", + (unsigned long)args->nsun_dirs); + goto error; + } sun_dirs = darray_double_data_get(&solstice->sun_dirs); + sun_angles = darray_double_data_get(&solstice->sun_angles); FOR_EACH(i, 0, args->nsun_dirs) { spherical_to_cartesian_sun_dir(args->sun_dirs + i, sun_dirs + i*3/*#dims*/); + d2(sun_angles + i*2, args->sun_dirs[i].azimuth, args->sun_dirs[i].elevation); } exit: return res; error: darray_double_clear(&solstice->sun_dirs); + darray_double_clear(&solstice->sun_angles); goto exit; } @@ -531,6 +542,7 @@ solstice_init darray_nodes_init(allocator, &solstice->roots); darray_nodes_init(allocator, &solstice->pivots); darray_double_init(allocator, &solstice->sun_dirs); + darray_double_init(allocator, &solstice->sun_angles); solstice->allocator = allocator ? allocator : &mem_default_allocator; @@ -633,12 +645,14 @@ solstice_release(struct solstice* solstice) darray_nodes_release(&solstice->roots); darray_nodes_release(&solstice->pivots); darray_double_release(&solstice->sun_dirs); + darray_double_release(&solstice->sun_angles); } res_T solstice_run(struct solstice* solstice) { const double* sun_dirs = NULL; + const double* sun_angles = NULL; size_t nsun_dirs = 0; size_t i; int dump; @@ -647,6 +661,7 @@ solstice_run(struct solstice* solstice) ASSERT(solstice); sun_dirs = darray_double_cdata_get(&solstice->sun_dirs); + sun_angles = darray_double_cdata_get(&solstice->sun_angles); nsun_dirs = darray_double_size_get(&solstice->sun_dirs); ASSERT(nsun_dirs%3 == 0); nsun_dirs /= 3/*#dims*/; @@ -674,6 +689,8 @@ solstice_run(struct solstice* solstice) } else { FOR_EACH(i, 0, nsun_dirs) { const double* sun_dir = sun_dirs + i*3/*#dims*/; + fprintf(solstice->output, "#--- Sun direction: %g %g (%g %g %g)\n", + SPLIT2(sun_angles), SPLIT3(sun_dir)); res = solstice_update_entities(solstice, sun_dir); if(res != RES_OK) goto error; @@ -694,7 +711,6 @@ solstice_run(struct solstice* solstice) res = solstice_solve(solstice); if(res != RES_OK) goto error; } - fprintf(solstice->output, "#--- Sun direction: %g %g %g\n", SPLIT3(sun_dir)); } } diff --git a/src/solstice.h b/src/solstice.h @@ -94,6 +94,7 @@ struct solstice { enum solstice_args_dump_split_mode dump_split_mode; struct darray_double sun_dirs; /* List of double3 */ + struct darray_double sun_angles; size_t nrealisations; /* # realisations */ FILE* output; /* Output stream */ diff --git a/src/solstice_entity.c b/src/solstice_entity.c @@ -37,7 +37,7 @@ update_instance_transform static res_T merge_name - (struct str* RESTRICT output, + (struct str* output, const struct str* name0, const struct str* name1) { diff --git a/src/solstice_object.c b/src/solstice_object.c @@ -434,6 +434,29 @@ create_parabolic_cylinder } static res_T +create_hyperbol + (struct solstice* solstice, + const double transform[12], + const struct solparser_shape_hyperboloid_id id, + struct ssol_shape** out_ssol_shape) +{ + const struct solparser_shape_hyperboloid* hyperboloid; + struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT; + ASSERT(solstice); + + hyperboloid = solparser_get_shape_hyperbol(solstice->parser, id); + + quadric.type = SSOL_QUADRIC_HYPERBOL; + quadric.data.hyperbol.real_focal = hyperboloid->focals.real; + quadric.data.hyperbol.img_focal = hyperboloid->focals.image; + d33_set(quadric.transform, transform); + d3_set(quadric.transform + 9, transform + 9); + + return create_ssol_shape_punched_surface + (solstice, &hyperboloid->polyclips, &quadric, out_ssol_shape); +} + +static res_T create_plane (struct solstice* solstice, const double transform[12], @@ -503,6 +526,9 @@ create_shaded_shape res = create_parabolic_cylinder (solstice, transform, shape->data.parabol, ssol_shape); break; + case SOLPARSER_SHAPE_HYPERBOL: + res = create_hyperbol(solstice, transform, shape->data.hyperbol, ssol_shape); + break; case SOLPARSER_SHAPE_PLANE: res = create_plane(solstice, transform, shape->data.plane, ssol_shape); break; diff --git a/src/test_solstice_simulation.c b/src/test_solstice_simulation.c @@ -0,0 +1,327 @@ +/* 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 200809L /* mkstemp support */ + +#include <rsys/rsys.h> +#include <rsys/math.h> + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef COMPILER_CL + /* Wrap POSIX functions and constants */ + #include <io.h> + #define fdopen _fdopen +#endif + +enum side { + FRONT, + BACK +}; + +enum result_type { + FRONT_INTEGRATED_IRRADIANCE, + BACK_INTEGRATED_IRRADIANCE, + FRONT_REFLECTIVITY_LOSS, + BACK_REFLECTIVITY_LOSS, + FRONT_ABSORPTIVITY_LOSS, + BACK_ABSORPTIVITY_LOSS, + FRONT_COS_LOSS, + BACK_COS_LOSS, + FRONT_EFFICIENCY, + BACK_EFFICIENCY, + MAX_RESULTS_COUNT__ +}; + +#define MAX_LINE_LEN 2048 + +static const char +sundir_header [] = "#--- Sun direction:"; + +#define IS_NEW_BLOCK(Line, Header) (!strncmp((Line), (Header), strlen(Header))) + +static int +read_line(char* line, size_t max_line_len, FILE* stream) +{ + ASSERT(stream && line && max_line_len); + line = fgets(line, (int)max_line_len, stream); + if(!line) return 0; + CHECK(strlen(line) + 1 < max_line_len, 1); + return 1; +} + +static void +get_dir_and_counts + (FILE* ref_file, + double angles[2], + unsigned long* recv_count, + unsigned long* realisation_count) +{ + char line[MAX_LINE_LEN]; + int n; + + NCHECK(ref_file, NULL); + NCHECK(angles, NULL); + NCHECK(recv_count, NULL); + NCHECK(realisation_count, NULL); + + /* Get sun dir */ + CHECK(read_line(line, sizeof(line), ref_file), 1); + CHECK(IS_NEW_BLOCK(line, sundir_header), 1); + n = sscanf(line+strlen(sundir_header), "%lg%lg", &angles[0], &angles[1]); + CHECK(n, 2); + + /* Get #receivers and #realisations */ + CHECK(read_line(line, sizeof(line), ref_file), 1); + n = sscanf(line, "%lu%lu", recv_count, realisation_count); + CHECK(n, 2); +} + +static void +read_recv(const char* line, char name[], double E[], double SE[]) +{ + int n; + + NCHECK(line, NULL); + NCHECK(name, NULL); + NCHECK(E, NULL); + NCHECK(SE, NULL); + + n = sscanf(line, + "%s%*u%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg%lg", + name, + &E[FRONT_INTEGRATED_IRRADIANCE], &SE[FRONT_INTEGRATED_IRRADIANCE], + &E[BACK_INTEGRATED_IRRADIANCE], &SE[BACK_INTEGRATED_IRRADIANCE], + &E[FRONT_REFLECTIVITY_LOSS], &SE[FRONT_REFLECTIVITY_LOSS], + &E[BACK_REFLECTIVITY_LOSS], &SE[BACK_REFLECTIVITY_LOSS], + &E[FRONT_ABSORPTIVITY_LOSS], &SE[FRONT_ABSORPTIVITY_LOSS], + &E[BACK_ABSORPTIVITY_LOSS], &SE[BACK_ABSORPTIVITY_LOSS], + &E[FRONT_COS_LOSS], &SE[FRONT_COS_LOSS], + &E[BACK_COS_LOSS], &SE[BACK_COS_LOSS], + &E[FRONT_EFFICIENCY], &SE[FRONT_EFFICIENCY], + &E[BACK_EFFICIENCY], &SE[BACK_EFFICIENCY]); + + CHECK(n, 2*MAX_RESULTS_COUNT__+1); +} + +#define POSITIVE_OR_M_ONE(x) ((x) == -1 || (x) >= 0) + +static FINLINE int +is_compatible_with + (const double ref_E, + const double ref_SE, + const double test_E, + const double test_SE) +{ + double SE; + + CHECK(POSITIVE_OR_M_ONE(ref_E), 1); + CHECK(POSITIVE_OR_M_ONE(ref_SE), 1); + CHECK(POSITIVE_OR_M_ONE(test_E), 1); + CHECK(POSITIVE_OR_M_ONE(test_SE), 1); + + if(ref_E == -1) { + CHECK(ref_SE, -1); + return (test_E == -1 && test_SE == -1); + } + + NCHECK(ref_SE, -1); + SE = ref_SE > 0 ? 2 * ref_SE : (ref_E > 0 ? ref_E * 1e-6 : 1e-6); + return (fabs(ref_E - test_E) <= SE && test_SE <= SE); +} + +static void +check_1_reference + (FILE* tested_file, + const char* rcv_name, + const double* reference_E, + const double* reference_SE) +{ + double a[2]; + size_t c1, c2; + int found = 0; + + NCHECK(tested_file, NULL); + NCHECK(rcv_name, NULL); + NCHECK(reference_E, NULL); + NCHECK(reference_SE, NULL); + + get_dir_and_counts(tested_file, a, &c1, &c2); /* Skip headers */ + + while(!feof(tested_file) && !found) { + char line[MAX_LINE_LEN]; + char tested_rcv_name[MAX_LINE_LEN]; + double tested_E[MAX_RESULTS_COUNT__], tested_SE[MAX_RESULTS_COUNT__]; + enum result_type r; + + CHECK(read_line(line, sizeof(line), tested_file), 1); + + read_recv(line, tested_rcv_name, tested_E, tested_SE); + if(strcmp(rcv_name, tested_rcv_name)) continue; + + FOR_EACH(r, FRONT_INTEGRATED_IRRADIANCE, MAX_RESULTS_COUNT__) { + CHECK(is_compatible_with + (reference_E[r], reference_SE[r], tested_E[r], tested_SE[r]), 1); + } + found = 1; + } + CHECK(found, 1); +} + +static void +check_1_global + (FILE* tested_file, + const double reference_E, + const double reference_SE, + const unsigned rank) +{ + char line[MAX_LINE_LEN]; + double a[2]; + size_t recv_count, r2; + unsigned i; + int nb; + double tested_E, tested_SE; + + get_dir_and_counts(tested_file, a, &recv_count, &r2); + + /* Skip receivers */ + while(recv_count--) CHECK(read_line(line, sizeof(line), tested_file), 1); + + /* Read the rank th global data */ + FOR_EACH(i, 0, rank+1) CHECK(read_line(line, sizeof(line), tested_file), 1); + + nb = sscanf(line, "%lg%lg", &tested_E, &tested_SE); + CHECK(nb, 2); + CHECK(is_compatible_with(reference_E, reference_SE, tested_E, tested_SE), 1); +} + +static void +check_references(FILE* ref_file, FILE* tested_file) +{ + char line[MAX_LINE_LEN]; + unsigned nb_global = 0; + fpos_t pos; + + NCHECK(ref_file, NULL); + NCHECK(tested_file, NULL); + + CHECK(fgetpos(ref_file, &pos), 0); + while(read_line(line, sizeof(line), ref_file)) { + double val, std; + int nb = 0; + + if(IS_NEW_BLOCK(line, sundir_header)) { + /* Keep the header as a part of the following block */ + CHECK(fsetpos(ref_file, &pos), 0); + break; + } + + nb = sscanf(line, "%lg%lg", &val, &std); + CHECK(nb == 0 || nb == 2, 1); + + rewind(tested_file); + if(nb != 0) { + check_1_global(tested_file, val, std, nb_global); + nb_global++; + } else { + char ref_name[MAX_LINE_LEN]; + double reference_E[MAX_RESULTS_COUNT__]; + double reference_SE[MAX_RESULTS_COUNT__]; + read_recv(line, ref_name, reference_E, reference_SE); + check_1_reference(tested_file, ref_name, reference_E, reference_SE); + } + + CHECK(fgetpos(ref_file, &pos), 0); + } +} + +static FINLINE int +create_tmp_file_name(char* name, const size_t max_sizeof_name) +{ + const char* template = "solstice_tmp_file_XXXXXX"; + int fd; + NCHECK(name, NULL); + CHECK(strlen(template)+1 <= max_sizeof_name-1, 1); + strcpy(name, template); + fd = mkstemp(name); + NCHECK(fd, -1); + return fd; +} + +static void +do_check(const char* binary, const char* dir, const char* base_name) +{ + char ref_file_name[128]; + FILE* ref_file; + unsigned long c1, realisation_count; + int n; + ASSERT(base_name); + + n = snprintf(ref_file_name, sizeof(ref_file_name), "%s%s.ref", dir, base_name); + CHECK((size_t)n < sizeof(ref_file_name), 1); + + ref_file = fopen(ref_file_name, "r"); + NCHECK(ref_file, NULL); + + while(!feof(ref_file)) { + char cmd[512]; + char tested_file_name[128]; + double sun_angles[2]; + FILE* fp = NULL; + int fd = -1; + + get_dir_and_counts(ref_file, sun_angles, &c1, &realisation_count); + + fd = create_tmp_file_name(tested_file_name, sizeof(tested_file_name)); + fp = fdopen(fd, "r"); + NCHECK(fp, NULL); + + n = snprintf(cmd, sizeof(cmd), + "%s -o %s -f -D %g,%g -n %lu -R %s%s_receiver.yaml %s%s.yaml", + binary, tested_file_name, SPLIT2(sun_angles), realisation_count, + dir, base_name, dir, base_name); + CHECK((unsigned)n < sizeof(cmd), 1); + + CHECK(system(cmd), RES_OK); + + check_references(ref_file, fp); + + fclose(fp); + remove(tested_file_name); + } +} + +int +main(int argc, char** argv) +{ + int err = 0; + + if(argc != 4) { + printf("Usage: %s <solstice-binary> <file-path> <file-base-name>\n", argv[0]); + goto error; + } + + do_check(argv[1], argv[2], argv[3]); + +exit: + return err; +error: + err = 1; + goto exit; +} + diff --git a/yaml/beam_down.ref b/yaml/beam_down.ref @@ -0,0 +1,12 @@ +#--- Sun direction: 0 90 (-3.7494e-33 -6.12323e-17 -1) +2 10000 +tower.secondary.hyperbol 10 465.464 0.00509812 0 0 0 0 0 0 0 0 0 0 34.5362 0.00509812 0 0 0.930847 1.01954e-05 0 0 +tower.receptor 14 465.464 0.00509812 -1 -1 0 0 -1 -1 0 0 -1 -1 34.5362 0.00509812 -1 -1 0.930847 1.01954e-05 -1 -1 +0 0 +0 0 +#--- Sun direction: 50 50 (-0.413176 -0.492404 -0.766044) +2 10000 +tower.secondary.hyperbol 10 400.231 0.107226 0 0 0 0 0 0 0 0 0 0 99.7686 0.107226 0 0 0.800393 0.000214433 0 0 +tower.receptor 14 136.51 1.90718 -1 -1 0 0 -1 -1 0 0 -1 -1 32.9896 0.464742 -1 -1 0.272997 0.00381404 -1 -1 +0 0 +0 0 diff --git a/yaml/beam_down.yaml b/yaml/beam_down.yaml @@ -0,0 +1,108 @@ +# Debug/solstice -D 90,90 -R ../yaml/beam_down_receiver.yaml ../yaml/beam_down.yaml +# Debug/solstice -D 90,90 -r pos=-100,-100,50:tgt=0,0,50:up=0,0,1:img=1000x800 -o ../yaml/beam_down.ppm -f ../yaml/beam_down.yaml +# +# 1 10000 +# tower.receptor 14 465.464 0.00509812 -1 -1 0 0 -1 -1 0 0 -1 -1 34.5362 0.00509812 -1 -1 0.930847 1.01954e-05 -1 -1 +# 0 0 +# 0 0 +# --- Sun direction: -3.7494e-33 -6.12323e-17 -1 + +- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] } + +- material: &mirror { mirror: { reflectivity: 1, roughness: 0 } } +- material: &black { matte: { reflectivity: 0 } } +- material: &virtual { virtual: } + +- template: &hyperbol + name: hyperbol + primary: 0 + geometry: + - hyperbol: + focals: &hyperbol_focals { real: 100, image: 20 } + clip: + - operation: AND + #vertices: [[-25, -25], [-25, 25], [25, 25], [25, -25]] + vertices: [[-5, 0], [20, -10], [35, 0], [20, 10]] + material: { front: *mirror, back: *virtual } + anchors: + - name: image_point + hyperboloid_image_focals: *hyperbol_focals + +- geometry: &target + - plane: + clip: + - operation: AND + vertices: [[-2.5, -2.5], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5]] + #vertices: [[-1, -1], [-1, 1], [1, 1], [1, -1]] + #vertices: [[-.5, -.5], [-.5, .5], [.5, .5], [.5, -.5]] + #vertices: [[-.1, -.1], [-.1, .1], [.1, .1], [.1, -.1]] + material: *black + +- geometry: &primary150 + - parabol: + focal: 150 + clip: + - operation: AND + vertices: [[-5, -5], [-5, 5], [5, 5], [5, -5]] + #vertices: [[-3, -3], [-3, 3], [3, 3], [3, -3]] + #vertices: [[-2, -2], [-2, 2], [2, 2], [2, -2]] + #vertices: [[-1, -1], [-1, 1], [1, 1], [1, -1]] + #vertices: [[-.01, -.01], [-.01, .01], [.01, .01], [.01, -.01]] + material: *mirror + +- template: &temp_heliostat150 + name: "temp-heliostat150" + primary: 0 + geometry: + - cylinder: { radius: 0.3, height: 10 } + transform: { translation: [0, 0, 5] } + material: *black + children: + - name: "pivot" + transform: { translation: [0, 0, 10] } + zx_pivot: + spacing: 1 + target: { anchor: tower.secondary.hyperbol.image_point } + children: + - name: "reflector" + transform: { rotation: [-90, 0, 0] } + primary: 1 + geometry: *primary150 + +- entity: + name: "tower" + children: + - name: secondary + children: [ *hyperbol ] + transform: { translation: [ 0, 0, 100 ] } + - name: receptor + geometry: *target + primary: 0 + - name: "building" + primary: 0 + geometry: + - cylinder: { radius: 1, height: 110 } + transform: { translation: [-4, 0, 55] } + material: *black + +- entity: + name: "heliostat1" + transform: { translation: [100, -30, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat2" + transform: { translation: [101, -15, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat3" + transform: { translation: [102, 0, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat4" + transform: { translation: [101, 15, 0] } + children: [ *temp_heliostat150 ] +- entity: + name: "heliostat5" + transform: { translation: [100, 30, 0] } + children: [ *temp_heliostat150 ] + +\ No newline at end of file diff --git a/yaml/beam_down_receiver.yaml b/yaml/beam_down_receiver.yaml @@ -0,0 +1,2 @@ +- { name: "tower.receptor", side: FRONT } +- { name: "tower.secondary.hyperbol" } +\ No newline at end of file diff --git a/yaml/test01.ref b/yaml/test01.ref @@ -0,0 +1,5 @@ +#--- Sun direction: 0 90 (-6.12323e-17 -0 -1) +1 10000 +square_receiver 2 -1 -1 1 0 -1 -1 0 0 -1 -1 0 0 -1 -1 0 0 -1 -1 1 0 +0 0 +0 0 diff --git a/yaml/test01.yaml b/yaml/test01.yaml @@ -0,0 +1,50 @@ +- sun: &sun + dni: 1 + spectrum: [{wavelength: 1, data: 1}] + +- material: &specular + front: + mirror: { reflectivity: 1, roughness: 0 } + back: + mirror: { reflectivity: 1, roughness: 0 } + + +- geometry: &small_square + - material: *specular + plane: + clip: + - operation: AND + vertices: + - [-0.50, -0.50] + - [-0.50, 0.50] + - [0.50, 0.50] + - [0.50, -0.50] + +- geometry: &big_square + - material: { virtual: } + plane: + clip: + - operation: AND + vertices: + - [-5.00, -5.00] + - [-5.00, 5.00] + - [5.00, 5.00] + - [5.00, -5.00] + + +- entity: + name: "reflector" + primary: 1 + transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } + geometry: *small_square + + + +- entity: + name: "square_receiver" + primary: 0 + transform: { rotation: [0, 0, 0], translation: [0, 0, 2] } + geometry: *big_square + + + diff --git a/yaml/test01_receiver.yaml b/yaml/test01_receiver.yaml @@ -0,0 +1 @@ +- { name: "square_receiver", side: BACK } diff --git a/yaml/test02.ref b/yaml/test02.ref @@ -0,0 +1,5 @@ +#--- Sun direction: 0 90 (-6.12323e-17 -0 -1) +1 100000 +square_receiver 2 -1 -1 1 0.0313065 -1 -1 0 0 -1 -1 0 0 -1 -1 0 0 -1 -1 0.01003 0.000315109 +0 0 +99 0.0313065 diff --git a/yaml/test02.yaml b/yaml/test02.yaml @@ -0,0 +1,47 @@ +- sun: &sun + dni: 1 + spectrum: [{wavelength: 1, data: 1}] + +- material: &specular + mirror: { reflectivity: 1, roughness: 0 } + + +- geometry: &small_square + - material: { virtual: } + plane: + clip: + - operation: AND + vertices: + - [-0.50, -0.50] + - [-0.50, 0.50] + - [0.50, 0.50] + - [0.50, -0.50] + +- geometry: &big_square + - material: *specular + plane: + clip: + - operation: AND + vertices: + - [-5.00, -5.00] + - [-5.00, 5.00] + - [5.00, 5.00] + - [5.00, -5.00] + + +- entity: + name: "reflector" + primary: 1 + transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } + geometry: *big_square + + + +- entity: + name: "square_receiver" + primary: 0 + transform: { rotation: [0, 0, 0], translation: [0, 0, 2] } + geometry: *small_square + + + diff --git a/yaml/test02_receiver.yaml b/yaml/test02_receiver.yaml @@ -0,0 +1 @@ +- { name: "square_receiver", side: BACK } diff --git a/yaml/test03.ref b/yaml/test03.ref @@ -0,0 +1,5 @@ +#--- Sun direction: 0 45 (-0.707107 -0 -0.707107) +1 10000 +square_receiver 2 -1 -1 0.707107 0 -1 -1 0 0 -1 -1 0 0 -1 -1 0.292893 0 -1 -1 0.707107 0 +0 0 +0 0 diff --git a/yaml/test03.yaml b/yaml/test03.yaml @@ -0,0 +1,49 @@ +- sun: &sun + dni: 1 + spectrum: [{wavelength: 1, data: 1}] + +- material: &specular + front: + mirror: { reflectivity: 1, roughness: 0 } + back: + mirror: { reflectivity: 1, roughness: 0 } + +- geometry: &small_square + - material: *specular + plane: + clip: + - operation: AND + vertices: + - [-0.50, -0.50] + - [-0.50, 0.50] + - [0.50, 0.50] + - [0.50, -0.50] + +- geometry: &big_square + - material: { virtual: } + plane: + clip: + - operation: AND + vertices: + - [-5.00, -5.00] + - [-5.00, 5.00] + - [5.00, 5.00] + - [5.00, -5.00] + + +- entity: + name: "reflector" + primary: 1 + transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } + geometry: *small_square + + + +- entity: + name: "square_receiver" + primary: 0 + transform: { rotation: [0, 0, 0], translation: [-2, 0, 2] } + geometry: *big_square + + + diff --git a/yaml/test03_receiver.yaml b/yaml/test03_receiver.yaml @@ -0,0 +1 @@ +- { name: "square_receiver", side: BACK } diff --git a/yaml/test04.ref b/yaml/test04.ref @@ -0,0 +1,4 @@ +#--- Sun direction: 0 45 (-0.707107 -0 -0.707107) +1 10000 +square_receiver 2 0 0 0.707107 0 0 0 0 0 0 0 0 0 0 0 0.292893 0 0 0 0.707107 0 +0 0 diff --git a/yaml/test04.yaml b/yaml/test04.yaml @@ -0,0 +1,52 @@ +- sun: &sun + dni: 1 + spectrum: [{wavelength: 1, data: 1}] + +- material: &specular + front: + mirror: { reflectivity: 1, roughness: 0 } + back: + mirror: { reflectivity: 1, roughness: 0 } + +- material: &black + matte: { reflectivity: 0 } + +- geometry: &small_square + - material: *specular + plane: + clip: + - operation: AND + vertices: + - [-0.50, -0.50] + - [-0.50, 0.50] + - [0.50, 0.50] + - [0.50, -0.50] + +- geometry: &big_square + - material: { virtual: } + plane: + clip: + - operation: AND + vertices: + - [-5.00, -5.00] + - [-5.00, 5.00] + - [5.00, 5.00] + - [5.00, -5.00] + + +- entity: + name: "reflector" + primary: 1 + transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } + geometry: *small_square + + + +- entity: + name: "square_receiver" + primary: 0 + transform: { rotation: [0, -45, 0], translation: [-2, 0, 2] } + geometry: *big_square + + + diff --git a/yaml/test04_receiver.yaml b/yaml/test04_receiver.yaml @@ -0,0 +1 @@ +- { name: "square_receiver", side: FRONT_AND_BACK } diff --git a/yaml/test05.ref b/yaml/test05.ref @@ -0,0 +1,5 @@ +#--- Sun direction: 0 90 (-6.12323e-17 -0 -1) +1 10000 +spherical_receiver 2 -1 -1 1 0 -1 -1 0 0 -1 -1 0 0 -1 -1 0 0 -1 -1 1 0 +0 0 +0 0 diff --git a/yaml/test05.yaml b/yaml/test05.yaml @@ -0,0 +1,44 @@ +- sun: &sun + dni: 1 + spectrum: [{wavelength: 1, data: 1}] + +- material: &lambertian + front: + matte: { reflectivity: 1 } + back: + matte: { reflectivity: 1 } + +- geometry: &small_square + - material: *lambertian + plane: + clip: + - operation: AND + vertices: + - [-0.50, -0.50] + - [-0.50, 0.50] + - [0.50, 0.50] + - [0.50, -0.50] + +- geometry: &big_sphere + - material: { virtual: } + sphere: + radius: 2.0 + slices: 128 + + +- entity: + name: "reflector" + primary: 1 + transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } + geometry: *small_square + + + +- entity: + name: "spherical_receiver" + primary: 0 + transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } + geometry: *big_sphere + + + diff --git a/yaml/test05_receiver.yaml b/yaml/test05_receiver.yaml @@ -0,0 +1 @@ +- { name: "spherical_receiver", side: BACK }