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 436c4e4c42ae34bc19cea8dd86b40cc2671cb0ae
parent b770f7310e1991c4dab4fa0b60fbcde64abd6fe6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 15 Mar 2017 15:54:30 +0100

Load the "slices" parameter that controls the quadric discretisation

Diffstat:
Mdoc/input | 9++++-----
Msrc/parser/solparser.c | 65++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/parser/solparser_shape.h | 16++++++++++++++--
Msrc/solstice_object.c | 29++++++++++++++++++-----------
4 files changed, 76 insertions(+), 43 deletions(-)

diff --git a/doc/input b/doc/input @@ -1,7 +1,6 @@ #-------------------------------------------------------------------------------- # 1/ Example #-------------------------------------------------------------------------------- - # Declare materials - material: &lambertian matte: @@ -157,7 +156,7 @@ clip: <polyclip-list> # By default slices is automatically compute with respect to the parabol # curvature -[ slices: INTEGER ] # in [1, INF) +[ slices: INTEGER ] # in [4, 4096) <parabolic-cylinder> ::= parabolic-cylinder: # y^2 - 4*focal*z = 0 @@ -165,7 +164,7 @@ clip: <polyclip-list> # By default slices is automatically compute with respect to the hyperbol # curvature -[ slices: INTEGER ] # in [1, INF) +[ 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; @@ -176,7 +175,7 @@ clip: <polyclip-list> # By default slices is automatically compute with respect to the hyperbol # curvature -[ slices: INTEGER ] # in [1, INF) +[ slices: INTEGER ] # in [4, 4096) <hyperboloid_focals> ::= real: REAL # in ]0, INF) @@ -185,7 +184,7 @@ <plane> ::= plane: clip: <polyclip-list> -[ slices: INTEGER ] # in [1, INF). Default 1 +[ slices: INTEGER ] # in [1, 4096). Default 1 <sphere> ::= sphere: diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -1839,7 +1839,7 @@ parse_paraboloid const enum solparser_shape_type type, struct solparser_shape_paraboloid_id* out_ishape) { - enum { CLIP, FOCAL }; + enum { CLIP, FOCAL, SLICES }; struct solparser_shape_paraboloid* shape = NULL; struct darray_paraboloid* paraboloids; const char* name; @@ -1903,6 +1903,9 @@ parse_paraboloid } else if(!strcmp((char*)key->data.scalar.value, "focal")) { SETUP_MASK(FOCAL, "focal"); res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &shape->focal); + } 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 %s parameter `%s'.\n", name, key->data.scalar.value); @@ -1950,7 +1953,7 @@ parse_focals_description res_T res = RES_OK; ASSERT(doc && desc && focals); - if (desc->type != YAML_MAPPING_NODE) { + if(desc->type != YAML_MAPPING_NODE) { log_err(parser, desc, "expect a mapping of focal parameters.\n"); res = RES_BAD_ARG; goto error; @@ -1963,7 +1966,7 @@ parse_focals_description 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) { + if(key->type != YAML_SCALAR_NODE) { log_err(parser, key, "expect focal parameters.\n"); res = RES_BAD_ARG; goto error; @@ -1977,14 +1980,14 @@ parse_focals_description } \ mask |= BIT(Flag); \ } (void)0 - if (!strcmp((char*) key->data.scalar.value, "real")) { + 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")) { + } 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) { + if(res != RES_OK) { log_node(parser, key); goto error; } @@ -2014,7 +2017,7 @@ parse_hyperboloid const yaml_node_t* hyperboloid, struct solparser_shape_hyperboloid_id* out_ishape) { - enum { CLIP, FOCAL }; + enum { CLIP, FOCAL, SLICES }; struct solparser_shape_hyperboloid* shape = NULL; size_t ishape = SIZE_MAX; intptr_t i, n; @@ -2022,7 +2025,7 @@ parse_hyperboloid res_T res = RES_OK; ASSERT(doc && hyperboloid && out_ishape); - if (hyperboloid->type != YAML_MAPPING_NODE) { + if(hyperboloid->type != YAML_MAPPING_NODE) { log_err(parser, hyperboloid, "expect a mapping of hyperbol parameters.\n"); res = RES_BAD_ARG; goto error; @@ -2031,7 +2034,7 @@ parse_hyperboloid /* Allocate a hyperboloid shape */ ishape = darray_hyperboloid_size_get(&parser->hyperbols); res = darray_hyperboloid_resize(&parser->hyperbols, ishape + 1); - if (res != RES_OK) { + if(res != RES_OK) { log_err(parser, hyperboloid, "could not allocate the hyperbol shape.\n"); goto error; } @@ -2044,7 +2047,7 @@ parse_hyperboloid 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) { + if(key->type != YAML_SCALAR_NODE) { log_err(parser, key, "expect hyperbol parameters.\n"); res = RES_BAD_ARG; goto error; @@ -2058,19 +2061,22 @@ parse_hyperboloid } \ mask |= BIT(Flag); \ } (void)0 - if (!strcmp((char*) key->data.scalar.value, "clip")) { + 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")) { + } else if(!strcmp((char*)key->data.scalar.value, "focals")) { SETUP_MASK(FOCAL, "focals"); res = parse_focals_description(parser, doc, val, &shape->focals); + } 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 hyperbol parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; goto error; } - if (res != RES_OK) { + if(res != RES_OK) { log_node(parser, key); goto error; } @@ -2091,7 +2097,7 @@ exit : out_ishape->i = ishape; return res; error: - if (shape) { + if(shape) { darray_hyperboloid_pop_back(&parser->hyperbols); ishape = SIZE_MAX; } @@ -2105,7 +2111,7 @@ parse_plane const yaml_node_t* plane, struct solparser_shape_plane_id* out_ishape) { - enum { CLIP }; + enum { CLIP, SLICES }; struct solparser_shape_plane* shape = NULL; size_t ishape = SIZE_MAX; intptr_t i, n; @@ -2140,14 +2146,22 @@ parse_plane res = RES_BAD_ARG; goto error; } + #define SETUP_MASK(Flag, Name) { \ + if(mask & BIT(Flag)) { \ + log_err(parser, key, \ + "the plane 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")) { - if(mask & BIT(CLIP)) { - log_err(parser, key, "the plane clipping is already defined.\n"); - res = RES_BAD_ARG; - goto error; - } - mask |= BIT(CLIP); + SETUP_MASK(CLIP, "clip"); res = parse_clip(parser, doc, val, &shape->polyclips); + } else if(!strcmp((char*)key->data.scalar.value, "slices")) { + SETUP_MASK(SLICES, "slices"); + res = parse_integer(parser, val, 1, 4096, &shape->nslices); } else { log_err(parser, key, "unknown plane parameter `%s'.\n", key->data.scalar.value); @@ -2158,6 +2172,7 @@ parse_plane log_node(parser, key); goto error; } + #undef SETUP_MASK } if(!(mask & BIT(CLIP))) { log_err(parser, plane, "the plane parameter `clip' is missing.\n"); @@ -2371,7 +2386,7 @@ 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")) { + } 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); @@ -2646,11 +2661,11 @@ parse_anchor } else if(!strcmp((char*)key->data.scalar.value, "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")) { + } else if(!strcmp((char*) key->data.scalar.value, "hyperboloid_image_focals")) { struct solparser_hyperboloid_focals focals; SETUP_MASK(POSITION, "position description"); res = parse_focals_description(parser, doc, val, &focals); - if (res != RES_OK) goto error; + if(res != RES_OK) goto error; d3(solanchor->position, 0, 0, focals.image); } else { log_err(parser, key, "unknown anchor parameter `%s'.\n", @@ -2842,7 +2857,7 @@ parse_entity } else if(!strcmp((char*)key->data.scalar.value, "name")) { SETUP_MASK(NAME, "name"); res = parse_identifier_string(parser, val, &solent.name); - if (!strcmp(str_get(&solent.name), "self")) { + if(!strcmp(str_get(&solent.name), "self")) { /* self is a reserved keyword */ log_err(parser, key, "Reserved keywords cannot be used as names: %s.\n", str_get(&solent.name)); diff --git a/src/parser/solparser_shape.h b/src/parser/solparser_shape.h @@ -159,7 +159,8 @@ solparser_shape_imported_geometry_copy_and_release ******************************************************************************/ struct solparser_shape_paraboloid { double focal; - struct darray_polyclip polyclips; + long nslices; /* < 0 if not defined */ + struct darray_polyclip polyclips; }; static INLINE void @@ -168,6 +169,7 @@ solparser_shape_paraboloid_init struct solparser_shape_paraboloid* paraboloid) { ASSERT(paraboloid); + paraboloid->nslices = -1; darray_polyclip_init(allocator, &paraboloid->polyclips); } @@ -185,6 +187,7 @@ solparser_shape_paraboloid_copy { ASSERT(dst && src); dst->focal = src->focal; + dst->nslices = src->nslices; return darray_polyclip_copy(&dst->polyclips, &src->polyclips); } @@ -195,6 +198,7 @@ solparser_shape_paraboloid_copy_and_release { ASSERT(dst && src); dst->focal = src->focal; + dst->nslices = src->nslices; return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips); } @@ -207,12 +211,13 @@ struct solparser_hyperboloid_focals { }; #define SOLPARSER_HYPERBOLOID_FOCALS_NULL__ { 0, 0 } -static const struct solparser_hyperboloid_focals +static const struct solparser_hyperboloid_focals SOLPARSER_HYPERBOLOID_FOCALS_NULL = SOLPARSER_HYPERBOLOID_FOCALS_NULL__; struct solparser_shape_hyperboloid { struct solparser_hyperboloid_focals focals; struct darray_polyclip polyclips; + long nslices; /* < 0 if not defined */ }; static INLINE void @@ -221,6 +226,7 @@ solparser_shape_hyperboloid_init struct solparser_shape_hyperboloid* hyperboloid) { ASSERT(hyperboloid); + hyperboloid->nslices = -1; darray_polyclip_init(allocator, &hyperboloid->polyclips); } @@ -238,6 +244,7 @@ solparser_shape_hyperboloid_copy { ASSERT(dst && src); dst->focals = src->focals; + dst->nslices = src->nslices; return darray_polyclip_copy(&dst->polyclips, &src->polyclips); } @@ -248,6 +255,7 @@ solparser_shape_hyperboloid_copy_and_release { ASSERT(dst && src); dst->focals = src->focals; + dst->nslices = src->nslices; return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips); } @@ -256,6 +264,7 @@ solparser_shape_hyperboloid_copy_and_release ******************************************************************************/ struct solparser_shape_plane { struct darray_polyclip polyclips; + long nslices; }; static INLINE void @@ -264,6 +273,7 @@ solparser_shape_plane_init struct solparser_shape_plane* plane) { ASSERT(plane); + plane->nslices = 1; darray_polyclip_init(allocator, &plane->polyclips); } @@ -280,6 +290,7 @@ solparser_shape_plane_copy const struct solparser_shape_plane* src) { ASSERT(dst && src); + dst->nslices = src->nslices; return darray_polyclip_copy(&dst->polyclips, &src->polyclips); } @@ -289,6 +300,7 @@ solparser_shape_plane_copy_and_release struct solparser_shape_plane* src) { ASSERT(dst && src); + dst->nslices = src->nslices; return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips); } diff --git a/src/solstice_object.c b/src/solstice_object.c @@ -284,21 +284,21 @@ create_stl ASSERT(str_cget(&stl->filename)); res = sstl_create(NULL, solstice->allocator, 0, &tmp_stl); - if (res != RES_OK) { + if(res != RES_OK) { fprintf(stderr, "Could not create a Solstice Solver STL shape.\n"); goto error; } res = sstl_load(tmp_stl, str_cget(&stl->filename)); - if (res != RES_OK) goto error; + if(res != RES_OK) goto error; res = sstl_get_desc(tmp_stl, &tmp_desc); - if (res != RES_OK) goto error; + if(res != RES_OK) goto error; ASSERT(tmp_desc.triangles_count <= UINT_MAX); ASSERT(tmp_desc.vertices_count <= UINT_MAX); mesh_ctx.transform = transform; mesh_ctx.desc = tmp_desc; res = ssol_shape_create_mesh(solstice->ssol, &ssol_shape); - if (res != RES_OK) { + if(res != RES_OK) { fprintf(stderr, "Could not create the STL mesh shape.\n"); goto error; } @@ -308,20 +308,17 @@ create_stl res = ssol_mesh_setup(ssol_shape, (unsigned)tmp_desc.triangles_count, mesh_ctx_sstl_get_ids, (unsigned)tmp_desc.vertices_count, &vertex_data, 1, &mesh_ctx); - if (res != RES_OK) { + if(res != RES_OK) { fprintf(stderr, "Could not setup STL mesh.\n"); goto error; } exit: - if (tmp_stl) { - SSTL(ref_put(tmp_stl)); - tmp_stl = NULL; - } + if(tmp_stl) SSTL(ref_put(tmp_stl)); *out_stl = ssol_shape; return res; error: - if (ssol_shape) { + if(ssol_shape) { SSOL(shape_ref_put(ssol_shape)); ssol_shape = NULL; } @@ -405,7 +402,9 @@ create_parabol quadric.data.parabol.focal = paraboloid->focal; d33_set(quadric.transform, transform); d3_set(quadric.transform+9, transform+9); - + if(paraboloid->nslices > 0) { /* nslices is set */ + quadric.slices_count_hint = (size_t)paraboloid->nslices; + } return create_ssol_shape_punched_surface (solstice, &paraboloid->polyclips, &quadric, out_ssol_shape); } @@ -427,6 +426,9 @@ create_parabolic_cylinder quadric.data.parabolic_cylinder.focal = paraboloid->focal; d33_set(quadric.transform, transform); d3_set(quadric.transform+9, transform+9); + if(paraboloid->nslices > 0) { /* nslices is set */ + quadric.slices_count_hint = (size_t)paraboloid->nslices; + } return create_ssol_shape_punched_surface (solstice, &paraboloid->polyclips, &quadric, out_ssol_shape); @@ -451,6 +453,9 @@ create_hyperbol quadric.data.hyperbol.img_focal = hyperboloid->focals.image; d33_set(quadric.transform, transform); d3_set(quadric.transform + 9, transform + 9); + if(hyperboloid->nslices > 0) { /* nslices is set */ + quadric.slices_count_hint = (size_t)hyperboloid->nslices; + } return create_ssol_shape_punched_surface (solstice, &hyperboloid->polyclips, &quadric, out_ssol_shape); @@ -468,8 +473,10 @@ create_plane ASSERT(solstice); plane = solparser_get_shape_plane(solstice->parser, id); + ASSERT(plane->nslices > 0); quadric.type = SSOL_QUADRIC_PLANE; + quadric.slices_count_hint = (size_t)plane->nslices; d33_set(quadric.transform, transform); d3_set(quadric.transform+9, transform+9);