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 620f2f62a2213e01f7c334e5ae0c1a8257c82e51
parent 633798d63e20638812f501fe1671970b54031b08
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 21 Apr 2017 15:24:06 +0200

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

Diffstat:
Mcmake/CMakeLists.txt | 3++-
Mdoc/input | 26+++++++++++++++++++-------
Msrc/parser/solparser.c | 12++++++++++++
Msrc/parser/solparser.h | 5+++++
Msrc/parser/solparser_c.h | 11+++++++++++
Msrc/parser/solparser_geometry.c | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/parser/solparser_pivot.c | 22+++-------------------
Msrc/parser/solparser_shape.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/parser/test_solparser3.c | 30++++++++++++++++++++++++++++--
Msrc/parser/test_solparser6.c | 17++++++++++++++++-
Msrc/parser/yaml/test_ko_0.yaml | 28++++++++++++++++++++++++++++
Msrc/solstice_object.c | 35++++++++++++++++++++++++++++++++---
Msrc/solstice_solve.c | 16++++------------
Msrc/test_solstice_simulation.c | 4++--
Myaml/beam_down.ref | 84++++++++++++++++++++++++++++++++++++++++----------------------------------------
Ayaml/test07.ref | 12++++++++++++
Ayaml/test07.yaml | 36++++++++++++++++++++++++++++++++++++
Ayaml/test07_receiver.yaml | 1+
18 files changed, 425 insertions(+), 105 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -31,7 +31,7 @@ find_package(RCMake 0.2.3 REQUIRED) find_package(RSys 0.4 REQUIRED) find_package(SolAnim 0.1 REQUIRED) find_package(SolSolver 0.1.1 REQUIRED) -find_package(Star3DUT REQUIRED) +find_package(Star3DUT 0.2 REQUIRED) find_package(StarSP 0.4 REQUIRED) find_package(StarSTL 0.3 REQUIRED) @@ -156,6 +156,7 @@ if(NOT NO_TEST) add_test_simulation(test04) add_test_simulation(test05) add_test_simulation(test06) + add_test_simulation(test07) endif() diff --git a/doc/input b/doc/input @@ -133,6 +133,7 @@ | <parabol> | <parabolic-cylinder> | <hyperbol> + | <hemisphere> | <plane> | <sphere> | <stl> @@ -145,7 +146,8 @@ cylinder: height: REAL # in ]0, INF) radius: REAL # in ]0, INF) -[ slices: INTEGER ] # in [4, 4096]. Default 16 +[ slices: INTEGER # in [4, 4096]. Default 32 ] +[ stacks: INTEGER # in [1, 4096]. Default 1 ] <obj> ::= obj: @@ -156,17 +158,17 @@ parabol: focal: REAL # in ]0, INF) clip: <polyclip-list> - # By default slices is automatically compute with respect to the parabol + # By default slices is automatically computed with respect to the parabol # curvature -[ slices: INTEGER ] # in [4, 4096) +[ slices: INTEGER # in [4, 4096) ] <parabolic-cylinder> ::= parabolic-cylinder: # y^2 - 4*focal*z = 0 focal: REAL # in ]0, INF) clip: <polyclip-list> - # By default slices is automatically compute with respect to the hyperbol + # By default slices is automatically computed with respect to the hyperbol # curvature -[ slices: INTEGER ] # in [4, 4096) +[ slices: INTEGER # in [4, 4096) ] # (x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0 # with g = img_focal + real_focal; f = real_focal / g; @@ -177,12 +179,21 @@ clip: <polyclip-list> # By default slices is automatically compute with respect to the hyperbol # curvature -[ slices: INTEGER ] # in [4, 4096) +[ slices: INTEGER # in [4, 4096) ] <hyperboloid_focals> ::= real: REAL # in ]0, INF) image: REAL # in ]0, INF) +# x^2 + y^2 + (z - radius)^2 - radius^2 = 0 +<hemisphere> ::= + hemisphere: + radius: REAL # in ]0, INF) +[ clip: <polyclip-list> ] + # By default slices is automatically compute with respect to the hemisphere + # extension +[ slices: INTEGER # in [4, 4096) ] + <plane> ::= plane: clip: <polyclip-list> @@ -191,7 +202,8 @@ <sphere> ::= sphere: radius: REAL # in ]0, INF) -[ slices: INTEGER ] # in [4, 4096]. Default 16 +[ slices: INTEGER # in [4, 4096). Default 32 ] +[ stacks: INTEGER # in [2, 4096]. Default slices/2 ] <stl> ::= stl: diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -211,6 +211,7 @@ parser_clear(struct solparser* parser) darray_paraboloid_clear(&parser->parabols); darray_paraboloid_clear(&parser->parabolic_cylinders); darray_hyperboloid_clear(&parser->hyperbols); + darray_hemisphere_clear(&parser->hemispheres); darray_plane_clear(&parser->planes); darray_sphere_clear(&parser->spheres); darray_impgeom_clear(&parser->stls); @@ -270,6 +271,7 @@ parser_release(ref_T* ref) darray_paraboloid_release(&parser->parabols); darray_paraboloid_release(&parser->parabolic_cylinders); darray_hyperboloid_release(&parser->hyperbols); + darray_hemisphere_release(&parser->hemispheres); darray_plane_release(&parser->planes); darray_sphere_release(&parser->spheres); darray_impgeom_release(&parser->stls); @@ -603,6 +605,7 @@ solparser_create darray_paraboloid_init(mem_allocator, &parser->parabols); darray_paraboloid_init(mem_allocator, &parser->parabolic_cylinders); darray_hyperboloid_init(mem_allocator, &parser->hyperbols); + darray_hemisphere_init(mem_allocator, &parser->hemispheres); darray_plane_init(mem_allocator, &parser->planes); darray_sphere_init(mem_allocator, &parser->spheres); darray_impgeom_init(mem_allocator, &parser->stls); @@ -1073,6 +1076,15 @@ solparser_get_shape_hyperbol return darray_hyperboloid_cdata_get(&parser->hyperbols) + hyperboloid.i; } +const struct solparser_shape_hemisphere* +solparser_get_shape_hemisphere + (const struct solparser* parser, + const struct solparser_shape_hemisphere_id hemisphere) +{ + ASSERT(parser && hemisphere.i < darray_hemisphere_size_get(&parser->hemispheres)); + return darray_hemisphere_cdata_get(&parser->hemispheres) + hemisphere.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 @@ -176,6 +176,11 @@ solparser_get_shape_hyperbol (const struct solparser* parser, const struct solparser_shape_hyperboloid_id hyperboloid); +extern LOCAL_SYM const struct solparser_shape_hemisphere* +solparser_get_shape_hemisphere + (const struct solparser* parser, + const struct solparser_shape_hemisphere_id hemisphere); + extern LOCAL_SYM const struct solparser_shape_plane* solparser_get_shape_plane (const struct solparser* parser, diff --git a/src/parser/solparser_c.h b/src/parser/solparser_c.h @@ -136,6 +136,16 @@ struct target_alias { solparser_shape_hyperboloid_copy_and_release #include <rsys/dynamic_array.h> +/* Declare the array of hemispheres */ +#define DARRAY_NAME hemisphere +#define DARRAY_DATA struct solparser_shape_hemisphere +#define DARRAY_FUNCTOR_INIT solparser_shape_hemisphere_init +#define DARRAY_FUNCTOR_RELEASE solparser_shape_hemisphere_release +#define DARRAY_FUNCTOR_COPY solparser_shape_hemisphere_copy +#define DARRAY_FUNCTOR_COPY_AND_RELEASE \ + solparser_shape_hemisphere_copy_and_release +#include <rsys/dynamic_array.h> + /* Declare the array of planes */ #define DARRAY_NAME plane #define DARRAY_DATA struct solparser_shape_plane @@ -240,6 +250,7 @@ struct solparser { struct darray_paraboloid parabols; struct darray_paraboloid parabolic_cylinders; struct darray_hyperboloid hyperbols; + struct darray_hemisphere hemispheres; struct darray_plane planes; struct darray_sphere spheres; struct darray_impgeom stls; diff --git a/src/parser/solparser_geometry.c b/src/parser/solparser_geometry.c @@ -305,7 +305,7 @@ parse_cylinder const yaml_node_t* cylinder, struct solparser_shape_cylinder_id* out_ishape) { - enum { HEIGHT, RADIUS, SLICES }; + enum { HEIGHT, RADIUS, SLICES, STACKS }; struct solparser_shape_cylinder* shape = NULL; size_t ishape = SIZE_MAX; intptr_t i, n; @@ -329,6 +329,8 @@ parse_cylinder shape = darray_cylinder_data_get(&parser->cylinders) + ishape; n = cylinder->data.mapping.pairs.top - cylinder->data.mapping.pairs.start; + shape->nslices = 16; /* default value */ + shape->nstacks = 1; /* default value */ FOR_EACH(i, 0, n) { yaml_node_t* key; yaml_node_t* val; @@ -358,6 +360,10 @@ parse_cylinder } else if(!strcmp((char*)key->data.scalar.value, "slices")) { SETUP_MASK(SLICES, "slices"); res = parse_integer(parser, val, 4, 4096, &shape->nslices); + } + else if(!strcmp((char*)key->data.scalar.value, "stacks")) { + SETUP_MASK(STACKS, "stacks"); + res = parse_integer(parser, val, 1, 4096, &shape->nstacks); } else { log_err(parser, key, "unknown cylinder parameter `%s'.\n", key->data.scalar.value); @@ -382,13 +388,6 @@ parse_cylinder CHECK_PARAM(RADIUS, "radius"); #undef CHECK_PARAM - #define DEFAULT_PARAM(Flag, Ptr, Value) \ - if(!(mask & BIT(Flag))) { \ - *(Ptr) = Value; \ - } (void)0 - DEFAULT_PARAM(SLICES, &shape->nslices, 16); - #undef DEFAULT_PARAM - exit: out_ishape->i = ishape; return res; @@ -692,6 +691,102 @@ error: } static res_T +parse_hemisphere + (struct solparser* parser, + yaml_document_t* doc, + const yaml_node_t* hemisphere, + struct solparser_shape_hemisphere_id* out_ishape) +{ + enum { CLIP, RADIUS, SLICES }; + struct solparser_shape_hemisphere* 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 && hemisphere && out_ishape); + + if(hemisphere->type != YAML_MAPPING_NODE) { + log_err(parser, hemisphere, "expect a mapping of hemisphere parameters.\n"); + res = RES_BAD_ARG; + goto error; + } + + /* Allocate a hemispheric shape */ + ishape = darray_hemisphere_size_get(&parser->hemispheres); + res = darray_hemisphere_resize(&parser->hemispheres, ishape + 1); + if(res != RES_OK) { + log_err(parser, hemisphere, "could not allocate the hemisphere shape.\n"); + goto error; + } + shape = darray_hemisphere_data_get(&parser->hemispheres) + ishape; + + n = hemisphere->data.mapping.pairs.top - hemisphere->data.mapping.pairs.start; + FOR_EACH(i, 0, n) { + yaml_node_t* key; + yaml_node_t* val; + + key = yaml_document_get_node(doc, hemisphere->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, hemisphere->data.mapping.pairs.start[i].value); + if(key->type != YAML_SCALAR_NODE) { + log_err(parser, key, "expect hemisphere parameters.\n"); + res = RES_BAD_ARG; + goto error; + } + #define SETUP_MASK(Flag, Name) { \ + if(mask & BIT(Flag)) { \ + log_err(parser, key, \ + "the hemisphere 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, "radius")) { + SETUP_MASK(RADIUS, "radius"); + res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &shape->radius); + } + else if(!strcmp((char*)key->data.scalar.value, "slices")) { + SETUP_MASK(SLICES, "slices"); + res = parse_integer(parser, val, 4, 4096, &shape->nslices); + } + else { + log_err(parser, key, "unknown hemisphere 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, hemisphere, \ + "the hemisphere parameter `"Name"' is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(RADIUS, "radius"); + #undef CHECK_PARAM + +exit : + out_ishape->i = ishape; + return res; +error: + if(shape) { + darray_hemisphere_pop_back(&parser->hemispheres); + ishape = SIZE_MAX; + } + goto exit; +} + +static res_T parse_plane (struct solparser* parser, yaml_document_t* doc, @@ -722,6 +817,7 @@ parse_plane shape = darray_plane_data_get(&parser->planes) + ishape; n = plane->data.mapping.pairs.top - plane->data.mapping.pairs.start; + shape->nslices = 1; /* default value */ FOR_EACH(i, 0, n) { yaml_node_t* key; yaml_node_t* val; @@ -785,7 +881,7 @@ parse_sphere const yaml_node_t* sphere, struct solparser_shape_sphere_id* out_ishape) { - enum { RADIUS, SLICES }; + enum { RADIUS, SLICES, STACKS }; struct solparser_shape_sphere* shape = NULL; size_t ishape = SIZE_MAX; intptr_t i, n; @@ -809,6 +905,8 @@ parse_sphere shape = darray_sphere_data_get(&parser->spheres) + ishape; n = sphere->data.mapping.pairs.top - sphere->data.mapping.pairs.start; + shape->nslices = 16; /* default value */ + shape->nstacks = 8; /* initial default value */ FOR_EACH(i, 0, n) { yaml_node_t* key; yaml_node_t* val; @@ -835,6 +933,11 @@ parse_sphere } else if(!strcmp((char*)key->data.scalar.value, "slices")) { SETUP_MASK(SLICES, "slices"); res = parse_integer(parser, val, 4, 4096, &shape->nslices); + if(!(mask & BIT(STACKS))) + shape->nstacks = shape->nslices / 2; /* if unset, new default value */ + } else if(!strcmp((char*)key->data.scalar.value, "stacks")) { + SETUP_MASK(STACKS, "stacks"); + res = parse_integer(parser, val, 2, 4096, &shape->nstacks); } else { log_err(parser, key, "unknown sphere parameter `%s'.\n", key->data.scalar.value); @@ -858,13 +961,6 @@ parse_sphere CHECK_PARAM(RADIUS, "radius"); #undef CHECK_PARAM - #define DEFAULT_PARAM(Flag, Ptr, Value) \ - if(!(mask & BIT(Flag))) { \ - *(Ptr) = Value; \ - } (void)0 - DEFAULT_PARAM(SLICES, &shape->nslices, 16); - #undef DEFAULT_PARAM - exit: out_ishape->i = ishape; return res; @@ -975,6 +1071,11 @@ parse_object 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, "hemisphere")) { + SETUP_MASK(SHAPE, "shape"); + shape->type = SOLPARSER_SHAPE_HEMISPHERE; + res = parse_hemisphere(parser, doc, val, &shape->data.hemisphere); } else if(!strcmp((char*)key->data.scalar.value, "plane")) { SETUP_MASK(SHAPE, "shape"); shape->type = SOLPARSER_SHAPE_PLANE; diff --git a/src/parser/solparser_pivot.c b/src/parser/solparser_pivot.c @@ -191,6 +191,7 @@ parse_x_pivot solxpivot = darray_x_pivot_data_get(&parser->x_pivots) + isolpivot; n = x_pivot->data.mapping.pairs.top - x_pivot->data.mapping.pairs.start; + d3_splat(solxpivot->ref_point, 0); /* default value */ FOR_EACH(i, 0, n) { yaml_node_t* key; yaml_node_t* val; @@ -240,15 +241,6 @@ parse_x_pivot CHECK_PARAM(TARGET, "target"); #undef CHECK_PARAM - #define DEFAULT_PARAM(Flag, Ptr, Value) \ - if(!(mask & BIT(Flag))) { \ - *(Ptr) = Value; \ - } (void)0 - DEFAULT_PARAM(REF_POINT, solxpivot->ref_point, 0); - DEFAULT_PARAM(REF_POINT, solxpivot->ref_point+1, 0); - DEFAULT_PARAM(REF_POINT, solxpivot->ref_point+2, 0); - #undef DEFAULT_PARAM - exit: out_isolpivot->i = isolpivot; return res; @@ -292,6 +284,8 @@ parse_zx_pivot solxzpivot = darray_zx_pivot_data_get(&parser->zx_pivots) + isolpivot; n = zx_pivot->data.mapping.pairs.top - zx_pivot->data.mapping.pairs.start; + solxzpivot->spacing = 0; /* default value */ + d3_splat(solxzpivot->ref_point, 0); /* default value */ FOR_EACH(i, 0, n) { yaml_node_t* key; yaml_node_t* val; @@ -348,16 +342,6 @@ parse_zx_pivot CHECK_PARAM(TARGET, "target"); #undef CHECK_PARAM - #define DEFAULT_PARAM(Flag, Ptr, Value) \ - if(!(mask & BIT(Flag))) { \ - *(Ptr) = Value; \ - } (void)0 - DEFAULT_PARAM(SPACING, &solxzpivot->spacing, 0); - DEFAULT_PARAM(REF_POINT, solxzpivot->ref_point, 0); - DEFAULT_PARAM(REF_POINT, solxzpivot->ref_point+1, 0); - DEFAULT_PARAM(REF_POINT, solxzpivot->ref_point+2, 0); - #undef DEFAULT_PARAM - exit: out_isolpivot->i = isolpivot; return res; diff --git a/src/parser/solparser_shape.h b/src/parser/solparser_shape.h @@ -33,6 +33,7 @@ enum solparser_shape_type { SOLPARSER_SHAPE_PARABOL, SOLPARSER_SHAPE_PARABOLIC_CYLINDER, SOLPARSER_SHAPE_HYPERBOL, + SOLPARSER_SHAPE_HEMISPHERE, SOLPARSER_SHAPE_PLANE, SOLPARSER_SHAPE_SPHERE, SOLPARSER_SHAPE_STL /* Imported STereo Lithography */ @@ -260,6 +261,56 @@ solparser_shape_hyperboloid_copy_and_release } /******************************************************************************* +* Hemisphere shape +******************************************************************************/ +struct solparser_shape_hemisphere { + double radius; + struct darray_polyclip polyclips; + long nslices; /* < 0 if not defined */ + long nstacks; /* < 0 if not defined */ +}; + +static INLINE void +solparser_shape_hemisphere_init + (struct mem_allocator* allocator, + struct solparser_shape_hemisphere* hemisphere) +{ + ASSERT(hemisphere); + hemisphere->nslices = -1; + darray_polyclip_init(allocator, &hemisphere->polyclips); +} + +static INLINE void +solparser_shape_hemisphere_release + (struct solparser_shape_hemisphere* hemisphere) +{ + ASSERT(hemisphere); + darray_polyclip_release(&hemisphere->polyclips); +} + +static INLINE res_T +solparser_shape_hemisphere_copy + (struct solparser_shape_hemisphere* dst, + const struct solparser_shape_hemisphere* src) +{ + ASSERT(dst && src); + dst->radius = src->radius; + dst->nslices = src->nslices; + return darray_polyclip_copy(&dst->polyclips, &src->polyclips); +} + +static INLINE res_T +solparser_shape_hemisphere_copy_and_release + (struct solparser_shape_hemisphere* dst, + struct solparser_shape_hemisphere* src) +{ + ASSERT(dst && src); + dst->radius = src->radius; + dst->nslices = src->nslices; + return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips); +} + +/******************************************************************************* * Plane shape ******************************************************************************/ struct solparser_shape_plane { @@ -315,11 +366,13 @@ struct solparser_shape_cylinder { double height; double radius; long nslices; + long nstacks; }; struct solparser_shape_sphere { double radius; long nslices; + long nstacks; }; struct solparser_shape_cuboid_id { size_t i; }; @@ -327,6 +380,7 @@ 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_hemisphere_id { size_t i; }; struct solparser_shape_plane_id { size_t i; }; struct solparser_shape_sphere_id { size_t i; }; @@ -339,6 +393,7 @@ struct solparser_shape { struct solparser_shape_paraboloid_id parabol; struct solparser_shape_paraboloid_id parabolic_cylinder; struct solparser_shape_hyperboloid_id hyperbol; + struct solparser_shape_hemisphere_id hemisphere; 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 @@ -32,6 +32,13 @@ static const char* input[] = { " - operation : AND\n", " vertices : [[1, 2],[3, 4],[6, 7]]\n", " material: *lambertian\n", + "- geometry: &hemisphere1\n", + " - hemisphere:\n", + " radius: 100\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", @@ -61,6 +68,9 @@ static const char* input[] = { " - name: entity0c\n", " primary: 0\n", " geometry: *hyperbol1\n", + " - name: entity0d\n", + " primary: 0\n", + " geometry: *hemisphere1\n", "- entity:\n", " name: entity1\n", " x_pivot:\n", @@ -95,7 +105,7 @@ check_entity0 struct solparser_anchor_id anchor_id; struct solparser_entity_id entity_id; struct solparser_object_id obj_id; - const struct solparser_entity *entity0a, *entity0b; + const struct solparser_entity *entity0a, *entity0b, *entity0c, *entity0d; const struct solparser_material_matte* matte; const struct solparser_material* mtl; const struct solparser_material_double_sided* mtl2; @@ -137,7 +147,7 @@ check_entity0 matte = solparser_get_material_matte(parser, mtl->data.matte); CHECK(matte->reflectivity, 0.5); - CHECK(solparser_entity_get_children_count(entity0), 3); + CHECK(solparser_entity_get_children_count(entity0), 4); CHECK(solparser_entity_get_anchors_count(entity0), 3); anchor_id = solparser_entity_get_anchor(entity0, 0); @@ -186,6 +196,22 @@ check_entity0 entity0_entity0b_entity0b = solparser_get_anchor(parser, anchor_id); CHECK(strcmp(str_cget(&entity0_entity0b_entity0b->name), "entity0b"), 0); CHECK(d3_eq(entity0_entity0b_entity0b->position, d3(tmp, 7, 8, 9)), 1); + + entity_id = solparser_entity_get_child(entity0, 2); + entity0c = solparser_get_entity(parser, entity_id); + CHECK(strcmp(str_cget(&entity0c->name), "entity0c"), 0); + CHECK(entity0c->type, SOLPARSER_ENTITY_GEOMETRY); + NCHECK(entity0->data.geometry.i, entity0c->data.geometry.i); + CHECK(solparser_entity_get_anchors_count(entity0c), 0); + CHECK(solparser_entity_get_children_count(entity0c), 0); + + entity_id = solparser_entity_get_child(entity0, 3); + entity0d = solparser_get_entity(parser, entity_id); + CHECK(strcmp(str_cget(&entity0d->name), "entity0d"), 0); + CHECK(entity0d->type, SOLPARSER_ENTITY_GEOMETRY); + NCHECK(entity0->data.geometry.i, entity0d->data.geometry.i); + CHECK(solparser_entity_get_anchors_count(entity0d), 0); + CHECK(solparser_entity_get_children_count(entity0d), 0); } static void diff --git a/src/parser/test_solparser6.c b/src/parser/test_solparser6.c @@ -35,6 +35,7 @@ main(int argc, char** argv) const struct solparser_shape_paraboloid* parabol; const struct solparser_shape_plane* plane; const struct solparser_shape_hyperboloid* hyperbol; + const struct solparser_shape_hemisphere* hemisphere; const struct solparser_polyclip* polyclip; double pos[2]; FILE* stream; @@ -72,6 +73,12 @@ main(int argc, char** argv) fprintf(stream, " - operation : AND\n"); fprintf(stream, " vertices : [[1, 2], [3, 4], [6, 7]]\n"); fprintf(stream, " material: { ?virtual }\n"); + fprintf(stream, " - hemisphere:\n"); + fprintf(stream, " radius: 100\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); @@ -88,7 +95,7 @@ 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), 4); + CHECK(solparser_geometry_get_objects_count(geom), 5); obj_id = solparser_geometry_get_object(geom, 0); obj = solparser_get_object(parser, obj_id); @@ -140,6 +147,14 @@ main(int argc, char** argv) plane = solparser_get_shape_plane(parser, shape->data.plane); CHECK(plane->nslices, 1); /* Default value */ + obj_id = solparser_geometry_get_object(geom, 4); + obj = solparser_get_object(parser, obj_id); + shape = solparser_get_shape(parser, obj->shape); + CHECK(shape->type, SOLPARSER_SHAPE_HEMISPHERE); + hemisphere = solparser_get_shape_hemisphere(parser, shape->data.hemisphere);; + CHECK(hemisphere->radius, 100); + CHECK(hemisphere->nslices, -1); /* Default value: auto */ + solparser_entity_iterator_next(&it); CHECK(solparser_entity_iterator_eq(&it, &end), 1); diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml @@ -515,6 +515,7 @@ # height: REAL # in ]0, INF) # radius: REAL # in ]0, INF) # [ slices: INTEGER ] # in [4, 4096]. Default 16 +# [ stacks: INTEGER ] # in [1, 4096]. Default 1 # # missing cylinder definition @@ -544,6 +545,9 @@ # slices should be a number - geometry: [ { cylinder: { slices: "dummy" } } ] --- +# stacks +- geometry: [ { cylinder: { stacks: "dummy" } } ] +--- # -1 invalid - geometry: [ { cylinder: { radius: -1 } } ] --- @@ -565,15 +569,27 @@ # 2x slices - geometry: [ { cylinder: { slices: 10, slices: 10 } } ] --- +# stacks +- geometry: [ { cylinder: { stacks: 10, stacks: 10 } } ] +--- # 1 invalid - geometry: [ { cylinder: { height: 1, radius: 1, slices: 1 } } ] --- # 4097 invalid - geometry: [ { cylinder: { height: 1, radius: 1, slices: 4097 } } ] --- +# 0 invalid +- geometry: [ { cylinder: { height: 1, radius: 1, stacks: 0 } } ] +--- +# 4097 invalid +- geometry: [ { cylinder: { height: 1, radius: 1, stacks: 4097 } } ] +--- # 12.5 invalid - geometry: [ { cylinder: { height: 1, radius: 1, slices: 12.5 } } ] --- +# 12.5 invalid +- geometry: [ { cylinder: { height: 1, radius: 1, stacks: 12.5 } } ] +--- # # <obj> ::= @@ -884,6 +900,9 @@ # slices should be a number - geometry: [ { sphere: { slices: "dummy" } } ] --- +# stacks should be a number +- geometry: [ { sphere: { stacks: "dummy" } } ] +--- # -1 invalid - geometry: [ { sphere: { radius: -1 } } ] --- @@ -896,12 +915,21 @@ # 4097 invalid - geometry: [ { sphere: { radius: 1, slices: 4097 } } ] --- +# 0 invalid +- geometry: [ { sphere: { radius: 1, stacks: 0 } } ] +--- +# 4097 invalid +- geometry: [ { sphere: { radius: 1, stacks: 4097 } } ] +--- # 2x radius - geometry: [ { sphere: { radius: 1, radius: 1 } } ] --- # 2x slices - geometry: [ { sphere: { slices: 10, slices: 10 } } ] --- +# 2x stacks +- geometry: [ { sphere: { stacks: 10, stacks: 10 } } ] +--- # # <stl> ::= diff --git a/src/solstice_object.c b/src/solstice_object.c @@ -190,6 +190,7 @@ error: goto exit; } + static res_T create_cylinder (struct solstice* solstice, @@ -243,7 +244,7 @@ create_sphere sphere = solparser_get_shape_sphere(solstice->parser, sphere_id); ASSERT(sphere->nslices > 0 && sphere->nslices < UINT_MAX); res = s3dut_create_sphere(solstice->allocator, sphere->radius, - (unsigned)sphere->nslices, (unsigned)(sphere->nslices/2), &mesh); + (unsigned)sphere->nslices, (unsigned)(sphere->nslices / 2), &mesh); if(res != RES_OK) { fprintf(stderr, "Could not create the sphere 3D data.\n"); goto error; @@ -432,7 +433,6 @@ create_parabolic_cylinder return create_ssol_shape_punched_surface (solstice, &paraboloid->polyclips, &quadric, out_ssol_shape); - } static res_T @@ -458,7 +458,32 @@ create_hyperbol } return create_ssol_shape_punched_surface - (solstice, &hyperboloid->polyclips, &quadric, out_ssol_shape); + (solstice, &hyperboloid->polyclips, &quadric, out_ssol_shape); +} + +static res_T +create_hemisphere + (struct solstice* solstice, + const double transform[12], + const struct solparser_shape_hemisphere_id id, + struct ssol_shape** out_ssol_shape) +{ + const struct solparser_shape_hemisphere* hemisphere; + struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT; + ASSERT(solstice); + + hemisphere = solparser_get_shape_hemisphere(solstice->parser, id); + + quadric.type = SSOL_QUADRIC_HEMISPHERE; + quadric.data.hemisphere.radius = hemisphere->radius; + d33_set(quadric.transform, transform); + d3_set(quadric.transform + 9, transform + 9); + if(hemisphere->nslices > 0) { /* nslices is set */ + quadric.slices_count_hint = (size_t)hemisphere->nslices; + } + + return create_ssol_shape_punched_surface + (solstice, &hemisphere->polyclips, &quadric, out_ssol_shape); } static res_T @@ -542,6 +567,10 @@ create_shaded_shape case SOLPARSER_SHAPE_HYPERBOL: res = create_hyperbol(solstice, transform, shape->data.hyperbol, ssol_shape); break; + case SOLPARSER_SHAPE_HEMISPHERE: + res = + create_hemisphere(solstice, transform, shape->data.hemisphere, ssol_shape); + break; case SOLPARSER_SHAPE_PLANE: res = create_plane(solstice, transform, shape->data.plane, ssol_shape); break; diff --git a/src/solstice_solve.c b/src/solstice_solve.c @@ -33,14 +33,6 @@ write_mc_global(struct solstice* solstice, struct ssol_estimator* estimator) double area, potential, irradiance_factor; ASSERT(solstice && estimator); - #define MC_RCV_NONE { \ - { -1, -1, -1 }, /* Integrated irradiance */ \ - { -1, -1, -1 }, /* Absorptivity loss */ \ - { -1, -1, -1 }, /* Reflectivity loss */ \ - { -1, -1, -1 }, /* Cos loss */ \ - 0, NULL, NULL \ - } - /* get global information */ SSOL(estimator_get_mc_global(estimator, &mc_global)); SSOL(estimator_get_realisation_count(estimator, &nexperiments)); @@ -78,8 +70,8 @@ write_mc_global(struct solstice* solstice, struct ssol_estimator* estimator) const struct str* name = htable_receiver_iterator_key_get(&r_it); struct solstice_receiver* rcv = htable_receiver_iterator_data_get(&r_it); struct ssol_instance* inst = rcv->node->instance; - struct ssol_mc_receiver front = MC_RCV_NONE; - struct ssol_mc_receiver back = MC_RCV_NONE; + struct ssol_mc_receiver front = MC_RCV_NONE__; + struct ssol_mc_receiver back = MC_RCV_NONE__; double f_eff_E = -1, f_eff_SE = -1; /* Front efficiency */ double b_eff_E = -1, b_eff_SE = -1; /* Back efficiency */ uint32_t id; @@ -161,8 +153,8 @@ write_mc_global(struct solstice* solstice, struct ssol_estimator* estimator) while (!htable_primary_iterator_eq(&p_it, &p_end)) { struct solstice_primary* prim = htable_primary_iterator_data_get(&p_it); struct ssol_instance* prim_inst = prim->node->instance; - struct ssol_mc_receiver front = MC_RCV_NONE; - struct ssol_mc_receiver back = MC_RCV_NONE; + struct ssol_mc_receiver front = MC_RCV_NONE__; + struct ssol_mc_receiver back = MC_RCV_NONE__; SSOL(instance_get_id(prim_inst, &prim_id)); switch (rcv->side) { diff --git a/src/test_solstice_simulation.c b/src/test_solstice_simulation.c @@ -296,10 +296,10 @@ read_primary CHECK( sscanf(line, "%s %*u " - "%lg %lg %*u " + "%lg %*lu %lg " "%lg %lg\n", name, /* ID */ - area, cos, /* count */ + area, /* count, */ cos, &E[PRIMARY_SHADOW], &SE[PRIMARY_SHADOW]), 2 * PRIMARY_RESULTS_COUNT__ + 3); } diff --git a/yaml/beam_down.ref b/yaml/beam_down.ref @@ -1,52 +1,52 @@ #--- Sun direction: 90 90 (-3.7494e-33 -6.12323e-17 -1) -7 2 5 10000 0 -500.043 0 # Potential -465.484 0.0183212 -0.930883 3.66351e-05 +7 2 5 100000 0 +500.043 0 +465.46 0.0057839 +0.930834 1.15684e-05 0 0 0 0 0 0 0 0 -tower.secondary.hyperbol 10 421.957 FRONT: 0 0 465.484 0.0183212 0 0 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 0 0 -tower.receptor 14 25 FRONT: 465.484 0.0183212 465.484 0.0183212 0 0 0 0 0.930888 3.66392e-05 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -heliostat4.temp-heliostat150.pivot.reflector 6 100.009 1999 0 0 0 0 -heliostat5.temp-heliostat150.pivot.reflector 30 100.009 1986 0 0 0 0 -heliostat3.temp-heliostat150.pivot.reflector 22 100.009 1997 0 0 0 0 -heliostat2.temp-heliostat150.pivot.reflector 26 100.009 1994 0 0 0 0 -heliostat1.temp-heliostat150.pivot.reflector 34 100.009 2024 0 0 0 0 -10 6 FRONT: 0 0 93.126 1.86312 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 30 FRONT: 0 0 92.325 1.85463 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 22 FRONT: 0 0 93.051 1.86278 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 26 FRONT: 0 0 92.8912 1.86133 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 34 FRONT: 0 0 94.0913 1.86784 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -14 6 FRONT: 93.126 1.86312 93.126 1.86312 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 30 FRONT: 92.325 1.85463 92.325 1.85463 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 22 FRONT: 93.051 1.86278 93.051 1.86278 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 26 FRONT: 92.8912 1.86133 92.8912 1.86133 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 34 FRONT: 94.0913 1.86784 94.0913 1.86784 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +tower.secondary.hyperbol 10 421.957 FRONT: 0 0 465.46 0.0057839 0 0 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 0 0 +tower.receptor 14 25 FRONT: 465.46 0.0057839 465.46 0.0057839 0 0 0 0 0.93084 1.15668e-05 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +heliostat4.temp-heliostat150.pivot.reflector 6 100.009 19915 0 0 0 0 +heliostat5.temp-heliostat150.pivot.reflector 30 100.009 20068 0 0 0 0 +heliostat3.temp-heliostat150.pivot.reflector 22 100.009 19919 0 0 0 0 +heliostat2.temp-heliostat150.pivot.reflector 26 100.009 20054 0 0 0 0 +heliostat1.temp-heliostat150.pivot.reflector 34 100.009 20044 0 0 0 0 +10 6 FRONT: 0 0 92.7742 0.588324 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 30 FRONT: 0 0 93.2842 0.588736 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 22 FRONT: 0 0 92.8029 0.588432 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 26 FRONT: 0 0 93.4242 0.589876 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 34 FRONT: 0 0 93.1748 0.588486 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +14 6 FRONT: 92.7742 0.588324 92.7742 0.588324 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 30 FRONT: 93.2842 0.588736 93.2842 0.588736 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 22 FRONT: 92.8029 0.588432 92.8029 0.588432 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 26 FRONT: 93.4242 0.589876 93.4242 0.589876 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 34 FRONT: 93.1748 0.588486 93.1748 0.588486 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 #--- Sun direction: 50 50 (-0.413176 -0.492404 -0.766044) -7 2 5 10000 0 +7 2 5 100000 0 500.043 0 -136.561 1.90791 -0.80038 0.000222269 +135.852 0.602426 +0.800261 7.05527e-05 0 0 -244.012 1.94769 +245.21 0.615008 0 0 0 0 -tower.secondary.hyperbol 10 421.957 FRONT: 0 0 400.227 0.111144 0 0 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 0 0 -tower.receptor 14 25 FRONT: 136.561 1.90791 136.561 1.90791 0 0 0 0 0.273098 0.0038155 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -heliostat4.temp-heliostat150.pivot.reflector 6 100.009 2045 0 0 0 0 -heliostat5.temp-heliostat150.pivot.reflector 30 100.009 1956 0 0 0 0 -heliostat3.temp-heliostat150.pivot.reflector 22 100.009 1948 0 0 0 0 -heliostat2.temp-heliostat150.pivot.reflector 26 100.009 2049 0 0 0 0 -heliostat1.temp-heliostat150.pivot.reflector 34 100.009 2002 0 0 0 0 -10 6 FRONT: 0 0 80.2952 1.58372 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 30 FRONT: 0 0 75.2847 1.52678 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 22 FRONT: 0 0 77.9198 1.58423 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 26 FRONT: 0 0 83.5939 1.64675 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -10 34 FRONT: 0 0 83.1332 1.66167 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 -14 6 FRONT: 22.2344 0.907756 22.2344 0.907756 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 30 FRONT: 18.29 0.819036 18.29 0.819036 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 22 FRONT: 24.7238 0.963323 24.7238 0.963323 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 26 FRONT: 33.4259 1.11916 33.4259 1.11916 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -14 34 FRONT: 37.8866 1.19599 37.8866 1.19599 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +tower.secondary.hyperbol 10 421.957 FRONT: 0 0 400.167 0.0352796 0 0 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 0 0 +tower.receptor 14 25 FRONT: 135.852 0.602426 135.852 0.602426 0 0 0 0 0.271681 0.00120475 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +heliostat4.temp-heliostat150.pivot.reflector 6 100.009 20095 0 0 0 0 +heliostat5.temp-heliostat150.pivot.reflector 30 100.009 20027 0 0 0 0 +heliostat3.temp-heliostat150.pivot.reflector 22 100.009 19777 0 0 0 0 +heliostat2.temp-heliostat150.pivot.reflector 26 100.009 19976 0 0 0 0 +heliostat1.temp-heliostat150.pivot.reflector 34 100.009 20125 0 0 0 0 +10 6 FRONT: 0 0 78.903 0.497568 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 30 FRONT: 0 0 77.0867 0.487147 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 22 FRONT: 0 0 79.1052 0.503835 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 26 FRONT: 0 0 81.4942 0.515816 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +10 34 FRONT: 0 0 83.5784 0.526554 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 +14 6 FRONT: 22.1799 0.286704 22.1799 0.286704 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 30 FRONT: 18.6614 0.26147 18.6614 0.26147 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 22 FRONT: 25.3271 0.308097 25.3271 0.308097 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 26 FRONT: 31.6777 0.345324 31.6777 0.345324 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 +14 34 FRONT: 38.0063 0.378737 38.0063 0.378737 0 0 0 0 BACK: -1 -1 -1 -1 -1 -1 -1 -1 diff --git a/yaml/test07.ref b/yaml/test07.ref @@ -0,0 +1,12 @@ +#--- Sun direction: 0 90 (-6.12323e-17 -0 -1) +7 1 1 10000 0 +56.3503 0 +0 0 +0.666607 0.00232391 +0 0 +28.093 0 +0 0 +0 0 +square_receiver 2 100 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 28.093 0 0 0 0 0 0 0 +reflector 6 56.3503 10000 0 0 0 0 +2 6 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 28.093 0 0 0 0 0 diff --git a/yaml/test07.yaml b/yaml/test07.yaml @@ -0,0 +1,36 @@ +- sun: &sun { dni: 1 } + +- material: &specular + front: + mirror: { reflectivity: 1, roughness: 0 } + back: + mirror: { reflectivity: 1, roughness: 0 } + +- geometry: &hemisphere + - material: *specular + hemisphere: + radius: 3 + slices: 32 + +- 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: *hemisphere + +- entity: + name: "square_receiver" + primary: 0 + transform: { rotation: [0, 0, 0], translation: [0, 0, 4] } + geometry: *big_square diff --git a/yaml/test07_receiver.yaml b/yaml/test07_receiver.yaml @@ -0,0 +1 @@ +- { name: "square_receiver", side: BACK }