htrdr

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

commit 47a11f3369b05172f06044db812cefaaa7df1239
parent ff3dd07b51cb4dece229359a0864ec9ef09adcad
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  7 Dec 2022 08:40:55 +0100

htrdr-planeto: source radiance by wavelength

Source radiance can now be described by wavelength by providing a new
file following a file format described in this commit. When set,
this new argument overrides the source temperature.

In any case, these data are loaded, but are not used internally either
to sample a wavelength during rendering, nor to return spectrally
varying radiance when querying the source. Those are the next steps.

Diffstat:
Mcmake/planeto/CMakeLists.txt | 4+++-
Mdoc/htrdr-planeto.1.scd.in | 2+-
Adoc/rnrl.scd | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/core/htrdr_ran_wlen_planck.c | 2+-
Msrc/planeto/htrdr_planeto_args.c | 26++++++++++++++++++++++----
Msrc/planeto/htrdr_planeto_args.h.in | 5++++-
Msrc/planeto/htrdr_planeto_source.c | 44++++++++++++++++++++++++++++++++++++++++++--
7 files changed, 158 insertions(+), 10 deletions(-)

diff --git a/cmake/planeto/CMakeLists.txt b/cmake/planeto/CMakeLists.txt @@ -26,6 +26,7 @@ find_package(RNATM 0.0 REQUIRED) find_package(RNGRD 0.0 REQUIRED) find_package(RSys 0.11 REQUIRED) find_package(Star3D 0.8 REQUIRED) +find_package(StarBuffer 0.0 REQUIRED) find_package(StarCamera 0.0 REQUIRED) find_package(StarSF 0.6 REQUIRED) find_package(StarSP 0.12 REQUIRED) @@ -40,6 +41,7 @@ include_directories( ${RNGRD} ${RSys_INCLUDE_DIR} ${Star3D_INCLUDE_DIR} + ${StarBuffer_INCLUDE_DIR} ${StarCamera_INCLUDE_DIR} ${StarSF_INCLUDE_DIR} ${StarSP_INCLUDE_DIR} @@ -81,7 +83,7 @@ add_library(htrdr-planeto SHARED ${HTRDR_PLANETO_FILES_SRC} ${HTRDR_PLANETO_FILES_INC}) target_link_libraries(htrdr-planeto - htrdr-core RNATM RNGRD RSys Star3D StarCamera StarSF StarSP) + htrdr-core RNATM RNGRD RSys Star3D StarBuffer StarCamera StarSF StarSP) set_target_properties(htrdr-planeto PROPERTIES DEFINE_SYMBOL HTRDR_SHARED_BUILD diff --git a/doc/htrdr-planeto.1.scd.in b/doc/htrdr-planeto.1.scd.in @@ -18,7 +18,7 @@ htrdr-planeto(1) ; You should have received a copy of the GNU General Public License ; along with this program. If not, see <http://www.gnu.org/licenses/>. -# Name +# NAME htrdr-planeto - simulate radiative transfer in 3D planetary atmosphere diff --git a/doc/rnrl.scd b/doc/rnrl.scd @@ -0,0 +1,85 @@ +rnrl(5) + +; Copyright (C) 2018, 2019, 2020, 2021 |Meso|Star> (contact@meso-star.com) +; Copyright (C) 2018, 2019, 2021 CNRS +; Copyright (C) 2018, 2019 Université Paul Sabatier +; (contact-edstar@laplace.univ-tlse.fr) +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see <http://www.gnu.org/licenses/>. + +# NAME + +rnsr - Rad-Net Radiance List file format + +# DESCRIPTION + +*rnrl* is a binary file format for storing a list of spectrally varying +radiances. The radiances (in W/m²/sr/m) are listed by wavelength (in nm) +sorted in ascending order. + +A *rnrl* file is actually a Star-Buffer file (see *sbuf*(5)). It starts with a +header of 4 64-bit integers describing the layout of the data. The first integer +is a power of two (usually 4096) that defines the size of the memory page in +bytes to which the list of per wavelength radiances aligns (_pagesize_). The +second integer is the _size_ of the array, i.e. the number of wavelength for +which a radiance is defined. Finally, the 2 remaining integers store the memory +size (16 bytes, i.e. 2 double precision values) and the memory alignment (16 +bytes) of a per wavelength radiance. + +An *rnrl* file is actually a Star-Buffer file (see *sbuf*(5)). It starts with a +header of 4 64-bit integers describing the layout of the data. The first integer +is a power of two (usually 4096) which defines the size of the memory page in +bytes on which the list of radiances by wavelength aligns (_pagesize_). The +second integer is the _size_ of the array, that is, the number of wavelengths +for which a radiance is defined. Finally, the remaining 2 integers store the +memory size (16 bytes) and memory alignment (16 bytes) of a radiance per +wavelength. + +The fill bytes follow the file header to align the radiances by wavelength to +_pagesize_. + +Each item in the list is composed of 2 double-precision floating-point values: +the wavelength in nanometers and its corresponding radiance in W/m²/sr/m. + +The end of the file is eventually padded with dummy bytes to ensure that the +overall file size is a multiple of _pagesize_. + +# BINARY FILE FORMAT + +Data are encoded with respect to the little endian bytes ordering, i.e. least +significant bytes are stored first. + +``` +<rnsr> ::= <pagesize> <size> 16 16 + <padding> + <radiances> + <padding> + +<pagesize> ::= UINT64 +<size> ::= UINT64 # Number of items stored + +--- + +<radiances> ::= <property> ... ... +<property> ::= <wavelength> <radiance> +<wavelength> ::= DOUBLE # in nanometer +<radiance> ::= DOUBLE # in W/m²/sr/m + +--- + +<padding> ::= [ BYTE ... ] # Ensure alignement +``` + +# SEE ALSO + +*sbuf*(5) diff --git a/src/core/htrdr_ran_wlen_planck.c b/src/core/htrdr_ran_wlen_planck.c @@ -298,7 +298,7 @@ htrdr_ran_wlen_planck_create if(!planck) { res = RES_MEM_ERR; htrdr_log_err(htrdr, - "%s: could not allocate longwave random variate data structure -- %s.\n", + "%s: could not allocate Planck distribution -- %s.\n", FUNC_NAME, res_to_cstr(res)); goto error; } diff --git a/src/planeto/htrdr_planeto_args.c b/src/planeto/htrdr_planeto_args.c @@ -386,7 +386,7 @@ error: static res_T parse_source_parameters(const char* str, void* ptr) { - enum {LAT, LON, DST, RADIUS, TEMP} iparam; + enum {LAT, LON, DST, RADIUS, TEMP, RAD} iparam; char buf[BUFSIZ]; struct htrdr_planeto_args* args = ptr; struct htrdr_planeto_source_args* src = NULL; @@ -411,6 +411,7 @@ parse_source_parameters(const char* str, void* ptr) if(!strcmp(key, "lat")) iparam = LAT; else if(!strcmp(key, "lon")) iparam = LON; else if(!strcmp(key, "dst")) iparam = DST; + else if(!strcmp(key, "rad")) iparam = RAD; else if(!strcmp(key, "radius")) iparam = RADIUS; else if(!strcmp(key, "temp")) iparam = TEMP; else { @@ -442,11 +443,23 @@ parse_source_parameters(const char* str, void* ptr) res = cstr_to_double(val, &src->distance); if(res == RES_OK && src->distance < 0) res = RES_BAD_ARG; break; + case RAD: + /* Use a per wavelength radiance rather than a constant temperature */ + src->temperature = -1; + if(src->rnrl_filename) mem_rm(src->rnrl_filename); + src->rnrl_filename = str_dup(val); + if(!src->rnrl_filename) res = RES_MEM_ERR; + break; case RADIUS: res = cstr_to_double(val, &src->radius); if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG; break; case TEMP: + /* Use a constant temperature rather than a per wavelength radiance */ + if(src->rnrl_filename) { + mem_rm(src->rnrl_filename); + src->rnrl_filename = NULL; + } res = cstr_to_double(val, &src->temperature); if(res == RES_OK && src->temperature < 0) res = RES_BAD_ARG; break; @@ -692,6 +705,7 @@ htrdr_planeto_args_release(struct htrdr_planeto_args* args) if(args->ground.props_filename) mem_rm(args->ground.props_filename); if(args->ground.mtllst_filename) mem_rm(args->ground.mtllst_filename); if(args->ground.name) mem_rm(args->ground.name); + if(args->source.rnrl_filename) mem_rm(args->source.rnrl_filename); FOR_EACH(i, 0, args->naerosols) { struct rnatm_aerosol_args* aerosol = args->aerosols + i; @@ -775,9 +789,13 @@ htrdr_planeto_source_args_check(const struct htrdr_planeto_source_args* args) || args->distance < 0) return RES_BAD_ARG; - /* Miscellaneous parameters */ - if(args->radius < 0 - || args->temperature < 0) + /* Invalid radius */ + if(args->radius < 0) + return RES_BAD_ARG; + + /* Invalid radiance */ + if((args->temperature < 0 && !args->rnrl_filename) /* Both are invalids */ + || (args->temperature >=0 && args->rnrl_filename)) /* Both are valids */ return RES_BAD_ARG; return RES_OK; diff --git a/src/planeto/htrdr_planeto_args.h.in b/src/planeto/htrdr_planeto_args.h.in @@ -43,13 +43,16 @@ static const struct htrdr_planeto_spectral_args HTRDR_PLANETO_SPECTRAL_ARGS_DEFAULT = HTRDR_PLANETO_SPECTRAL_ARGS_DEFAULT__; struct htrdr_planeto_source_args { + /* Radiance of the source per wavelength. May be NULL */ + char* rnrl_filename; + double longitude; /* In [-180, 180] degrees */ double latitude; /* In [-90, 90] degrees */ double distance; /* In km */ double radius; /* In km */ double temperature; /* In Kelvin */ }; -#define HTRDR_PLANETO_SOURCE_ARGS_NULL__ {0,0,0,-1,-1} +#define HTRDR_PLANETO_SOURCE_ARGS_NULL__ {NULL,0,0,0,-1,-1} static const struct htrdr_planeto_source_args HTRDR_PLANETO_SOURCE_ARGS_NULL = HTRDR_PLANETO_SOURCE_ARGS_NULL__; diff --git a/src/planeto/htrdr_planeto_source.c b/src/planeto/htrdr_planeto_source.c @@ -21,8 +21,10 @@ #include "core/htrdr.h" #include "core/htrdr_log.h" +#include <star/sbuf.h> #include <star/ssp.h> +#include <rsys/cstr.h> #include <rsys/double3.h> #include <rsys/ref_count.h> @@ -30,7 +32,11 @@ struct htrdr_planeto_source { double position[3]; /* In m */ double radius; /* In m */ - double temperature; /* In Kelvin */ + + /* In Kelvin. Defined if the radiances by wavelength is no set */ + double temperature; + + struct sbuf* per_wlen_radiances; /* List of radiances by wavelength */ ref_T ref; struct htrdr* htrdr; @@ -39,6 +45,32 @@ struct htrdr_planeto_source { /******************************************************************************* * Helper functions ******************************************************************************/ +static res_T +setup_per_wavelength_radiances + (struct htrdr_planeto_source* src, + const struct htrdr_planeto_source_args* args) +{ + struct sbuf_create_args sbuf_args; + res_T res = RES_OK; + ASSERT(src && args && args->rnrl_filename && args->temperature < 0); + + sbuf_args.logger = htrdr_get_logger(src->htrdr); + sbuf_args.allocator = htrdr_get_allocator(src->htrdr); + sbuf_args.verbose = htrdr_get_verbosity_level(src->htrdr); + res = sbuf_create(&sbuf_args, &src->per_wlen_radiances); + if(res != RES_OK) goto error; + + res = sbuf_load(src->per_wlen_radiances, args->rnrl_filename); + if(res != RES_OK) goto error; + +exit: + return res; +error: + htrdr_log_err(src->htrdr, "error loading %s -- %s\n", + args->rnrl_filename, res_to_cstr(res)); + goto exit; +} + static void release_source(ref_T* ref) { @@ -48,6 +80,7 @@ release_source(ref_T* ref) source = CONTAINER_OF(ref, struct htrdr_planeto_source, ref); htrdr = source->htrdr; + if(source->per_wlen_radiances) SBUF(ref_put(source->per_wlen_radiances)); MEM_RM(htrdr_get_allocator(htrdr), source); htrdr_ref_put(htrdr); } @@ -79,7 +112,14 @@ htrdr_planeto_source_create htrdr_ref_get(cmd->htrdr); src->htrdr = cmd->htrdr; src->radius = args->radius * 1e3/*From km to m*/; - src->temperature = args->temperature; + + if(!args->rnrl_filename) { + src->temperature = args->temperature; + } else { + res = setup_per_wavelength_radiances(src, args); + if(res != RES_OK) goto error; + src->temperature = -1; /* Not used */ + } /* Convert latitude and longitude to radians and distance in m */ lat = MDEG2RAD(args->latitude);