commit 508c45e648bf36f2a5b53ea847bad60afe2c07b5
parent 871b1717f95ed2248a0d0ec0d0792e97c6d94942
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Sat, 14 Oct 2023 13:54:36 +0200
Add the sck_validate function
It checks the validity of the loaded radiative coefficients. This check
is not mandatory, in order to speed up the loading step and avoid
loading these data when using memory mapping. However, it is always a
good idea to allow the caller to check that his input data is valid.
Diffstat:
3 files changed, 80 insertions(+), 23 deletions(-)
diff --git a/src/sck.c b/src/sck.c
@@ -729,6 +729,71 @@ sck_load_stream(struct sck* sck, const struct sck_load_stream_args* args)
return load_stream(sck, args);
}
+res_T
+sck_validate(const struct sck* sck)
+{
+ size_t iband;
+ if(!sck) return RES_BAD_ARG;
+
+ FOR_EACH(iband, 0, sck_get_bands_count(sck)) {
+ struct sck_band band = SCK_BAND_NULL;
+ size_t inode;
+ size_t iquad_pt;
+
+ SCK(get_band(sck, iband, &band));
+
+ /* Check band limits */
+ if(band.lower != band.lower /* NaN? */
+ || band.upper != band.upper) { /* NaN? */
+ log_err(sck, "%s: invalid limits for band %lu: [%g, %g[\n",
+ sck_get_name(sck), (unsigned long)iband, band.lower, band.upper);
+ return RES_BAD_ARG;
+ }
+
+ /* Check scattering coefficients */
+ FOR_EACH(inode, 0, sck_get_nodes_count(sck)) {
+ if(band.ks_list[inode] != band.ks_list[inode] /* NaN? */
+ || band.ks_list[inode] < 0) {
+ log_err(sck,
+ "%s: invalid scattering coefficient for band %lu at node %lu: %g\n",
+ sck_get_name(sck), (unsigned long)iband, (unsigned long) inode,
+ band.ks_list[inode]);
+ return RES_BAD_ARG;
+ }
+ }
+
+ FOR_EACH(iquad_pt, 0, band.quad_pts_count) {
+ struct sck_quad_pt quad_pt = SCK_QUAD_PT_NULL;
+
+ SCK(band_get_quad_pt(&band, iquad_pt, &quad_pt));
+
+ /* Check quadrature point weight */
+ if(quad_pt.weight != quad_pt.weight /* NaN? */
+ || quad_pt.weight <= 0) {
+ log_err(sck,
+ "%s: invalid weight for quadrature point %lu of band %lu: %g\n",
+ sck_get_name(sck), (unsigned long)iquad_pt, (unsigned long)iband,
+ quad_pt.weight);
+ return RES_BAD_ARG;
+ }
+
+ /* Check absorption coefficient */
+ FOR_EACH(inode, 0, sck_get_nodes_count(sck)) {
+ if(quad_pt.ka_list[inode] != quad_pt.ka_list[inode] /* NaN? */
+ || quad_pt.ka_list[inode] < 0) {
+ log_err(sck,
+ "%s: invalid absorption coefficient for quadrature point %lu "
+ "of band %lu at node %lu: %g\n",
+ sck_get_name(sck), (unsigned long)iquad_pt, (unsigned long)iband,
+ (unsigned long)inode, quad_pt.ka_list[inode]);
+ return RES_BAD_ARG;
+ }
+ }
+ }
+ }
+ return RES_OK;
+}
+
size_t
sck_get_bands_count(const struct sck* sck)
{
diff --git a/src/sck.h b/src/sck.h
@@ -123,6 +123,17 @@ sck_load_stream
(struct sck* sck,
const struct sck_load_stream_args* args);
+/* Validates radiative coefficients. Data checks have already been carried out
+ * during loading, notably on spectral bands and quadrature points, but this
+ * function performs longer and more thorough tests. It reviews all scattering
+ * and absorption coefficients to check their validity, i.e. whether they are
+ * positive or zero. Note that checking radiative coefficients is not mandatory,
+ * in order to speed up the loading step and avoid loading/unloading them when
+ * using memory mapping. */
+SCK_API res_T
+sck_validate
+ (const struct sck* sck);
+
SCK_API size_t
sck_get_bands_count
(const struct sck* sck);
diff --git a/src/test_sck_load.c b/src/test_sck_load.c
@@ -52,6 +52,9 @@ check_sck_load
CHK(nbands);
CHK(nnodes);
+ CHK(sck_validate(NULL) == RES_BAD_ARG);
+ CHK(sck_validate(sck) == RES_OK);
+
CHK(sck_get_bands_count(sck) == nbands);
CHK(sck_get_nodes_count(sck) == nnodes);
@@ -414,37 +417,15 @@ test_load_files(struct sck* sck, int argc, char** argv)
FOR_EACH(iband, 0, nbands) {
struct sck_band band = SCK_BAND_NULL;
- size_t inode;
- size_t iqpt;
CHK(sck_get_band(sck, iband, &band) == RES_OK);
printf("band %lu in [%g, %g[ nm with %lu quadrature points\n",
(unsigned long)band.id,
band.lower, band.upper,
(unsigned long)band.quad_pts_count);
-
- CHK(band.lower == band.lower); /* !NaN */
- CHK(band.upper == band.upper); /* !NaN */
- CHK(band.lower < band.upper);
- CHK(band.quad_pts_count);
-
- FOR_EACH(inode, 0, nnodes) {
- CHK(band.ks_list[inode] == band.ks_list[inode]); /* !NaN */
- }
-
- FOR_EACH(iqpt, 0, band.quad_pts_count) {
- struct sck_quad_pt qpt;
-
- CHK(sck_band_get_quad_pt(&band, iqpt, &qpt) == RES_OK);
- CHK(qpt.weight == qpt.weight); /* !NaN */
- CHK(qpt.weight > 0);
-
- FOR_EACH(inode, 0, nnodes) {
- CHK(qpt.ka_list[inode] == qpt.ka_list[inode]); /* !NaN */
- }
- }
}
+ CHK(sck_validate(sck) == RES_OK);
CHK(sck_compute_hash(sck, hash) == RES_OK);
}
}