commit 47965602f1064654c333c0e048253f67e0f3a6de
parent 8af1dd6353c0d9dbdbdd238b75ba6fad0ee23b32
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 31 Mar 2017 11:02:06 +0200
Merge remote-tracking branch 'origin/feature_outputs' into develop
Diffstat:
16 files changed, 584 insertions(+), 201 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -155,6 +155,7 @@ if(NOT NO_TEST)
add_test_simulation(test03)
add_test_simulation(test04)
add_test_simulation(test05)
+ add_test_simulation(test06)
endif()
diff --git a/src/solstice.c b/src/solstice.c
@@ -536,6 +536,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);
@@ -644,6 +645,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
@@ -38,6 +38,10 @@ struct solstice_receiver {
int per_primitive;
};
+struct solstice_primary {
+ struct solstice_node* node;
+};
+
#define DARRAY_NAME nodes
#define DARRAY_DATA struct solstice_node*
#include <rsys/dynamic_array.h>
@@ -69,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;
@@ -80,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,19 @@ 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);
+ ASSERT(n && transform && data);
(void)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;
+
+exit:
+ return res;
+error:
+ goto exit;
}
static res_T
@@ -328,6 +336,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 +466,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 +504,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
@@ -26,10 +26,11 @@ static void
write_mc_global(struct solstice* solstice, struct ssol_estimator* estimator)
{
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;
- double irradiance_factor;
+ size_t nexperiments, nfailed, nprimary;
+ double area, potential, irradiance_factor;
ASSERT(solstice && estimator);
#define MC_RCV_NONE { \
@@ -42,20 +43,44 @@ write_mc_global(struct solstice* solstice, struct ssol_estimator* estimator)
/* get global information */
SSOL(estimator_get_mc_global(estimator, &mc_global));
- SSOL(estimator_get_count(estimator, &nexperiments));
- SSOL(estimator_get_sampled_area(estimator, &irradiance_factor));
+ 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, &area));
solparser_sun = solparser_get_sun(solstice->parser);
- irradiance_factor = 1.0 / (solparser_sun->dni * irradiance_factor);
+ potential = solparser_sun->dni * area;
+ irradiance_factor = 1 / potential;
- fprintf(solstice->output, "%lu %lu\n",
+ /* Counts */
+ fprintf(solstice->output, "%lu %lu %lu %lu %lu\n",
+ 7, /* #global results count */
(unsigned long)htable_receiver_size_get(&solstice->receivers),
- (unsigned long)nexperiments);
+ (unsigned long)nprimary,
+ (unsigned long)nexperiments,
+ (unsigned long)nfailed);
- 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);
+ /* Global data */
+ fprintf(solstice->output, "%g %g\n",
+ potential, 0.);
+ fprintf(solstice->output, "%g %g\n",
+ mc_global.absorbed.E, mc_global.absorbed.SE);
+ fprintf(solstice->output, "%g %g\n",
+ mc_global.cos_factor.E, mc_global.cos_factor.SE);
+ fprintf(solstice->output, "%g %g\n",
+ mc_global.shadowed.E, mc_global.shadowed.SE);
+ fprintf(solstice->output, "%g %g\n",
+ mc_global.missing.E, mc_global.missing.SE);
+ fprintf(solstice->output, "%g %g\n",
+ mc_global.atmosphere.E, mc_global.atmosphere.SE);
+ fprintf(solstice->output, "%g %g\n",
+ mc_global.reflectivity.E, mc_global.reflectivity.SE);
+
+ /* 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_RCV_NONE;
struct ssol_mc_receiver back = MC_RCV_NONE;
@@ -63,47 +88,121 @@ write_mc_global(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));
- f_eff_E = front.integrated_irradiance.E * irradiance_factor;
- f_eff_SE = front.integrated_irradiance.SE * irradiance_factor;
+ f_eff_E = front.integrated_absorbed_irradiance.E * irradiance_factor;
+ f_eff_SE = front.integrated_absorbed_irradiance.SE * irradiance_factor;
break;
case SRCVL_BACK:
SSOL(estimator_get_mc_receiver(estimator, inst, SSOL_BACK, &back));
- b_eff_E = back.integrated_irradiance.E * irradiance_factor;
- b_eff_SE = back.integrated_irradiance.SE * irradiance_factor;
+ b_eff_E = back.integrated_absorbed_irradiance.E * irradiance_factor;
+ b_eff_SE = back.integrated_absorbed_irradiance.SE * irradiance_factor;
break;
case SRCVL_FRONT_AND_BACK:
SSOL(estimator_get_mc_receiver(estimator, inst, SSOL_FRONT, &front));
SSOL(estimator_get_mc_receiver(estimator, inst, SSOL_BACK, &back));
- f_eff_E = front.integrated_irradiance.E * irradiance_factor;
- f_eff_SE = front.integrated_irradiance.SE * irradiance_factor;
- b_eff_E = back.integrated_irradiance.E * irradiance_factor;
- b_eff_SE = back.integrated_irradiance.SE * irradiance_factor;
+ f_eff_E = front.integrated_absorbed_irradiance.E * irradiance_factor;
+ f_eff_SE = front.integrated_absorbed_irradiance.SE * irradiance_factor;
+ b_eff_E = back.integrated_absorbed_irradiance.E * irradiance_factor;
+ b_eff_SE = back.integrated_absorbed_irradiance.SE * irradiance_factor;
break;
default: FATAL("Unreachable code.\n"); break;
}
SSOL(instance_get_id(inst, &id));
+ SSOL(instance_get_area(inst, &area));
fprintf(solstice->output,
- "%s %u %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g\n",
- str_cget(name), (unsigned)id,
+ "%s %u %g "
+ "FRONT: %g %g %g %g %g %g %g %g %g %g "
+ "BACK: %g %g %g %g %g %g %g %g %g %g\n",
+ str_cget(name), (unsigned)id, area,
+ front.integrated_absorbed_irradiance.E, front.integrated_absorbed_irradiance.SE,
front.integrated_irradiance.E, front.integrated_irradiance.SE,
- back.integrated_irradiance.E, back.integrated_irradiance.SE,
front.reflectivity_loss.E, front.reflectivity_loss.SE,
- back.reflectivity_loss.E, back.reflectivity_loss.SE,
front.absorptivity_loss.E, front.absorptivity_loss.SE,
+ f_eff_E, f_eff_SE,
+ back.integrated_absorbed_irradiance.E, back.integrated_absorbed_irradiance.SE,
+ back.integrated_irradiance.E, back.integrated_irradiance.SE,
+ back.reflectivity_loss.E, back.reflectivity_loss.SE,
back.absorptivity_loss.E, back.absorptivity_loss.SE,
- front.cos_loss.E, front.cos_loss.SE,
- back.cos_loss.E, back.cos_loss.SE,
- f_eff_E, f_eff_SE, b_eff_E, b_eff_SE);
+ b_eff_E, b_eff_SE);
}
- fprintf(solstice->output, "%g %g\n",
- mc_global.shadowed.E, mc_global.shadowed.SE);
- fprintf(solstice->output, "%g %g\n",
- mc_global.missing.E, mc_global.missing.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;
+ uint32_t id;
+
+ 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, &area));
+ fprintf(solstice->output,
+ "%s %u %g %lu "
+ "%g %g %g %g\n",
+ str_cget(name), (unsigned) id, area, (unsigned long)sampled.nb_samples,
+ sampled.cos_factor.E, sampled.cos_factor.SE,
+ sampled.shadowed.E, sampled.shadowed.SE
+ );
+ }
+
+ /* ReceiverXprimarys' data */
+ htable_receiver_begin(&solstice->receivers, &r_it);
+ htable_receiver_end(&solstice->receivers, &r_end);
+ while (!htable_receiver_iterator_eq(&r_it, &r_end)) {
+ struct solstice_receiver* rcv = htable_receiver_iterator_data_get(&r_it);
+ struct ssol_instance* rcv_inst = rcv->node->instance;
+ uint32_t rcv_id, prim_id;
+
+ SSOL(instance_get_id(rcv_inst, &rcv_id));
+ htable_primary_begin(&solstice->primaries, &p_it);
+ htable_primary_end(&solstice->primaries, &p_end);
+ 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;
+
+ SSOL(instance_get_id(prim_inst, &prim_id));
+ switch (rcv->side) {
+ case SRCVL_FRONT:
+ SSOL(estimator_get_mc_sampled_x_receiver
+ (estimator, prim_inst, rcv_inst, SSOL_FRONT, &front));
+ break;
+ case SRCVL_BACK:
+ SSOL(estimator_get_mc_sampled_x_receiver
+ (estimator, prim_inst, rcv_inst, SSOL_BACK, &back));
+ break;
+ case SRCVL_FRONT_AND_BACK:
+ SSOL(estimator_get_mc_sampled_x_receiver
+ (estimator, prim_inst, rcv_inst, SSOL_FRONT, &front));
+ SSOL(estimator_get_mc_sampled_x_receiver
+ (estimator, prim_inst, rcv_inst, SSOL_BACK, &back));
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ fprintf(solstice->output,
+ "%u %u "
+ "FRONT: %g %g %g %g %g %g %g %g "
+ "BACK: %g %g %g %g %g %g %g %g\n",
+ (unsigned) rcv_id, (unsigned) prim_id,
+ front.integrated_absorbed_irradiance.E, front.integrated_absorbed_irradiance.SE,
+ front.integrated_irradiance.E, front.integrated_irradiance.SE,
+ front.reflectivity_loss.E, front.reflectivity_loss.SE,
+ front.absorptivity_loss.E, front.absorptivity_loss.SE,
+ back.integrated_absorbed_irradiance.E, back.integrated_absorbed_irradiance.SE,
+ back.integrated_irradiance.E, back.integrated_irradiance.SE,
+ back.reflectivity_loss.E, back.reflectivity_loss.SE,
+ back.absorptivity_loss.E, back.absorptivity_loss.SE);
+ htable_primary_iterator_next(&p_it);
+ }
+ htable_receiver_iterator_next(&r_it);
+ }
}
static void
diff --git a/src/test_solstice_simulation.c b/src/test_solstice_simulation.c
@@ -17,6 +17,7 @@
#include <rsys/rsys.h>
#include <rsys/math.h>
+#include <rsys/double2.h>
#include <math.h>
#include <stdio.h>
@@ -37,20 +38,52 @@ enum side {
BACK
};
-enum result_type {
+enum global_result_type {
+ GLOBAL_POTENTIAL,
+ GLOBAL_ABSORBED,
+ GLOBAL_COS,
+ GLOBAL_SHADOW,
+ GLOBAL_MISSING,
+ GLOBAL_ATMOSPHERE,
+ GLOBAL_REFLECTIVITY,
+ GLOBAL_RESULTS_COUNT__
+};
+
+enum receiver_result_type {
+ FIRST_RECEIVER_RESULT,
+ FRONT_INTEGRATED_ABSORBED_IRRADIANCE = FIRST_RECEIVER_RESULT,
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_INTEGRATED_ABSORBED_IRRADIANCE,
+ BACK_INTEGRATED_IRRADIANCE,
+ BACK_REFLECTIVITY_LOSS,
+ BACK_ABSORPTIVITY_LOSS,
BACK_EFFICIENCY,
- MAX_RESULTS_COUNT__
+ RECEIVER_RESULTS_COUNT__
+};
+
+enum primary_result_type {
+ FIRST_PRIMARY_RESULT,
+ PRIMARY_SHADOW = FIRST_PRIMARY_RESULT,
+ PRIMARY_RESULTS_COUNT__
};
+struct counts {
+ unsigned long global, receiver, primary, realisation, failed;
+};
+
+static int
+counts_ok(const struct counts* ref, const struct counts* c)
+{
+ CHECK(ref->global, GLOBAL_RESULTS_COUNT__);
+ CHECK(c->global, GLOBAL_RESULTS_COUNT__);
+ return ref->receiver == c->receiver
+ && ref->primary == c->primary
+ && ref->failed >= c->failed;
+}
+
#define MAX_LINE_LEN 2048
static const char
@@ -170,63 +203,146 @@ read_line(char* line, size_t max_line_len, FILE* stream)
return 1;
}
-static void
-get_dir_and_counts
- (FILE* ref_file,
+static int
+get_angles_and_counts
+ (FILE* file,
double angles[2],
- unsigned long* recv_count,
- unsigned long* realisation_count)
+ struct counts* counts)
{
char line[MAX_LINE_LEN];
- int n;
+ int r;
- NCHECK(ref_file, NULL);
+ NCHECK(file, NULL);
NCHECK(angles, NULL);
- NCHECK(recv_count, NULL);
- NCHECK(realisation_count, NULL);
+ NCHECK(counts, NULL);
/* Get sun dir */
- CHECK(read_line(line, sizeof(line), ref_file), 1);
+ r = read_line(line, sizeof(line), file);
+ if (!r) {
+ CHECK(feof(file), 1);
+ return 0;
+ }
CHECK(IS_NEW_BLOCK(line, sundir_header), 1);
- n = sscanf(line+strlen(sundir_header), "%lg%lg", &angles[0], &angles[1]);
- CHECK(n, 2);
+ CHECK(
+ sscanf(line+strlen(sundir_header), "%lg%lg", &angles[0], &angles[1]),
+ 2);
+
+ /* Get counts */
+ CHECK(read_line(line, sizeof(line), file), 1);
+ CHECK(
+ sscanf(line,
+ "%lu %lu %lu %lu %lu",
+ &counts->global, &counts->receiver, &counts->primary,
+ &counts->realisation, &counts->failed),
+ 5);
+ return 1;
+}
- /* 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_global(FILE* file, double* E, double* SE)
+{
+ char line[MAX_LINE_LEN];
+ CHECK(read_line(line, sizeof(line), file), 1);
+ CHECK(
+ sscanf(line, "%lg %lg", E, SE),
+ 2);
}
static void
-read_recv(const char* line, char name[], double E[], double SE[])
+read_recv(FILE* file, char name[], double E[], double SE[])
{
- int n;
+ char line[MAX_LINE_LEN];
- NCHECK(line, NULL);
+ NCHECK(file, 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);
+ CHECK(read_line(line, sizeof(line), file), 1);
+ CHECK(
+ sscanf(line,
+ "%s %*lu %*lg "
+ "FRONT: %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg "
+ " BACK: %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg",
+ name, /* ID, area */
+ &E[FRONT_INTEGRATED_ABSORBED_IRRADIANCE],
+ &SE[FRONT_INTEGRATED_ABSORBED_IRRADIANCE],
+ &E[FRONT_INTEGRATED_IRRADIANCE], &SE[FRONT_INTEGRATED_IRRADIANCE],
+ &E[FRONT_REFLECTIVITY_LOSS], &SE[FRONT_REFLECTIVITY_LOSS],
+ &E[FRONT_ABSORPTIVITY_LOSS], &SE[FRONT_ABSORPTIVITY_LOSS],
+ &E[FRONT_EFFICIENCY], &SE[FRONT_EFFICIENCY],
+ &E[BACK_INTEGRATED_ABSORBED_IRRADIANCE],
+ &SE[BACK_INTEGRATED_ABSORBED_IRRADIANCE],
+ &E[BACK_INTEGRATED_IRRADIANCE], &SE[BACK_INTEGRATED_IRRADIANCE],
+ &E[BACK_REFLECTIVITY_LOSS], &SE[BACK_REFLECTIVITY_LOSS],
+ &E[BACK_ABSORPTIVITY_LOSS], &SE[BACK_ABSORPTIVITY_LOSS],
+ &E[BACK_EFFICIENCY], &SE[BACK_EFFICIENCY]),
+ 2 * RECEIVER_RESULTS_COUNT__ + 1);
+}
+
+static void
+read_primary
+ (FILE* file, char name[], double* area, double* cos, double E[], double SE[])
+{
+ char line[MAX_LINE_LEN];
+
+ NCHECK(file, NULL);
+ NCHECK(area, NULL);
+ NCHECK(cos, NULL);
+ NCHECK(E, NULL);
+ NCHECK(SE, NULL);
+
+ CHECK(read_line(line, sizeof(line), file), 1);
+ CHECK(
+ sscanf(line,
+ "%s %*lu "
+ "%lg %lg %*lu "
+ "%lg %lg\n",
+ name, /* ID */
+ area, cos, /* count */
+ &E[PRIMARY_SHADOW], &SE[PRIMARY_SHADOW]),
+ 2 * PRIMARY_RESULTS_COUNT__ + 3);
+}
+
+static void
+read_recvXprim
+ (FILE* file,
+ unsigned long* rcv_id,
+ unsigned long* prim_id,
+ double E[],
+ double SE[])
+{
+ char line[MAX_LINE_LEN];
+
+ NCHECK(file, NULL);
+ NCHECK(rcv_id, NULL);
+ NCHECK(prim_id, NULL);
+ NCHECK(E, NULL);
+ NCHECK(SE, NULL);
+
+ CHECK(read_line(line, sizeof(line), file), 1);
+ CHECK(
+ sscanf(line,
+ "%lu %lu "
+ "FRONT: %lg %lg %lg %lg %lg %lg %lg %lg "
+ " BACK: %lg %lg %lg %lg %lg %lg %lg %lg",
+ rcv_id, prim_id,
+ &E[FRONT_INTEGRATED_ABSORBED_IRRADIANCE],
+ &SE[FRONT_INTEGRATED_ABSORBED_IRRADIANCE],
+ &E[FRONT_INTEGRATED_IRRADIANCE], &SE[FRONT_INTEGRATED_IRRADIANCE],
+ &E[FRONT_REFLECTIVITY_LOSS], &SE[FRONT_REFLECTIVITY_LOSS],
+ &E[FRONT_ABSORPTIVITY_LOSS], &SE[FRONT_ABSORPTIVITY_LOSS],
+ &E[BACK_INTEGRATED_ABSORBED_IRRADIANCE],
+ &SE[BACK_INTEGRATED_ABSORBED_IRRADIANCE],
+ &E[BACK_INTEGRATED_IRRADIANCE], &SE[BACK_INTEGRATED_IRRADIANCE],
+ &E[BACK_REFLECTIVITY_LOSS], &SE[BACK_REFLECTIVITY_LOSS],
+ &E[BACK_ABSORPTIVITY_LOSS], &SE[BACK_ABSORPTIVITY_LOSS]),
+ 2 * (RECEIVER_RESULTS_COUNT__ - 2 /* efficiencies not read */) + 2);
}
#define POSITIVE_OR_M_ONE(x) ((x) == -1 || (x) >= 0)
-static FINLINE int
+static int
is_compatible_with
(const double ref_E,
const double ref_SE,
@@ -252,106 +368,80 @@ is_compatible_with
static void
check_1_reference
- (FILE* tested_file,
- const char* rcv_name,
- const double* reference_E,
- const double* reference_SE)
+ (FILE* ref_file,
+ FILE* test_file,
+ const struct counts* counts)
{
- double a[2];
- unsigned long 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 */
+ unsigned n;
- 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);
+ NCHECK(ref_file, NULL);
+ NCHECK(test_file, NULL);
+ NCHECK(counts, NULL);
- read_recv(line, tested_rcv_name, tested_E, tested_SE);
- if(strcmp(rcv_name, tested_rcv_name)) continue;
+ /* both files' pointer are just past the new bloc header */
- FOR_EACH(r, FRONT_INTEGRATED_IRRADIANCE, MAX_RESULTS_COUNT__) {
+ for (n = 0; n < counts->global; n++) {
+ double reference_E, reference_SE, test_E, test_SE;
+ read_global(ref_file, &reference_E, &reference_SE);
+ read_global(test_file, &test_E, &test_SE);
+ CHECK(is_compatible_with(reference_E, reference_SE, test_E, test_SE), 1);
+ }
+ for (n = 0; n < counts->receiver; n++) {
+ char ref_rcv_name[MAX_LINE_LEN], test_rcv_name[MAX_LINE_LEN];
+ double reference_E[RECEIVER_RESULTS_COUNT__];
+ double reference_SE[RECEIVER_RESULTS_COUNT__];
+ double test_E[RECEIVER_RESULTS_COUNT__];
+ double test_SE[RECEIVER_RESULTS_COUNT__];
+ enum receiver_result_type r;
+
+ read_recv(ref_file, ref_rcv_name, reference_E, reference_SE);
+ read_recv(test_file, test_rcv_name, test_E, test_SE);
+ CHECK(strcmp(ref_rcv_name, test_rcv_name), 0);
+ FOR_EACH(r, FIRST_RECEIVER_RESULT, RECEIVER_RESULTS_COUNT__) {
CHECK(is_compatible_with
- (reference_E[r], reference_SE[r], tested_E[r], tested_SE[r]), 1);
+ (reference_E[r], reference_SE[r], test_E[r], test_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];
- unsigned long 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;
+ for (n = 0; n < counts->primary; n++) {
+ char ref_prim_name[MAX_LINE_LEN], test_prim_name[MAX_LINE_LEN];
+ double reference_E[PRIMARY_RESULTS_COUNT__];
+ double reference_SE[PRIMARY_RESULTS_COUNT__];
+ double test_E[PRIMARY_RESULTS_COUNT__];
+ double test_SE[PRIMARY_RESULTS_COUNT__];
+ double ref_area, ref_cos;
+ double test_area, test_cos;
+ enum primary_result_type r;
+
+ read_primary(ref_file, ref_prim_name, &ref_area, &ref_cos, reference_E, reference_SE);
+ read_primary(test_file, test_prim_name, &test_area, &test_cos, test_E, test_SE);
+ CHECK(is_compatible_with(ref_area, 0, test_area, 0), 1);
+ CHECK(is_compatible_with(ref_cos, 0, test_cos, 0), 1);
+ CHECK(strcmp(ref_prim_name, test_prim_name), 0);
+ FOR_EACH(r, FIRST_RECEIVER_RESULT, PRIMARY_RESULTS_COUNT__) {
+ CHECK(is_compatible_with
+ (reference_E[r], reference_SE[r], test_E[r], test_SE[r]), 1);
}
-
- 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);
+ }
+ for (n = 0; n < counts->receiver * counts->primary; n++) {
+ double reference_E[RECEIVER_RESULTS_COUNT__];
+ double reference_SE[RECEIVER_RESULTS_COUNT__];
+ double test_E[RECEIVER_RESULTS_COUNT__];
+ double test_SE[RECEIVER_RESULTS_COUNT__];
+ unsigned long ref_rcv_id, ref_prim_id;
+ unsigned long test_rcv_id, test_prim_id;
+
+ enum receiver_result_type r;
+ read_recvXprim(ref_file, &ref_rcv_id, &ref_prim_id, reference_E, reference_SE);
+ read_recvXprim(test_file, &test_rcv_id, &test_prim_id, test_E, test_SE);
+ /* we rely on the order of outputs */
+ CHECK(ref_rcv_id, test_rcv_id);
+ CHECK(ref_prim_id, test_prim_id);
+ FOR_EACH(r, FIRST_RECEIVER_RESULT, RECEIVER_RESULTS_COUNT__) {
+ if (r == FRONT_EFFICIENCY || r == BACK_EFFICIENCY)
+ continue; /* not read */
+ CHECK(is_compatible_with
+ (reference_E[r], reference_SE[r], test_E[r], test_SE[r]), 1);
}
-
- CHECK(fgetpos(ref_file, &pos), 0);
}
}
@@ -373,7 +463,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;
+ struct counts ref_counts, test_counts;
int n;
int err;
ASSERT(base_name);
@@ -386,30 +476,34 @@ do_check(const char* binary, const char* dir, const char* base_name)
while(!feof(ref_file)) {
char cmd[512];
- char tested_file_name[128];
- double sun_angles[2];
- FILE* fp = NULL;
+ char test_file_name[128];
+ double ref_sun_angles[2], test_sun_angles[2];
+ FILE* test_file = NULL;
int fd = -1;
- get_dir_and_counts(ref_file, sun_angles, &c1, &realisation_count);
+ if (!get_angles_and_counts(ref_file, ref_sun_angles, &ref_counts))
+ break; /* EOF */
- fd = create_tmp_file(tested_file_name, sizeof(tested_file_name));
- fp = fdopen(fd, "r");
- NCHECK(fp, NULL);
+ fd = create_tmp_file(test_file_name, sizeof(test_file_name));
+ test_file = fdopen(fd, "r");
+ NCHECK(test_file, 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,
+ binary, test_file_name, SPLIT2(ref_sun_angles), ref_counts.realisation,
dir, base_name, dir, base_name);
CHECK((unsigned)n < sizeof(cmd), 1);
err = system(cmd);
CHECK(err, 0);
- check_references(ref_file, fp);
+ get_angles_and_counts(test_file, test_sun_angles, &test_counts);
+ CHECK(d2_eq(ref_sun_angles, test_sun_angles), 1);
+ CHECK(counts_ok(&ref_counts, &test_counts), 1);
+ check_1_reference(ref_file, test_file, &ref_counts);
- fclose(fp);
- remove(tested_file_name);
+ fclose(test_file);
+ remove(test_file_name);
}
}
diff --git a/yaml/beam_down.ref b/yaml/beam_down.ref
@@ -1,12 +1,52 @@
#--- Sun direction: 90 90 (-3.7494e-33 -6.12323e-17 -1)
-2 10000
-tower.secondary.hyperbol 10 465.484 0.0183212 0 0 0 0 0 0 0 0 0 0 34.5362 0.00509812 0 0 0.930888 3.66392e-05 0 0
-tower.receptor 14 465.484 0.0183212 -1 -1 0 0 -1 -1 0 0 -1 -1 34.5362 0.00509812 -1 -1 0.930888 3.66392e-05 -1 -1
+7 2 5 10000 0
+500.043 0 # Potential
+465.484 0.0183212
+0.930883 3.66351e-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
#--- Sun direction: 50 50 (-0.413176 -0.492404 -0.766044)
-2 10000
-tower.secondary.hyperbol 10 400.227 0.111144 0 0 0 0 0 0 0 0 0 0 99.7686 0.107226 0 0 0.800384 0.000222269 0 0
-tower.receptor 14 136.561 1.90791 -1 -1 0 0 -1 -1 0 0 -1 -1 32.9896 0.464742 -1 -1 0.273098 0.0038155 -1 -1
+7 2 5 10000 0
+500.043 0
+136.561 1.90791
+0.80038 0.000222269
+0 0
+244.012 1.94769
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
diff --git a/yaml/test01.ref b/yaml/test01.ref
@@ -1,5 +1,12 @@
#--- 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
+7 1 1 10000 0
+1 0
0 0
+1 0
0 0
+1 0
+0 0
+0 0
+square_receiver 2 100 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 1 0 0 0 0 0 0 0
+reflector 6 1 10000 0 0 0 0
+2 6 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 1 0 0 0 0 0
diff --git a/yaml/test02.ref b/yaml/test02.ref
@@ -1,5 +1,12 @@
#--- 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
+7 1 1 10000 0
+100 0
+0.96 0.0975082
+1 0
0 0
-99 0.0313065
+99.04 0.0975082
+0 0
+0 0
+square_receiver 2 1 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0.96 0.0975082 0.96 0.0975082 0 0 0 0 0.0096 0.000975082
+reflector 6 100 10000 0 0 0 0
+2 6 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0.96 0.0975082 0.96 0.0975082 0 0 0 0
diff --git a/yaml/test02.yaml b/yaml/test02.yaml
@@ -7,7 +7,9 @@
- geometry: &small_square
- - material: { virtual: }
+ - material:
+ front: { virtual: }
+ back: { matte: { reflectivity: 0 } }
plane:
clip:
- operation: AND
diff --git a/yaml/test03.ref b/yaml/test03.ref
@@ -1,5 +1,12 @@
#--- 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
+7 1 1 10000 0
+1 0
0 0
+0.707107 0
0 0
+0.707107 0
+0 0
+0 0
+square_receiver 2 100 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 0.707107 0 0 0 0 0 0 0
+reflector 6 1 10000 0 0 0 0
+2 6 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 0.707107 0 0 0 0 0
diff --git a/yaml/test04.ref b/yaml/test04.ref
@@ -1,4 +1,12 @@
#--- 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
+7 1 1 10000 0
+1 0
0 0
+0.707107 0
+0 0
+0.707107 0
+0 0
+0 0
+square_receiver 2 100 FRONT: 0 0 0 0 0 0 0 0 0 0 BACK: 0 0 0.707107 0 0 0 0 0 0 0
+reflector 6 1 10000 0 0 0 0
+2 6 FRONT: 0 0 0 0 0 0 0 0 BACK: 0 0 0.707107 0 0 0 0 0
diff --git a/yaml/test05.ref b/yaml/test05.ref
@@ -1,5 +1,12 @@
#--- 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
+7 1 1 10000 0
+1 0
0 0
+1 0
0 0
+1 0
+0 0
+0 0
+spherical_receiver 2 50.2403 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 1 0 0 0 0 0 0 0
+reflector 6 1 10000 0 0 0 0
+2 6 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 1 0 0 0 0 0
diff --git a/yaml/test06.ref b/yaml/test06.ref
@@ -0,0 +1,12 @@
+#--- Sun direction: 0 63 (-0.45399 -0 -0.891007)
+7 1 1 10000 0
+111.97 0
+0 0
+0.896295 0.000571234
+0 0
+100 0
+0 0
+0 0
+reflector.ground.pivot.small_square 10 1 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 100 0 0 0 0 0 0 0
+reflector.ground.pivot.parabol 6 111.97 10000 0 0 0 0
+10 6 FRONT: -1 -1 -1 -1 -1 -1 -1 -1 BACK: 0 0 100 0 0 0 0 0
diff --git a/yaml/test06.yaml b/yaml/test06.yaml
@@ -0,0 +1,62 @@
+- sun: &sun
+ dni: 1
+ spectrum: [{wavelength: 1, data: 1}]
+
+- material: &lambertian
+ front:
+ matte: { reflectivity: 1 }
+ back:
+ matte: { reflectivity: 1 }
+
+- material: &specular
+ mirror: { reflectivity: 1, roughness: 0 }
+
+
+- template: &self_oriented_parabol
+ name: "ground"
+ primary: 0
+ geometry:
+ - material: *lambertian
+ plane:
+ clip:
+ - operation: AND
+ vertices:
+ - [-20.0, -20.0]
+ - [-20.0, 20.0]
+ - [ 20.0, 20.0]
+ - [ 20.0, -20.0]
+ children:
+ - name: "pivot"
+ transform: { translation: [0, 0, 4], rotation: [0, 0, 90] }
+ x_pivot:
+ target: { sun: *sun }
+ children:
+ - name: "parabol"
+ primary: 1
+ geometry:
+ - material: *specular
+ parabol:
+ focal: 4
+ clip:
+ - operation: AND
+ vertices: [[-5.0, -5.0], [-5.0, 5.0], [5.0, 5.0], [5.0, -5.0]]
+ - name: "small_square"
+ transform: { translation: [0, 0, 4] }
+ primary: 0
+ geometry:
+ - material: { virtual: }
+ plane:
+ clip:
+ - operation: AND
+ vertices:
+ - [-0.50, -0.50]
+ - [-0.50, 0.50]
+ - [0.50, 0.50]
+ - [0.50, -0.50]
+
+
+- entity:
+ name: "reflector"
+ transform: { rotation: [0, 0, 0], translation: [0, 0, 0] }
+ children: [ *self_oriented_parabol ]
+
diff --git a/yaml/test06_receiver.yaml b/yaml/test06_receiver.yaml
@@ -0,0 +1 @@
+- { name: "reflector.ground.pivot.small_square", side: BACK }