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 4ce7c9a04b7517a9f2d747d95fb08651ee1bd32f
parent cc46f2b77eeee79a8b297ceef6b27622fb95853d
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Tue, 14 Mar 2017 18:38:17 +0100

New count outputs; start adding outputs for primary objects (unfinished).

Diffstat:
Msrc/solstice.c | 2++
Msrc/solstice.h | 17+++++++++++++++++
Msrc/solstice_entity.c | 36+++++++++++++++++++++++++++++++-----
Msrc/solstice_solve.c | 53+++++++++++++++++++++++++++++++++++++++++++----------
Msrc/test_solstice_simulation.c | 24++++++++++++++----------
Myaml/beam_down.ref | 4++--
Myaml/test01.ref | 2+-
Myaml/test02.ref | 2+-
Myaml/test03.ref | 2+-
Myaml/test04.ref | 2+-
Myaml/test05.ref | 2+-
11 files changed, 114 insertions(+), 32 deletions(-)

diff --git a/src/solstice.c b/src/solstice.c @@ -535,6 +535,7 @@ solstice_init htable_object_init(allocator, &solstice->objects); htable_anchor_init(allocator, &solstice->anchors); htable_receiver_init(allocator, &solstice->receivers); + htable_primary_init(allocator, &solstice->primaries); darray_nodes_init(allocator, &solstice->roots); darray_nodes_init(allocator, &solstice->pivots); darray_double_init(allocator, &solstice->sun_dirs); @@ -638,6 +639,7 @@ solstice_release(struct solstice* solstice) htable_object_release(&solstice->objects); htable_anchor_release(&solstice->anchors); htable_receiver_release(&solstice->receivers); + htable_primary_release(&solstice->primaries); darray_nodes_release(&solstice->roots); darray_nodes_release(&solstice->pivots); darray_double_release(&solstice->sun_dirs); diff --git a/src/solstice.h b/src/solstice.h @@ -37,6 +37,11 @@ struct solstice_receiver { enum srcvl_side side; }; +struct solstice_primary { + struct solstice_node* node; + double n[3]; +}; + #define DARRAY_NAME nodes #define DARRAY_DATA struct solstice_node* #include <rsys/dynamic_array.h> @@ -68,6 +73,17 @@ struct solstice_receiver { #define HTABLE_DATA struct solstice_receiver #include <rsys/hash_table.h> +#define HTABLE_NAME primary +#define HTABLE_KEY struct str +#define HTABLE_KEY_FUNCTOR_INIT str_init +#define HTABLE_KEY_FUNCTOR_RELEASE str_release +#define HTABLE_KEY_FUNCTOR_COPY str_copy +#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release +#define HTABLE_KEY_FUNCTOR_EQ str_eq +#define HTABLE_KEY_FUNCTOR_HASH str_hash +#define HTABLE_DATA struct solstice_primary +#include <rsys/hash_table.h> + struct solstice { struct ssol_device* ssol; struct ssol_scene* scene; @@ -79,6 +95,7 @@ struct solstice { struct htable_object objects; struct htable_anchor anchors; struct htable_receiver receivers; + struct htable_primary primaries; struct darray_nodes roots; struct darray_nodes pivots; struct ssol_material* mtl_virtual; /* Shared virtual material */ diff --git a/src/solstice_entity.c b/src/solstice_entity.c @@ -19,6 +19,8 @@ #include <solstice/ssol.h> #include <solstice/sanim.h> +#include <rsys/double33.h> + /******************************************************************************* * Helper function ******************************************************************************/ @@ -26,13 +28,27 @@ static res_T update_instance_transform (const struct sanim_node* n, const double transform[12], void* data) { + res_T res = RES_OK; struct solstice_node* node; - ASSERT(n && transform); - (void)data; + struct solstice_primary* prim; + struct solstice* solstice = data; + ASSERT(n && transform && data); node = CONTAINER_OF(n, struct solstice_node, anim); if(node->type != SOLSTICE_NODE_GEOMETRY) return RES_OK; - return ssol_instance_set_transform(node->instance, transform); + res = ssol_instance_set_transform(node->instance, transform); + if(res != RES_OK) goto error; + + prim = htable_primary_find(&solstice->primaries, &node->name); + if(prim) { + d3(prim->n, 0, 0, 1); + //SSOL(xxx_get_normal(prim->node->instance, n)); + d33_muld3(prim->n, transform, prim->n); + } +exit: + return res; +error: + goto exit; } static res_T @@ -328,6 +344,16 @@ create_node str_cget(&entity->name)); goto error; } + if (entity->primary) { + struct solstice_primary p; + p.node = node; + res = htable_primary_set(&solstice->primaries, name, &p); + if (res != RES_OK) { + fprintf(stderr, "Could not define the entity `%s' as primary.\n", + str_cget(&entity->name)); + goto error; + } + } } /* Setup the entity receiver flags */ @@ -448,7 +474,7 @@ solstice_setup_entities(struct solstice* solstice) /* Initialialised the world space position of the entity geometry */ res = sanim_node_visit_tree - (&root->anim, dummy_sun_dir, NULL, update_instance_transform); + (&root->anim, dummy_sun_dir, solstice, update_instance_transform); if(res != RES_OK) { fprintf(stderr, "Could not setup the transformation of the entity geometries.\n"); @@ -486,7 +512,7 @@ solstice_update_entities(struct solstice* solstice, const double sun_dir[3]) /* Initialialised the world space position of the entity geometry */ res = sanim_node_visit_tree - (&node->anim, sun_dir, NULL, update_instance_transform); + (&node->anim, sun_dir, solstice, update_instance_transform); if(res != RES_OK) { fprintf(stderr, "Could not update the transformation of the entity geometries.\n"); diff --git a/src/solstice_solve.c b/src/solstice_solve.c @@ -33,23 +33,30 @@ write_global_mc(struct solstice* solstice, struct ssol_estimator* estimator) 0, NULL \ } struct ssol_mc_global mc_global; - struct htable_receiver_iterator it, end; + struct htable_receiver_iterator r_it, r_end; + struct htable_primary_iterator p_it, p_end; const struct solparser_sun* solparser_sun = NULL; - size_t nexperiments; + size_t nexperiments, nfailed, nprimary; double irradiance_factor; ASSERT(solstice && estimator); /* get global information */ SSOL(estimator_get_mc_global(estimator, &mc_global)); SSOL(estimator_get_realisation_count(estimator, &nexperiments)); + SSOL(estimator_get_sampled_count(estimator, &nprimary)); + SSOL(estimator_get_failed_count(estimator, &nfailed)); SSOL(estimator_get_sampled_area(estimator, &irradiance_factor)); solparser_sun = solparser_get_sun(solstice->parser); irradiance_factor = 1.0 / (solparser_sun->dni * irradiance_factor); - fprintf(solstice->output, "%lu %lu\n", + /* Counts */ + fprintf(solstice->output, "%lu %lu %lu %lu\n", (unsigned long)htable_receiver_size_get(&solstice->receivers), - (unsigned long)nexperiments); + (unsigned long)nprimary, + (unsigned long)nexperiments, + (unsigned long)nfailed); + /* Global data */ fprintf(solstice->output, "%g %g # Shadowing\n", mc_global.shadowed.E, mc_global.shadowed.SE); fprintf(solstice->output, "%g %g # Missing\n", @@ -57,11 +64,12 @@ write_global_mc(struct solstice* solstice, struct ssol_estimator* estimator) fprintf(solstice->output, "%g %g # Cos\n", mc_global.cos_factor.E, mc_global.cos_factor.SE); - htable_receiver_begin(&solstice->receivers, &it); - htable_receiver_end(&solstice->receivers, &end); - while(!htable_receiver_iterator_eq(&it, &end)) { - const struct str* name = htable_receiver_iterator_key_get(&it); - struct solstice_receiver* rcv = htable_receiver_iterator_data_get(&it); + /* Receivers' data */ + htable_receiver_begin(&solstice->receivers, &r_it); + htable_receiver_end(&solstice->receivers, &r_end); + while(!htable_receiver_iterator_eq(&r_it, &r_end)) { + 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_RECEIVER_NULL; struct ssol_mc_receiver back = MC_RECEIVER_NULL; @@ -69,7 +77,7 @@ write_global_mc(struct solstice* solstice, struct ssol_estimator* estimator) double b_eff_E = -1, b_eff_SE = -1; /* Back efficiency */ uint32_t id; - htable_receiver_iterator_next(&it); + htable_receiver_iterator_next(&r_it); switch(rcv->side) { case SRCVL_FRONT: SSOL(estimator_get_mc_receiver(estimator, inst, SSOL_FRONT, &front)); @@ -108,6 +116,31 @@ write_global_mc(struct solstice* solstice, struct ssol_estimator* estimator) back.absorptivity_loss.E, back.absorptivity_loss.SE, b_eff_E, b_eff_SE); } + + /* Primary-instances' data */ + htable_primary_begin(&solstice->primaries, &p_it); + htable_primary_end(&solstice->primaries, &p_end); + while (!htable_primary_iterator_eq(&p_it, &p_end)) { + const struct str* name = htable_primary_iterator_key_get(&p_it); + struct solstice_primary* prim = htable_primary_iterator_data_get(&p_it); + struct ssol_mc_sampled sampled; + double a, c, sun[3]; + uint32_t id; + + SSOL(sun_get_direction(solstice->sun, sun)); + c = -d3_dot(prim->n, sun); + htable_primary_iterator_next(&p_it); + SSOL(estimator_get_mc_sampled(estimator, prim->node->instance, &sampled)); + SSOL(instance_get_id(prim->node->instance, &id)); + SSOL(instance_get_area(prim->node->instance, &a)); + fprintf(solstice->output, + "%s %u " + "%g %g %lu %lg %lg\n", + str_cget(name), (unsigned) id, + a, c, (unsigned long)sampled.nb_samples, + sampled.shadowed.E, sampled.shadowed.SE + ); + } } /******************************************************************************* diff --git a/src/test_solstice_simulation.c b/src/test_solstice_simulation.c @@ -174,7 +174,9 @@ get_angles_and_counts (FILE* ref_file, double angles[2], unsigned long* recv_count, - unsigned long* realisation_count) + unsigned long* primary_count, + unsigned long* realisation_count, + unsigned long* failed_count) { char line[MAX_LINE_LEN]; int n; @@ -182,7 +184,9 @@ get_angles_and_counts NCHECK(ref_file, NULL); NCHECK(angles, NULL); NCHECK(recv_count, NULL); + NCHECK(primary_count, NULL); NCHECK(realisation_count, NULL); + NCHECK(failed_count, NULL); /* Get sun dir */ CHECK(read_line(line, sizeof(line), ref_file), 1); @@ -190,10 +194,10 @@ get_angles_and_counts n = sscanf(line+strlen(sundir_header), "%lg%lg", &angles[0], &angles[1]); CHECK(n, 2); - /* Get #receivers and #realisations */ + /* Get counts */ CHECK(read_line(line, sizeof(line), ref_file), 1); - n = sscanf(line, "%lu%lu", recv_count, realisation_count); - CHECK(n, 2); + n = sscanf(line, "%lu%lu%lu%lu", recv_count, primary_count, realisation_count, failed_count); + CHECK(n, 4); } static void @@ -259,7 +263,7 @@ check_1_receiver const double* reference_SE) { double a[2]; - unsigned long c1, c2; + unsigned long c1, c2, c3, c4; int found = 0; NCHECK(test_file, NULL); @@ -267,7 +271,7 @@ check_1_receiver NCHECK(reference_E, NULL); NCHECK(reference_SE, NULL); - get_angles_and_counts(test_file, a, &c1, &c2); /* Skip headers */ + get_angles_and_counts(test_file, a, &c1, &c2, &c3, &c4); /* Skip headers */ while(!feof(test_file) && !found) { char line[MAX_LINE_LEN]; @@ -304,11 +308,11 @@ check_1_global { char line[MAX_LINE_LEN], test_name[MAX_LINE_LEN]; double a[2]; - unsigned long r1, r2; + unsigned long c1, c2, c3, c4; int nb; double test_E, test_SE; - get_angles_and_counts(test_file, a, &r1, &r2); + get_angles_and_counts(test_file, a, &c1, &c2, &c3, &c4); do { CHECK(read_line(line, sizeof(line), test_file), 1); @@ -377,7 +381,7 @@ 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; + unsigned long c1, c2, realisation_count, c4; int n; ASSERT(base_name); @@ -394,7 +398,7 @@ do_check(const char* binary, const char* dir, const char* base_name) FILE* fp = NULL; int fd = -1; - get_angles_and_counts(ref_file, sun_angles, &c1, &realisation_count); + get_angles_and_counts(ref_file, sun_angles, &c1, &c2, &realisation_count, &c4); fd = create_tmp_file(test_file_name, sizeof(test_file_name)); fp = fdopen(fd, "r"); diff --git a/yaml/beam_down.ref b/yaml/beam_down.ref @@ -1,12 +1,12 @@ #--- Sun direction: 0 90 (-3.7494e-33 -6.12323e-17 -1) -2 10000 +2 5 10000 0 0 0 # Shadowing 0 0 # Missing 0.92387953251128675612818318939679 0.1 # Cos tower.secondary.hyperbol 10 FRONT: 0 0 465.464 0.00509812 0 0 0 0 0 0 BACK: 0 0 0 0 0 0 0 0 0 0 tower.receptor 14 FRONT: 465.464 0.00509812 465.464 0.00509812 0 0 0 0 0.930847 1.01954e-05 BACK: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 #--- Sun direction: 50 50 (-0.413176 -0.492404 -0.766044) -2 10000 +2 5 10000 0 0 0 # Shadowing 0 0 # Missing 0.8 0.1 # Cos diff --git a/yaml/test01.ref b/yaml/test01.ref @@ -1,5 +1,5 @@ #--- Sun direction: 0 90 (-6.12323e-17 -0 -1) -1 10000 +1 1 10000 0 0 0 # Shadowing 0 0 # Missing 1 0 # Cos diff --git a/yaml/test02.ref b/yaml/test02.ref @@ -1,5 +1,5 @@ #--- Sun direction: 0 90 (-6.12323e-17 -0 -1) -1 100000 +1 1 100000 0 0 0 # Shadowing 99 0.0313065 # Missing 1 0 # Cos diff --git a/yaml/test03.ref b/yaml/test03.ref @@ -1,5 +1,5 @@ #--- Sun direction: 0 45 (-0.707107 -0 -0.707107) -1 10000 +1 1 10000 0 0 0 # Shadowing 0 0 # Missing 0.707107 0 # Cos diff --git a/yaml/test04.ref b/yaml/test04.ref @@ -1,5 +1,5 @@ #--- Sun direction: 0 45 (-0.707107 -0 -0.707107) -1 10000 +1 1 10000 0 0 0 # Shadowing 0 0 # Missing 0.707107 0 # Cos diff --git a/yaml/test05.ref b/yaml/test05.ref @@ -1,5 +1,5 @@ #--- Sun direction: 0 90 (-6.12323e-17 -0 -1) -1 10000 +1 1 10000 0 0 0 # Shadowing 0 0 # Missing 1 0 # Cos