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 24b0c63edfc72d53f018c58ecaeb00b67d951751
parent ca263bca82309e52f94da0c38c01549faaef5203
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 23 Nov 2016 10:45:26 +0100

Update the pivot fileformat and load its data

Diffstat:
Mdoc/input | 21+++++++++++++--------
Msrc/parser/solstice_entity.h | 21+++++++++++++++++----
Msrc/parser/solstice_parser.c | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/parser/solstice_pivot.h | 2+-
Msrc/parser/test_solstice_parser2.c | 16++++++++++------
Msrc/parser/test_solstice_parser3.c | 12+++++++++---
6 files changed, 153 insertions(+), 47 deletions(-)

diff --git a/doc/input b/doc/input @@ -3,7 +3,7 @@ -------------------------------------------------------------------------------- # Declare materials - material: &lambertian - matte: + matte: reflectivity: 1 - material: &mirror mirror: { reflectivity: 1, roughness: 0 } @@ -57,7 +57,7 @@ pivot: point: [0, 0, 0] normal: [0, 1, 0] - target: "entity0.anchor0" + - entity: <<: *composition @@ -110,7 +110,11 @@ <target> ::= target: - <anchor-identifier> | <real3> | <sun> + anchor: <anchor-identifier> + | direction: <real3> + | position: <real3> + | <sun> + ---------------------------------------- <shape> ::= @@ -221,6 +225,12 @@ name: STRING position: <real3> +<entity-identifier> ::= + STRING[.STRING ... ] + +<anchor-identifier> ::= + <entity-identifier>.STRING + ---------------------------------------- <sun> ::= sun: @@ -259,9 +269,4 @@ wavelength: REAL data: REAL -<identifier> ::= - name: STRING - -<anchor-identifier> ::= - "<identifier>.<identifier>.<identifier>" diff --git a/src/parser/solstice_entity.h b/src/parser/solstice_entity.h @@ -26,6 +26,11 @@ #include <rsys/list.h> #include <rsys/str.h> +enum solstice_entity_type { + SOLSTICE_ENTITY_GEOMETRY, + SOLSTICE_ENTITY_PIVOT +}; + struct solstice_entity_id { size_t i; }; #define DARRAY_NAME child_id @@ -54,7 +59,12 @@ struct solstice_entity { double translation[3]; struct str name; - struct solstice_geometry_id geometry; + + enum solstice_entity_type type; + union { + struct solstice_geometry_id geometry; + struct solstice_pivot_id pivot; + } data; /* Internal data. Should not be acceded directly. */ struct htable_str2sols str2anchors; @@ -70,7 +80,8 @@ solstice_entity_init ASSERT(entity); d3_splat(entity->rotation, 0); d3_splat(entity->translation, 0); - entity->geometry.i = SIZE_MAX; + entity->type = SOLSTICE_ENTITY_GEOMETRY; + entity->data.geometry.i = SIZE_MAX; str_init(allocator, &entity->name); htable_str2sols_init(allocator, &entity->str2anchors); htable_str2sols_init(allocator, &entity->str2children); @@ -97,7 +108,8 @@ solstice_entity_copy ASSERT(dst && src); d3_set(dst->translation, src->translation); d3_set(dst->rotation, src->rotation); - dst->geometry = src->geometry; + dst->type = src->type; + dst->data = src->data; res = str_copy(&dst->name, &src->name); if(res != RES_OK) return res; res = htable_str2sols_copy(&dst->str2anchors, &src->str2anchors); @@ -119,7 +131,8 @@ solstice_entity_copy_and_release ASSERT(dst && src); d3_set(dst->translation, src->translation); d3_set(dst->rotation, src->rotation); - dst->geometry = src->geometry; + dst->type = src->type; + dst->data = src->data; res = str_copy_and_release(&dst->name, &src->name); if(res != RES_OK) return res; res = htable_str2sols_copy_and_release(&dst->str2anchors, &src->str2anchors); diff --git a/src/parser/solstice_parser.c b/src/parser/solstice_parser.c @@ -135,6 +135,11 @@ #define DARRAY_FUNCTOR_COPY_AND_RELEASE solstice_anchor_copy_and_release #include <rsys/dynamic_array.h> +/* Declare the array of pivots */ +#define DARRAY_NAME pivot +#define DARRAY_DATA struct solstice_pivot +#include <rsys/dynamic_array.h> + /* Declare the hash table that maps the address of a YAML node to the id of its * in memory representation. */ #define HTABLE_NAME yaml2sols @@ -179,8 +184,9 @@ struct solstice_parser { struct htable_str2sols str2entities; struct darray_entity entities; - /* Anchors */ + /* Miscellaneous */ struct darray_anchor anchors; + struct darray_pivot pivots; ref_T ref; struct mem_allocator* allocator; @@ -205,7 +211,8 @@ static res_T parse_pivot (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* pivot); + const yaml_node_t* pivot, + struct solstice_pivot_id* out_isolpivot); static res_T parse_sun @@ -269,13 +276,14 @@ parser_clear(struct solstice_parser* parser) solstice_sun_clear(&parser->sun); parser->sun_key = 0; - /* Entitiies */ + /* Entities */ htable_yaml2sols_clear(&parser->yaml2entities); htable_str2sols_clear(&parser->str2entities); darray_entity_clear(&parser->entities); - /* Anchors */ + /* Miscellaneous */ darray_anchor_clear(&parser->anchors); + darray_pivot_clear(&parser->pivots); } static void @@ -319,8 +327,9 @@ parser_release(ref_T* ref) htable_str2sols_release(&parser->str2entities); darray_entity_release(&parser->entities); - /* Anchors */ + /* Miscellaneous */ darray_anchor_release(&parser->anchors); + darray_pivot_release(&parser->pivots); MEM_RM(parser->allocator, parser); } @@ -2274,13 +2283,15 @@ parse_entity (parser, doc, val, &solent->str2children, &solent->children); } else if(!strcmp((char*)key->data.scalar.value, "geometry")) { SETUP_MASK(DATA, "data"); - res = parse_geometry(parser, doc, val, &solent->geometry); + solent->type = SOLSTICE_ENTITY_GEOMETRY; + res = parse_geometry(parser, doc, val, &solent->data.geometry); } else if(!strcmp((char*)key->data.scalar.value, "name")) { SETUP_MASK(NAME, "name"); res = parse_identifier_string(parser, val, &solent->name); } else if(!strcmp((char*)key->data.scalar.value, "pivot")) { SETUP_MASK(DATA, "data"); - res = parse_pivot(parser, doc, val); + solent->type = SOLSTICE_ENTITY_PIVOT; + res = parse_pivot(parser, doc, val, &solent->data.pivot); } else if(!strcmp((char*)key->data.scalar.value, "transform")) { SETUP_MASK(TRANSFORM, "transform"); res = parse_transform @@ -2347,19 +2358,54 @@ error: * Pivot ******************************************************************************/ static res_T +parse_anchor_alias + (struct solstice_parser* parser, + const yaml_node_t* alias, + struct solstice_anchor_id* out_ianchor) +{ + const struct solstice_anchor* anchor = NULL; + intptr_t ianchor = INTPTR_MAX; + res_T res = RES_OK; + ASSERT(parser && alias && out_ianchor); + + if(alias->type != YAML_SCALAR_NODE) { + log_err(parser, alias, "expect an anchor idententifier.\n"); + res = RES_BAD_ARG; + goto error; + } + + anchor = solstice_parser_find_anchor(parser, (char*)alias->data.scalar.value); + if(!anchor) { + log_err(parser, alias, "undefined anchor `%s'.\n", + alias->data.scalar.value); + res = RES_BAD_ARG; + goto error; + } + + ianchor = anchor - darray_anchor_cdata_get(&parser->anchors); + ASSERT(ianchor >= 0); + ASSERT((size_t)ianchor < darray_anchor_size_get(&parser->anchors)); + +exit: + out_ianchor->i = (size_t)ianchor; + return res; +error: + ianchor = INTPTR_MAX; + goto exit; +} + +static res_T parse_target (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* target) + const yaml_node_t* target, + struct solstice_pivot* pivot) { enum { POLICY }; - struct solstice_sun* sun; /* TODO */ - double direction[3]; - double position[3]; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ res_T res = RES_OK; - ASSERT(doc && target); + ASSERT(doc && target && pivot); if(target->type != YAML_MAPPING_NODE) { log_err(parser, target, "expect a target definition.\n"); @@ -2388,14 +2434,28 @@ parse_target } \ mask |= BIT(Flag); \ } (void)0 - if(!strcmp((char*)key->data.scalar.value, "direction")) { + if(!strcmp((char*)key->data.scalar.value, "anchor")) { SETUP_MASK(POLICY, "policy"); - res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, direction); + pivot->target_type = SOLSTICE_TARGET_ANCHOR; + res = parse_anchor_alias(parser, val, &pivot->target.anchor); + } else if(!strcmp((char*)key->data.scalar.value, "direction")) { + SETUP_MASK(POLICY, "policy"); + pivot->target_type = SOLSTICE_TARGET_DIRECTION; + res = parse_real3 + (parser, doc, val, -DBL_MAX, DBL_MAX, pivot->target.direction); } else if(!strcmp((char*)key->data.scalar.value, "position")) { SETUP_MASK(POLICY, "policy"); - res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, position); + pivot->target_type = SOLSTICE_TARGET_POSITION; + res = parse_real3 + (parser, doc, val, -DBL_MAX, DBL_MAX, pivot->target.position); } else if(!strcmp((char*)key->data.scalar.value, "sun")) { + /* There is only one sun per YAML file. It is thus sufficient to define + * the target_type to SOLSTICE_TARGET_SUN to indentify which data is + * targeted, i.e. it is not necessary to store the identifier of the sun + * to target */ + struct solstice_sun* sun; SETUP_MASK(POLICY, "policy"); + pivot->target_type = SOLSTICE_TARGET_SUN; res = parse_sun(parser, doc, val, &sun); } else { log_err(parser, key, "unknown target parameter `%s'.\n", @@ -2423,17 +2483,16 @@ static res_T parse_pivot (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* pivot) + const yaml_node_t* pivot, + struct solstice_pivot_id* out_isolpivot) { enum { NORMAL, POINT, TARGET, TRANSFORM }; - double point[3]; - double normal[3]; - double translation[3] = {0, 0, 0}; - double rotation[3] = {0, 0, 0}; + struct solstice_pivot* solpivot = NULL; + size_t isolpivot = SIZE_MAX; int mask = 0; /* Register the parsed attributes */ intptr_t i, n; res_T res = RES_OK; - ASSERT(doc && pivot); + ASSERT(doc && pivot && out_isolpivot); if(pivot->type != YAML_MAPPING_NODE) { log_err(parser, pivot, "expect a pivot definition.\n"); @@ -2441,6 +2500,16 @@ parse_pivot goto error; } + /* Allocate the solstice pivot */ + isolpivot = darray_pivot_size_get(&parser->pivots); + res = darray_pivot_resize(&parser->pivots, isolpivot + 1); + if(res != RES_OK) { + log_err(parser, pivot, "could not allocate the pivot.\n"); + res = RES_BAD_ARG; + goto error; + } + solpivot = darray_pivot_data_get(&parser->pivots) + isolpivot; + n = pivot->data.mapping.pairs.top - pivot->data.mapping.pairs.start; FOR_EACH(i, 0, n) { yaml_node_t* key; @@ -2464,16 +2533,17 @@ parse_pivot } (void)0 if(!strcmp((char*)key->data.scalar.value, "point")) { SETUP_MASK(POINT, "point"); - res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, point); + res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solpivot->point); } else if(!strcmp((char*)key->data.scalar.value, "normal")) { SETUP_MASK(NORMAL, "normal"); - res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, normal); + res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solpivot->normal); } else if(!strcmp((char*)key->data.scalar.value, "target")) { SETUP_MASK(TARGET, "target"); - res = parse_target(parser, doc, val); + res = parse_target(parser, doc, val, solpivot); } else if(!strcmp((char*)key->data.scalar.value, "transform")) { SETUP_MASK(TRANSFORM, "transform"); - res = parse_transform(parser, doc, val, translation, rotation); + res = parse_transform + (parser, doc, val, solpivot->translation, solpivot->rotation); } else { log_err(parser, key, "unknown pivot parameter `%s'.\n", key->data.scalar.value); @@ -2491,11 +2561,17 @@ parse_pivot } (void)0 CHECK_PARAM(POINT, "point"); CHECK_PARAM(NORMAL, "normal"); + CHECK_PARAM(TARGET, "target"); #undef CHECK_PARAM exit: + out_isolpivot->i = isolpivot; return res; error: + if(solpivot) { + darray_pivot_pop_back(&parser->pivots); + isolpivot = SIZE_MAX; + } goto exit; } @@ -2831,6 +2907,7 @@ solstice_parser_create darray_object_init(mem_allocator, &parser->objects); darray_geometry_init(mem_allocator, &parser->geometries); + /* Sun */ solstice_sun_init(mem_allocator, &parser->sun); /* Entities */ @@ -2840,6 +2917,7 @@ solstice_parser_create /* Anchors */ darray_anchor_init(mem_allocator, &parser->anchors); + darray_pivot_init(mem_allocator, &parser->pivots); exit: *out_parser = parser; diff --git a/src/parser/solstice_pivot.h b/src/parser/solstice_pivot.h @@ -68,8 +68,8 @@ solstice_anchor_copy_and_release struct solstice_pivot { double point[3]; double normal[3]; - double position[3]; double rotation[3]; + double translation[3]; enum solstice_target_type target_type; union { double position[3]; /* World space position */ diff --git a/src/parser/test_solstice_parser2.c b/src/parser/test_solstice_parser2.c @@ -118,8 +118,9 @@ main(int argc, char** argv) CHECK(d3_eq(entity->rotation, d3(tmp, 4, 5, 6)), 1); CHECK(strcmp("lvl 0", str_cget(&entity->name)), 0); CHECK(solstice_entity_get_children_count(entity), 2); - geom_id = entity->geometry; - geom = solstice_parser_get_geometry(parser, entity->geometry); + CHECK(entity->type, SOLSTICE_ENTITY_GEOMETRY); + geom_id = entity->data.geometry; + geom = solstice_parser_get_geometry(parser, entity->data.geometry); CHECK(geom == geoms[0] || geom == geoms[1], 1); CHECK(solstice_geometry_get_objects_count(geom), 1); obj_id = solstice_geometry_get_object(geom, 0); @@ -144,8 +145,9 @@ main(int argc, char** argv) CHECK(d3_eq(entity1a->rotation, d3_splat(tmp, 0)), 1); CHECK(strcmp("lvl1a", str_cget(&entity1a->name)), 0); CHECK(solstice_entity_get_children_count(entity1a), 0); - NCHECK(entity1a->geometry.i, geom_id.i); - geom = solstice_parser_get_geometry(parser, entity1a->geometry); + CHECK(entity1a->type, SOLSTICE_ENTITY_GEOMETRY); + NCHECK(entity1a->data.geometry.i, geom_id.i); + geom = solstice_parser_get_geometry(parser, entity1a->data.geometry); CHECK(geom == geoms[0] || geom == geoms[1], 1); CHECK(solstice_geometry_get_objects_count(geom), 1); obj_id = solstice_geometry_get_object(geom, 0); @@ -171,7 +173,8 @@ main(int argc, char** argv) CHECK(d3_eq(entity1b->rotation, d3(tmp, 3.14, 0, -1)), 1); CHECK(strcmp("lvl1b", str_cget(&entity1b->name)), 0); CHECK(solstice_entity_get_children_count(entity1b), 1); - CHECK(entity1b->geometry.i, geom_id.i); + CHECK(entity1b->type, SOLSTICE_ENTITY_GEOMETRY); + CHECK(entity1b->data.geometry.i, geom_id.i); entity_id = solstice_entity_get_child(entity1b, 0); entity2 = solstice_parser_get_entity(parser, entity_id); @@ -179,7 +182,8 @@ main(int argc, char** argv) CHECK(d3_eq(entity2->rotation, d3_splat(tmp, 0)), 1); CHECK(strcmp("lvl2", str_cget(&entity2->name)), 0); CHECK(solstice_entity_get_children_count(entity2), 0); - CHECK(entity2->geometry.i, geom_id.i); + CHECK(entity2->type, SOLSTICE_ENTITY_GEOMETRY); + CHECK(entity2->data.geometry.i, geom_id.i); entity3 = solstice_parser_find_entity(parser, "lvl 0"); CHECK(entity3, entity); diff --git a/src/parser/test_solstice_parser3.c b/src/parser/test_solstice_parser3.c @@ -85,8 +85,9 @@ main(int argc, char** argv) CHECK(strcmp(str_cget(&entity->name), "entity0"), 0); CHECK(d3_eq(entity->rotation, d3_splat(tmp, 0)), 1); CHECK(d3_eq(entity->translation, d3_splat(tmp, 0)), 1); + CHECK(entity->type, SOLSTICE_ENTITY_GEOMETRY); - geom = solstice_parser_get_geometry(parser, entity->geometry); + geom = solstice_parser_get_geometry(parser, entity->data.geometry); CHECK(solstice_geometry_get_objects_count(geom), 1); obj_id = solstice_geometry_get_object(geom, 0); @@ -127,14 +128,16 @@ main(int argc, char** argv) entity_id = solstice_entity_get_child(entity, 0); entity1 = solstice_parser_get_entity(parser, entity_id); CHECK(strcmp(str_cget(&entity1->name), "entity0a"), 0); - CHECK(entity->geometry.i, entity1->geometry.i); + CHECK(entity1->type, SOLSTICE_ENTITY_GEOMETRY); + CHECK(entity->data.geometry.i, entity1->data.geometry.i); CHECK(solstice_entity_get_anchors_count(entity1), 0); CHECK(solstice_entity_get_children_count(entity1), 0); entity_id = solstice_entity_get_child(entity, 1); entity1 = solstice_parser_get_entity(parser, entity_id); CHECK(strcmp(str_cget(&entity1->name), "entity0b"), 0); - CHECK(entity->geometry.i, entity1->geometry.i); + CHECK(entity->type, SOLSTICE_ENTITY_GEOMETRY); + CHECK(entity->data.geometry.i, entity1->data.geometry.i); CHECK(solstice_entity_get_anchors_count(entity1), 2); CHECK(solstice_entity_get_children_count(entity1), 0); @@ -163,6 +166,9 @@ main(int argc, char** argv) anchor4 = solstice_parser_find_anchor(parser, "entity1.entity0b.anchor1"); CHECK(anchor4, NULL); + solstice_entity_iterator_next(&it); + CHECK(solstice_entity_iterator_eq(&it, &it_end), 1); + CHECK(solstice_parser_load(parser), RES_BAD_OP); solstice_parser_ref_put(parser); fclose(stream);