solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

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:
Msrc/ssol.h | 2+-
Msrc/ssol_atmosphere.c | 5++---
Msrc/ssol_solver.c | 38++++++++++++++++----------------------
Msrc/ssol_spectrum.c | 147++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/ssol_spectrum_c.h | 14++++++++------
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 */