commit fcee059601c6901d5f4592ae3da3e20b9c18df79
parent 3face32bdf729929c34ac339cd62393cdba13ce8
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 13 Feb 2017 17:52:48 +0100
Cos loss computation (per receiver).
Diffstat:
5 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -258,6 +258,7 @@ struct ssol_estimator_status {
struct ssol_mc_result irradiance;
struct ssol_mc_result absorptivity_loss;
struct ssol_mc_result reflectivity_loss;
+ struct ssol_mc_result cos_loss;
size_t N; /* Samples count */
size_t Nf; /* Failed samples count */
};
diff --git a/src/ssol_estimator.c b/src/ssol_estimator.c
@@ -123,6 +123,9 @@ ssol_estimator_get_status
status->reflectivity_loss.E = 0;
status->reflectivity_loss.V = 0;
status->reflectivity_loss.SE = 0;
+ status->cos_loss.E = 0;
+ status->cos_loss.V = 0;
+ status->cos_loss.SE = 0;
return RES_OK;
}
@@ -166,6 +169,13 @@ ssol_estimator_get_receiver_status
status->reflectivity_loss.SE
= (status->reflectivity_loss.V > 0) ?
sqrt(status->reflectivity_loss.V / (double) status->N) : 0;
+ status->cos_loss.E = data->cos_loss.weight / (double) status->N;
+ status->cos_loss.V
+ = data->cos_loss.sqr_weight / (double) status->N
+ - status->cos_loss.E * status->cos_loss.E;
+ status->cos_loss.SE
+ = (status->cos_loss.V > 0) ?
+ sqrt(status->cos_loss.V / (double) status->N) : 0;
return RES_OK;
}
diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h
@@ -41,9 +41,11 @@ struct mc_per_receiver_1side_data {
struct mc_data irradiance;
struct mc_data absorptivity_loss;
struct mc_data reflectivity_loss;
+ struct mc_data cos_loss;
};
-#define MC_RECV_1SIDE_DATA_NULL__ { MC_DATA_NULL__, MC_DATA_NULL__, MC_DATA_NULL__ }
+#define MC_RECV_1SIDE_DATA_NULL__ {\
+ MC_DATA_NULL__, MC_DATA_NULL__, MC_DATA_NULL__, MC_DATA_NULL__ }
static const struct mc_per_receiver_1side_data
MC_RECV_1SIDE_DATA_NULL = MC_RECV_1SIDE_DATA_NULL__;
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -54,8 +54,9 @@ struct point {
float uv[2];
double wl; /* Sampled wavelength */
double weight; /* actual weight */
- double absorptivity_loss; /* weight with no amospheric effets */
- double reflectivity_loss; /* weight with no reflectivity effets */
+ double absorptivity_loss;
+ double reflectivity_loss;
+ double cos_loss;
enum ssol_side_flag side;
};
@@ -92,6 +93,7 @@ point_init
struct s3d_hit hit;
struct ray_data ray_data = RAY_DATA_NULL;
float dir[3], pos[3], range[2] = { 0, FLT_MAX };
+ double cos_sun;
size_t id;
/* Sample a point into the scene view */
@@ -115,7 +117,9 @@ point_init
ranst_sun_dir_get(ran_sun_dir, rng, pt->dir);
/* Initialise the Monte Carlo weight */
- pt->weight = scn->sun->dni * sampled_area * fabs(d3_dot(pt->N, pt->dir));
+ cos_sun = fabs(d3_dot(pt->N, pt->dir));
+ pt->weight = scn->sun->dni * sampled_area * cos_sun;
+ pt->cos_loss = scn->sun->dni * sampled_area * (1 - cos_sun);
pt->absorptivity_loss = pt->reflectivity_loss = 0;
/* Retrieve the sampled instance and shaded shape */
@@ -485,6 +489,8 @@ ssol_solve
data->absorptivity_loss.sqr_weight += pt.absorptivity_loss * pt.absorptivity_loss;
data->reflectivity_loss.weight += pt.reflectivity_loss;
data->reflectivity_loss.sqr_weight += pt.reflectivity_loss * pt.reflectivity_loss;
+ data->cos_loss.weight += pt.cos_loss;
+ data->cos_loss.sqr_weight += pt.cos_loss * pt.cos_loss;
hit_a_receiver = 1;
}
@@ -572,6 +578,7 @@ ssol_solve
ACCUM_WEIGHT(irradiance);
ACCUM_WEIGHT(absorptivity_loss);
ACCUM_WEIGHT(reflectivity_loss);
+ ACCUM_WEIGHT(cos_loss);
#undef ACCUM_WEIGHT
}
}
diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c
@@ -261,7 +261,8 @@ main(int argc, char** argv)
CHECK(fcount, 0);
logger_print(&logger, LOG_OUTPUT, "\nIr = %g +/- %g", m, std);
#define COS cos(PI / 4)
-#define DNI_cos (1000 * COS)
+#define DNI 1000
+#define DNI_cos (DNI * COS)
CHECK(eq_eps(m, 4 * DNI_cos, MMAX(4 * DNI_cos * 1e-2, 2*std)), 1);
#define SQR(x) ((x)*(x))
dbl = sqrt((SQR(12 * DNI_cos) / 3 - SQR(4 * DNI_cos)) / (double)count);
@@ -397,7 +398,8 @@ main(int argc, char** argv)
CHECK(fclose(tmp), 0);
logger_print(&logger, LOG_OUTPUT, "\nIr = %g +/- %g", a_m, a_std);
#define K (exp(-KA * 4 * sqrt(2)))
- CHECK(eq_eps(a_m, REFLECTIVITY * 4 * K * DNI_cos, MMAX(4 * K * DNI_cos * 1e-1, a_std)), 1);
+ CHECK(eq_eps(a_m, REFLECTIVITY * 4 * K * DNI_cos,
+ MMAX(4 * K * DNI_cos * 1e-1, a_std)), 1);
CHECK(eq_eps(a_std, 0, 1e-4), 1);
CHECK(GET_STATUS(estimator, SSOL_STATUS_SHADOW, &status), RES_OK);
logger_print(&logger, LOG_OUTPUT, "Shadows = %g +/- %g",
@@ -408,15 +410,27 @@ main(int argc, char** argv)
status.irradiance.E, status.irradiance.SE);
CHECK(eq_eps(status.irradiance.E, 0, 1e-4), 1);
CHECK(GET_RCV_STATUS(estimator, target, SSOL_FRONT, &status), RES_OK);
- logger_print(&logger, LOG_OUTPUT, "Ir(target) = %g +/- %g (%.2g %%)",
+ logger_print(&logger, LOG_OUTPUT,
+ "Ir(target) = %g +/- %g (%.2g %%)",
status.irradiance.E, status.irradiance.SE, 100 * status.irradiance.E / m);
- logger_print(&logger, LOG_OUTPUT, "Atmospheric Loss(target) = %g +/- %g (%.2g %%)",
- status.absorptivity_loss.E, status.absorptivity_loss.SE, 100 * status.absorptivity_loss.E / m);
- logger_print(&logger, LOG_OUTPUT, "Reflectivity Loss(target) = %g +/- %g (%.2g %%)",
- status.reflectivity_loss.E, status.reflectivity_loss.SE, 100 * status.reflectivity_loss.E / m);
+ logger_print(&logger, LOG_OUTPUT,
+ "Atmospheric Loss(target) = %g +/- %g (%.2g %%)",
+ status.absorptivity_loss.E, status.absorptivity_loss.SE,
+ 100 * status.absorptivity_loss.E / m);
+ logger_print(&logger, LOG_OUTPUT,
+ "Reflectivity Loss(target) = %g +/- %g (%.2g %%)",
+ status.reflectivity_loss.E, status.reflectivity_loss.SE,
+ 100 * status.reflectivity_loss.E / m);
+ logger_print(&logger, LOG_OUTPUT,
+ "Cos Loss(target) = %g +/- %g (%.2g %%)",
+ status.cos_loss.E, status.cos_loss.SE, 100 * status.cos_loss.E / m);
CHECK(eq_eps(status.irradiance.E, a_m, 1e-8), 1);
CHECK(eq_eps(status.irradiance.SE, a_std, 1e-4), 1);
- CHECK(eq_eps(status.irradiance.E + status.absorptivity_loss.E + status.reflectivity_loss.E, m, 1e-8), 1);
+ CHECK(eq_eps(status.irradiance.E + status.absorptivity_loss.E
+ + status.reflectivity_loss.E, m, 1e-8), 1);
+ CHECK(eq_eps(status.irradiance.E + status.absorptivity_loss.E
+ + status.reflectivity_loss.E + status.cos_loss.E, 4 * DNI, 1e-8), 1);
+ CHECK(eq_eps(status.cos_loss.E / (4 * DNI), 1 - COS, 1e-8), 1);
CHECK(ssol_estimator_ref_put(estimator), RES_OK);
CHECK(ssol_scene_detach_instance(scene, heliostat2), RES_OK);