htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit 82a7b2e8552adde24bbb90d82845a20383fb32ab
parent c565ae49a99be1f1466f3708ea50e7355192123d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  9 Dec 2022 16:14:43 +0100

planeto: add support of discrete distribution of wavelengths

In shortwave, if spectrally variable radiance is defined on the source,
wavelengths are sampled from this data.

Diffstat:
Msrc/planeto/htrdr_planeto.c | 53+++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/planeto/htrdr_planeto_c.h | 1+
Msrc/planeto/htrdr_planeto_draw_map.c | 18+++++++++++++++++-
3 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/src/planeto/htrdr_planeto.c b/src/planeto/htrdr_planeto.c @@ -19,6 +19,7 @@ #include "core/htrdr.h" #include "core/htrdr_ran_wlen_cie_xyz.h" +#include "core/htrdr_ran_wlen_discrete.h" #include "core/htrdr_ran_wlen_planck.h" #include "core/htrdr_log.h" @@ -232,6 +233,49 @@ error: goto exit; } +static res_T +setup_spectral_domain_sw + (struct htrdr_planeto* cmd, + const struct htrdr_planeto_args* args) +{ + res_T res = RES_OK; + ASSERT(cmd && args); + ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW); + + /* Discrete distribution */ + if(args->source.rnrl_filename) { + struct htrdr_planeto_source_spectrum spectrum; + struct htrdr_ran_wlen_discrete_create_args discrete_args; + + res = htrdr_planeto_source_get_spectrum + (cmd->source, cmd->spectral_domain.wlen_range, &spectrum); + if(res != RES_OK) goto error; + + discrete_args.get = htrdr_planeto_source_spectrum_at; + discrete_args.nwavelengths = spectrum.size; + discrete_args.context = &spectrum; + res = htrdr_ran_wlen_discrete_create + (cmd->htrdr, &discrete_args, &cmd->discrete); + if(res != RES_OK) goto error; + + /* Planck distribution */ + } else { + const size_t nintervals = compute_nintervals_for_spectral_cdf(cmd); + + /* Use the source temperature as the reference temperature of the Planck + * distribution */ + res = htrdr_ran_wlen_planck_create(cmd->htrdr, + cmd->spectral_domain.wlen_range, nintervals, args->source.temperature, + &cmd->planck); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + static INLINE res_T setup_spectral_domain (struct htrdr_planeto* cmd, @@ -245,7 +289,6 @@ setup_spectral_domain cmd->spectral_domain = args->spectral_domain; /* Configure the spectral distribution */ - nintervals = compute_nintervals_for_spectral_cdf(cmd); switch(cmd->spectral_domain.type) { case HTRDR_SPECTRAL_LW: @@ -255,6 +298,7 @@ setup_spectral_domain /* Use as the reference temperature of the Planck distribution the * maximum scene temperature which, in fact, should be the maximum ground * temperature */ + nintervals = compute_nintervals_for_spectral_cdf(cmd); res = htrdr_ran_wlen_planck_create(cmd->htrdr, cmd->spectral_domain.wlen_range, nintervals, ground_T_range[1], &cmd->planck); @@ -262,16 +306,13 @@ setup_spectral_domain break; case HTRDR_SPECTRAL_SW: - /* Use the source temperature as the reference temperature of the Planck - * distribution */ - res = htrdr_ran_wlen_planck_create(cmd->htrdr, - cmd->spectral_domain.wlen_range, nintervals, args->source.temperature, - &cmd->planck); + res = setup_spectral_domain_sw(cmd, args); if(res != RES_OK) goto error; break; case HTRDR_SPECTRAL_SW_CIE_XYZ: /* CIE XYZ distribution */ + nintervals = compute_nintervals_for_spectral_cdf(cmd); res = htrdr_ran_wlen_cie_xyz_create(cmd->htrdr, cmd->spectral_domain.wlen_range, nintervals, &cmd->cie); if(res != RES_OK) goto error; diff --git a/src/planeto/htrdr_planeto_c.h b/src/planeto/htrdr_planeto_c.h @@ -85,6 +85,7 @@ struct htrdr_planeto { struct htrdr_planeto_spectral_args spectral_domain; struct htrdr_ran_wlen_cie_xyz* cie; /* HTRDR_SPECTRAL_SW_CIE_XYZ */ struct htrdr_ran_wlen_planck* planck; /* HTRDR_SPECTRAL_<LW|SW> */ + struct htrdr_ran_wlen_discrete* discrete; /* HTRDR_SPECTRAL_SW */ FILE* octrees_storage; diff --git a/src/planeto/htrdr_planeto_draw_map.c b/src/planeto/htrdr_planeto_draw_map.c @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "planeto/htrdr_planeto_c.h" +#include "planeto/htrdr_planeto_source.h" #include "core/htrdr.h" #include "core/htrdr_accum.h" @@ -23,6 +24,7 @@ #include "core/htrdr_draw_map.h" #include "core/htrdr_log.h" #include "core/htrdr_ran_wlen_cie_xyz.h" +#include "core/htrdr_ran_wlen_discrete.h" #include "core/htrdr_ran_wlen_planck.h" #include <rad-net/rnatm.h> @@ -92,7 +94,21 @@ draw_pixel_xwave r2 = ssp_rng_canonical(args->rng); /* Sample a wavelength */ - wlen[0] = wlen[1] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf); + switch(cmd->spectral_domain.type) { + case HTRDR_SPECTRAL_LW: + wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf); + break; + case HTRDR_SPECTRAL_SW: + if(htrdr_planeto_source_does_radiance_vary_spectrally(cmd->source)) { + wlen[0] = htrdr_ran_wlen_discrete_sample(cmd->discrete, r0, r1, &pdf); + } else { + wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf); + } + break; + default: FATAL("Unreachable code\n"); break; + + } + wlen[1] = wlen[0]; pdf *= 1.e9; /* Transform the pdf from nm⁻¹ to m⁻¹ */ /* Find the band the wavelength belongs to and sample a quadrature point */