commit 328431caec15f89af6f667eb9a430926982d8765
parent 327bd21a0ed14ae6dfc44f4cd87b395624dfff07
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 11 May 2023 14:32:17 +0200
atmosphere/planeto: upd of the planck/CIE cumulative building
To speed up the sampling of the spectral dimension, we divide the Planck
function and the CIE tristimuli into small bands of fixed size, about 1
nanometre in length. We also require that the spectral bands of the
underlying semi-transparent material include at least one of these
sampling bands. This latter constraint becomes problematic, however,
when the integration domain begins or ends near the end or beginning of
a spectral band: the spectral bands truncated at the integration domain
can be very thin, resulting in a prohibitive total number of sample
bands.
We are unable to find the justification for the requirement to have at
least one sample band in a spectral band. Indeed, the two are distinct
since the sample bands are used to sample a wavelength which is then,
and only then, used to recover the spectral band of the semi-transparent
material in which it is located, before finally sampling a quadrature
point in that spectral band. In this commit, we therefore remove this
constraint to avoid having too many sample bands, which could saturate
the memory space and cause an allocation error.
Diffstat:
2 files changed, 2 insertions(+), 95 deletions(-)
diff --git a/src/atmosphere/htrdr_atmosphere.c b/src/atmosphere/htrdr_atmosphere.c
@@ -48,37 +48,6 @@
/*******************************************************************************
* Helper functions
******************************************************************************/
-static double
-compute_sky_min_band_len(struct htsky* sky, const double range[2])
-{
- double min_band_len = DBL_MAX;
- size_t nbands;
- ASSERT(sky && range && range[0] <= range[1]);
-
- nbands = htsky_get_spectral_bands_count(sky);
-
- if(eq_eps(range[0], range[1], 1.e-6)) {
- ASSERT(nbands == 1);
- min_band_len = 0;
- } else {
- size_t i = 0;
-
- /* Compute the length of the current band clamped to the submitted range */
- FOR_EACH(i, 0, nbands) {
- const size_t iband = htsky_get_spectral_band_id(sky, i);
- double wlens[2];
- HTSKY(get_spectral_band_bounds(sky, iband, wlens));
-
- /* Adjust band boundaries to the submitted range */
- wlens[0] = MMAX(wlens[0], range[0]);
- wlens[1] = MMIN(wlens[1], range[1]);
-
- min_band_len = MMIN(wlens[1] - wlens[0], min_band_len);
- }
- }
- return min_band_len;
-}
-
/* Compute the number of fixed size bands used to discretized the spectral
* range */
static size_t
@@ -87,8 +56,6 @@ compute_spectral_bands_count(const struct htrdr_atmosphere* cmd)
double wlen_range[2];
double wlen_range_size;
size_t nbands;
- double band_len;
- double band_len_max;
ASSERT(cmd);
/* Compute size of the spectral range in nanometers */
@@ -99,18 +66,6 @@ compute_spectral_bands_count(const struct htrdr_atmosphere* cmd)
/* Define as many intervals as wavelengths count in the spectral range */
nbands = (size_t)rint(wlen_range_size);
- /* Compute the size in nanometers of an interval */
- band_len = wlen_range_size / (double)nbands;
-
- /* Compute the minimum band length of the sky spectral data and define it
- * as the maximum length that the bands can have */
- band_len_max = compute_sky_min_band_len(cmd->sky, wlen_range);
-
- /* Adjust the bands count to ensure that each sky spectral interval is
- * overlapped by at least one band */
- if(band_len > band_len_max) {
- nbands = (size_t)ceil(wlen_range_size / band_len_max);
- }
return nbands;
}
@@ -440,8 +395,8 @@ htrdr_atmosphere_create
cmd->wlen_range_m[0] = spectral_range[0]*1e-9; /* Convert in meters */
cmd->wlen_range_m[1] = spectral_range[1]*1e-9; /* Convert in meters */
- /* Compute the number of fixed sized bands used to descrised to the spectral
- * data */
+ /* Compute the number of fixed sized bands used to accelerate the sampling of
+ * spectral data */
nintervals = compute_spectral_bands_count(cmd);
if(cmd->spectral_type == HTRDR_SPECTRAL_SW_CIE_XYZ) {
diff --git a/src/planeto/htrdr_planeto.c b/src/planeto/htrdr_planeto.c
@@ -51,52 +51,12 @@
/*******************************************************************************
* Helper function
******************************************************************************/
-/* Calculate the minimum length of the atmospheric spectral bands for the
- * spectral domain considered */
-static double
-compute_min_band_len(const struct htrdr_planeto* cmd)
-{
- const double* range = NULL; /* In nm */
- double len = DBL_MAX;
- size_t ibands[2];
- size_t i;
- ASSERT(cmd);
-
- range = cmd->spectral_domain.wlen_range;
-
- /* The spectral range is degenerate to a wavelength */
- if(eq_eps(range[0], range[1], 1.e-6)) {
- return 0;
- }
-
- RNATM(find_bands(cmd->atmosphere, cmd->spectral_domain.wlen_range, ibands));
-
- /* At least one band must be overlaped by the spectral domain */
- ASSERT(ibands[0]<=ibands[1]);
- FOR_EACH(i, ibands[0], ibands[1]+1) {
- struct rnatm_band_desc band;
- double band_range[2];
- RNATM(band_get_desc(cmd->atmosphere, i, &band));
-
- /* Make the upper bound inclusive */
- band_range[0] = band.lower;
- band_range[1] = nextafter(band.upper, 0);
-
- /* Clamp the band range to the spectral domain */
- band_range[0] = MMAX(band_range[0], range[0]);
- band_range[1] = MMIN(band_range[1], range[1]);
- len = MMIN(band_range[1] - band_range[0], len);
- }
- return len;
-}
-
/* Calculate the number of fixed size spectral intervals to use for the
* cumulative */
static size_t
compute_nintervals_for_spectral_cdf(const struct htrdr_planeto* cmd)
{
double range_size;
- double interval_len;
size_t nintervals;
ASSERT(cmd);
@@ -107,14 +67,6 @@ compute_nintervals_for_spectral_cdf(const struct htrdr_planeto* cmd)
/* Initially assume ~one interval per nanometer */
nintervals = (size_t)rint(range_size);
- /* Calculate the minimum length of the atmospheric spectral bands fixed to
- * the spectral integration domain. We ensure that an interval of the
- * spectral cdf cannot be greater than this length */
- interval_len = compute_min_band_len(cmd);
- if(interval_len < (range_size / (double)nintervals)) {
- nintervals = (size_t)ceil(range_size / interval_len);
- }
-
return nintervals;
}