commit 2710584f654ce24d54813712e2f318afe9bd933b
parent 4f90c2c5fb4a354b26e69a728fedc631dab99468
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 10 Oct 2016 10:31:21 +0200
Refactor the spectrum code and update its local API
Internal spectrum functions assert if the submitted arguments are not
valid.
Ensure that the dynamic_array internal data are accessed through the
dynamic_array API.
Diffstat:
5 files changed, 97 insertions(+), 109 deletions(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -556,7 +556,7 @@ ssol_sun_set_buie_param
/*******************************************************************************
* Atmosphere API - Describe an atmosphere model.
******************************************************************************/
-/* The atmosphere describes absorbtion along the light paths */
+/* The atmosphere describes absorption along the light paths */
SSOL_API res_T
ssol_atmosphere_create_uniform
(struct ssol_device* dev,
diff --git a/src/ssol_atmosphere.c b/src/ssol_atmosphere.c
@@ -62,7 +62,7 @@ compute_atmosphere_attenuation
switch (atmosphere->type) {
case ATMOS_UNIFORM:
spectrum = atmosphere->data.uniform.spectrum;
- CHECK(spectrum_interpolate(spectrum, wavelength, &ka), RES_OK);
+ ka = spectrum_interpolate(spectrum, wavelength);
break;
default: FATAL("Unreachable code\n"); break;
}
@@ -139,4 +139,4 @@ ssol_atmosphere_set_uniform_absorbtion
SSOL(spectrum_ref_get(spectrum));
uni->spectrum = spectrum;
return RES_OK;
-}
-\ No newline at end of file
+}
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -70,39 +70,33 @@ cmp_candidates(const void* _c1, const void* _c2)
}
static FINLINE res_T
-check_scene(const struct ssol_scene* scene) {
- ASSERT(scene);
+check_scene(const struct ssol_scene* scene, const char* caller)
+{
+ ASSERT(scene && caller);
+
if (!scene->sun) {
- log_error(scene->dev, "%s: no sun attached.\n", FUNC_NAME);
+ log_error(scene->dev, "%s: no sun attached.\n", caller);
return RES_BAD_ARG;
}
if (!scene->sun->spectrum) {
- log_error(scene->dev, "%s: sun's spectrum undefined.\n", FUNC_NAME);
+ log_error(scene->dev, "%s: sun's spectrum undefined.\n", caller);
return RES_BAD_ARG;
}
if (scene->sun->dni <= 0) {
- log_error(scene->dev, "%s: sun's DNI undefined.\n", FUNC_NAME);
+ log_error(scene->dev, "%s: sun's DNI undefined.\n", caller);
return RES_BAD_ARG;
}
if (scene->atmosphere) {
- switch (scene->atmosphere->type) {
- case ATMOS_UNIFORM: {
- char ok;
- CHECK(spectrum_includes(
- scene->atmosphere->data.uniform.spectrum,
- scene->sun->spectrum,
- &ok),
- RES_OK);
- if (!ok) {
- log_error(scene->dev, "%s: sun/atmosphere spectra mismatch.\n", FUNC_NAME);
- return RES_BAD_ARG;
- }
- break;
- }
- default: FATAL("Unreachable code\n"); break;
+ int i;
+ ASSERT(scene->atmosphere->type == ATMOS_UNIFORM);
+ i = spectrum_includes
+ (scene->atmosphere->data.uniform.spectrum, scene->sun->spectrum);
+ if (!i) {
+ log_error(scene->dev, "%s: sun/atmosphere spectra mismatch.\n", caller);
+ return RES_BAD_ARG;
}
}
return RES_OK;
@@ -492,7 +486,7 @@ sample_starting_point(struct realisation* rs)
id = *htable_shaded_shape_find
(&start->instance->object->shaded_shapes_samp, &sampl_prim.geom_id);
start->shaded_shape = darray_shaded_shape_cdata_get
- (&start->instance->object->shaded_shapes)+id;
+ (&start->instance->object->shaded_shapes)+id;
shape = start->shaded_shape->shape;
start->on_punched = (shape->type == SHAPE_PUNCHED);
/* set sampling normal */
@@ -790,7 +784,7 @@ ssol_solve
if (!scene || !rng || !output || !realisations_count)
return RES_BAD_ARG;
- res = check_scene(scene);
+ res = check_scene(scene, FUNC_NAME);
if (res != RES_OK) return res;
/* init realisation */
diff --git a/src/ssol_spectrum.c b/src/ssol_spectrum.c
@@ -40,105 +40,96 @@ spectrum_release(ref_T* ref)
SSOL(device_ref_put(dev));
}
-static char
+static int
spectrum_includes_point
(const struct ssol_spectrum* spectrum,
- const double wavelenght)
+ const double wavelength)
{
const double* data;
size_t sz;
- ASSERT(spectrum && spectrum->wavelengths.data && spectrum->intensities.data);
- sz = spectrum->wavelengths.size;
- ASSERT(sz && sz == spectrum->intensities.size);
- data = spectrum->wavelengths.data;
- return data[0] <= wavelenght && wavelenght <= data[sz - 1];
+ ASSERT(spectrum);
+ sz = darray_double_size_get(&spectrum->wavelengths);
+ ASSERT(sz && sz == darray_double_size_get(&spectrum->intensities));
+ data = darray_double_cdata_get(&spectrum->wavelengths);
+ return data[0] <= wavelength && wavelength <= data[sz - 1];
}
static int
-eq_d(const void* key, const void* base)
+eq_dbl(const void* key, const void* base)
{
- double k = *(double*) key;
- double b = *(double*) base;
- if (k > b) return +1;
- if (k < b) return -1;
+ const double k = *(const double*) key;
+ const double b = *(const double*) base;
+ if(k > b) return +1;
+ if(k < b) return -1;
return 0;
}
/*******************************************************************************
-* Local ssol_spectrum functions
-******************************************************************************/
-res_T
+ * Local ssol_spectrum functions
+ ******************************************************************************/
+int
spectrum_includes
(const struct ssol_spectrum* reference,
- const struct ssol_spectrum* tested,
- char* include)
+ const struct ssol_spectrum* tested)
{
const double* test_data;
size_t test_sz;
- if(!reference || !tested || !include) {
- return RES_BAD_ARG;
- }
-
- test_sz = tested->wavelengths.size;
- test_data = tested->wavelengths.data;
- *include = spectrum_includes_point(reference, test_data[0])
- && spectrum_includes_point(reference, test_data[test_sz - 1]);
+ ASSERT(reference && tested);
- return RES_OK;
+ test_sz = darray_double_size_get(&tested->wavelengths);
+ test_data = darray_double_cdata_get(&tested->wavelengths);
+ return spectrum_includes_point(reference, test_data[0])
+ && spectrum_includes_point(reference, test_data[test_sz - 1]);
}
-res_T
+double
spectrum_interpolate
(const struct ssol_spectrum* spectrum,
- const double wavelenght,
- double* intensity)
+ const double wavelength)
{
- double* next;
- double* wavelengths;
- double* ints;
+ const double* wls;
+ const double* ints;
+ const double* next;
double slope;
- size_t idx_next, sz;
- if (!spectrum
- || !intensity
- || !spectrum_includes_point(spectrum, wavelenght))
- {
- return RES_BAD_ARG;
- }
-
- sz = spectrum->wavelengths.size;
- wavelengths = spectrum->wavelengths.data;
- ints = spectrum->intensities.data;
- next = search_lower_bound(&wavelenght, wavelengths, sz, sizeof(double), &eq_d);
- ASSERT(next); /* cause spectrum_includes_point */
- idx_next = (size_t)(next - wavelengths);
- ASSERT(idx_next); /* cause spectrum_includes_point */
- ASSERT(ints[idx_next] >= ints[idx_next - 1]);
- ASSERT(wavelengths[idx_next] >= wavelengths[idx_next - 1]);
-
- slope = (ints[idx_next] - ints[idx_next - 1])
- / (wavelengths[idx_next] - wavelengths[idx_next - 1]);
- *intensity = ints[idx_next - 1]
- + (wavelenght - wavelengths[idx_next - 1]) * slope;
- ASSERT(*intensity >= 0);
- return RES_OK;
+ double intensity;
+ size_t id_next, sz;
+ ASSERT(spectrum && spectrum_includes_point(spectrum, wavelength));
+
+ sz = darray_double_size_get(&spectrum->wavelengths);
+ wls = darray_double_cdata_get(&spectrum->wavelengths);
+ ints = darray_double_cdata_get(&spectrum->intensities);
+ next = search_lower_bound(&wavelength, wls, sz, sizeof(double), &eq_dbl);
+ ASSERT(next); /* because spectrum_includes_point */
+
+ id_next = (size_t)(next - wls);
+ ASSERT(id_next); /* because spectrum_includes_point */
+ ASSERT(ints[id_next] >= ints[id_next - 1]);
+ ASSERT(wls[id_next] >= wls[id_next - 1]);
+
+ slope = (ints[id_next] - ints[id_next-1]) / (wls[id_next] - wls[id_next-1]);
+ intensity = ints[id_next-1] + (wavelength - wls[id_next - 1]) * slope;
+ ASSERT(intensity >= 0);
+ return intensity;
}
/*******************************************************************************
-* Exported ssol_spectrum functions
-******************************************************************************/
+ * Exported ssol_spectrum functions
+ ******************************************************************************/
res_T
ssol_spectrum_create
(struct ssol_device* dev, struct ssol_spectrum** out_spectrum)
{
struct ssol_spectrum* spectrum = NULL;
res_T res = RES_OK;
- if (!dev || !out_spectrum) {
- return RES_BAD_ARG;
+
+ if(!dev || !out_spectrum) {
+ res = RES_BAD_ARG;
+ goto error;
}
spectrum = (struct ssol_spectrum*)MEM_CALLOC
(dev->allocator, 1, sizeof(struct ssol_spectrum));
- if (!spectrum) {
+ if(!spectrum) {
res = RES_MEM_ERR;
goto error;
}
@@ -150,10 +141,10 @@ ssol_spectrum_create
darray_double_init(dev->allocator, &spectrum->intensities);
exit:
- if (out_spectrum) *out_spectrum = spectrum;
+ if(out_spectrum) *out_spectrum = spectrum;
return res;
error:
- if (spectrum) {
+ if(spectrum) {
SSOL(spectrum_ref_put(spectrum));
spectrum = NULL;
}
@@ -163,8 +154,7 @@ error:
res_T
ssol_spectrum_ref_get(struct ssol_spectrum* spectrum)
{
- if (!spectrum)
- return RES_BAD_ARG;
+ if(!spectrum) return RES_BAD_ARG;
ref_get(&spectrum->ref);
return RES_OK;
}
@@ -172,8 +162,7 @@ ssol_spectrum_ref_get(struct ssol_spectrum* spectrum)
res_T
ssol_spectrum_ref_put(struct ssol_spectrum* spectrum)
{
- if (!spectrum)
- return RES_BAD_ARG;
+ if(!spectrum) return RES_BAD_ARG;
ref_put(&spectrum->ref, spectrum_release);
return RES_OK;
}
@@ -187,25 +176,29 @@ ssol_spectrum_setup
{
res_T res = RES_OK;
size_t i;
- if(!spectrum
- || nwavelength <= 0
- || !wavelengths
- || !data)
- return RES_BAD_ARG;
+ if(!spectrum || !nwavelength || !wavelengths || !data) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
res = darray_double_resize(&spectrum->wavelengths, nwavelength);
- if (res != RES_OK) return res;
+ if(res != RES_OK) goto error;
res = darray_double_resize(&spectrum->intensities, nwavelength);
- if (res != RES_OK) {
- darray_double_clear(&spectrum->wavelengths);
- return res;
- }
+ if(res != RES_OK) goto error;
FOR_EACH(i, 0, nwavelength) {
spectrum->wavelengths.data[i] = wavelengths[i];
spectrum->intensities.data[i] = data[i];
}
+exit:
return res;
+error:
+ if(spectrum) {
+ darray_double_clear(&spectrum->wavelengths);
+ darray_double_clear(&spectrum->intensities);
+ }
+ goto exit;
}
+
diff --git a/src/ssol_spectrum_c.h b/src/ssol_spectrum_c.h
@@ -22,20 +22,22 @@
struct ssol_spectrum {
struct darray_double wavelengths;
struct darray_double intensities;
+
struct ssol_device* dev;
ref_T ref;
};
-extern LOCAL_SYM res_T
+/* Check that the `tested' spectrum is included into `reference' */
+extern LOCAL_SYM int
spectrum_includes
(const struct ssol_spectrum* reference,
- const struct ssol_spectrum* tested,
- char* include);
+ const struct ssol_spectrum* tested);
-extern LOCAL_SYM res_T
+/* Retrieve the linearly interpolated spectrum intensity for the commited
+ * wavelength */
+extern LOCAL_SYM double
spectrum_interpolate
(const struct ssol_spectrum* spectrum,
- const double wavelenght,
- double* intensity);
+ const double wavelength);
#endif /* SSOL_SPECTRUM_C_H */