htrdr

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

commit 5201cd3cf44c3a2d459d41ab074b7c0a71735405
parent 0064745d8e23e3a31bacde3aaac258adcf09397c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  6 Mar 2020 12:45:53 +0100

Implement the htrdr_mtl API

Loads a list of materials.

Diffstat:
Mcmake/CMakeLists.txt | 8++++++--
Adoc/mtl | 5+++++
Asrc/htrdr_mtl.c | 251+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/htrdr_mtl.h | 44++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 306 insertions(+), 2 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -24,6 +24,8 @@ option(NO_TEST "Do not build the tests" OFF) ################################################################################ # Check dependencies ################################################################################ +find_package(HTSky REQUIRED) +find_package(MruMtl REQUIRED) find_package(RCMake 0.3 REQUIRED) find_package(RSys 0.7 REQUIRED) find_package(Star3D 0.6 REQUIRED) @@ -31,7 +33,6 @@ find_package(Star3DAW 0.3.1 REQUIRED) find_package(StarSF 0.6 REQUIRED) find_package(StarSP 0.8 REQUIRED) find_package(StarVX REQUIRED) -find_package(HTSky REQUIRED) find_package(OpenMP 1.2 REQUIRED) find_package(MPI 1 REQUIRED) @@ -42,6 +43,7 @@ include(rcmake_runtime) set(CMAKE_C_COMPILER ${MPI_C_COMPILER}) include_directories( + ${MruMtl_INCLUDE_DIR} ${RSys_INCLUDE_DIR} ${Star3D_INCLUDE_DIR} ${Star3DAW_INCLUDE_DIR} @@ -96,6 +98,7 @@ set(HTRDR_FILES_SRC htrdr_grid.c htrdr_ground.c htrdr_main.c + htrdr_mtl.c htrdr_rectangle.c htrdr_slab.c htrdr_sun.c) @@ -106,6 +109,7 @@ set(HTRDR_FILES_INC htrdr_camera.h htrdr_grid.h htrdr_ground.h + htrdr_mtl.h htrdr_rectangle.h htrdr_slab.h htrdr_sun.h @@ -122,7 +126,7 @@ rcmake_prepend_path(HTRDR_FILES_INC2 ${CMAKE_CURRENT_BINARY_DIR}) rcmake_prepend_path(HTRDR_FILES_DOC ${PROJECT_SOURCE_DIR}/../) add_executable(htrdr ${HTRDR_FILES_SRC} ${HTRDR_FILES_INC} ${HTRDR_FILES_INC2}) -target_link_libraries(htrdr HTSky RSys Star3D Star3DAW StarSF StarSP) +target_link_libraries(htrdr HTSky MruMtl RSys Star3D Star3DAW StarSF StarSP) if(CMAKE_COMPILER_IS_GNUCC) target_link_libraries(htrdr m) diff --git a/doc/mtl b/doc/mtl @@ -0,0 +1,5 @@ +<materials-list> ::= <material> + [ <material> ... ] +<material> ::= <material-name> <mrumtl-path> +<material-name> ::= STRING +<mrumtl-path> ::= PATH diff --git a/src/htrdr_mtl.c b/src/htrdr_mtl.c @@ -0,0 +1,251 @@ +/* Copyright (C) 2018, 2019 CNRS, Université Paul Sabatier + * Copyright (C) 2018, 2019, 2020 |Meso|Star> (contact@meso-star.com) + * + * 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/>. */ + +#define _POSIX_C_SOURCE 200112L /* strtok_r support */ + +#include "htrdr.h" +#include "htrdr_mtl.h" + +#include <modradurb/mrumtl.h> + +#include <rsys/cstr.h> +#include <rsys/hash_table.h> +#include <rsys/mem_allocator.h> +#include <rsys/ref_count.h> +#include <rsys/str.h> +#include <rsys/text_reader.h> + +#include <string.h> + +/* Generate the hash table that maps a material name to its data */ +#define HTABLE_NAME name2mtl +#define HTABLE_DATA struct mrumtl* +#define HTABLE_KEY struct str +#define HTABLE_KEY_FUNCTOR_INIT str_init +#define HTABLE_KEY_FUNCTOR_RELEASE str_release +#define HTABLE_KEY_FUNCTOR_COPY str_copy +#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release +#define HTABLE_KEY_FUNCTOR_HASH str_hash +#define HTABLE_KEY_FUNCTOR_EQ str_eq +#include <rsys/hash_table.h> + +struct htrdr_mtl { + struct htable_name2mtl name2mtl; + struct htrdr* htrdr; + ref_T ref; +}; + +/******************************************************************************* + * Local functions + ******************************************************************************/ +static res_T +parse_material + (struct htrdr_mtl* mtl, + struct txtrdr* txtrdr, + struct str* str) /* Scratch string */ +{ + char* tk = NULL; + char* tk_ctx = NULL; + struct mrumtl* mrumtl = NULL; + res_T res = RES_OK; + ASSERT(mtl && txtrdr); + + tk = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx); + ASSERT(tk); + + res = str_set(str, tk); + if(res != RES_OK) { + htrdr_log_err(mtl->htrdr, + "%s:%lu: could not copy the material name `%s' -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk, + res_to_cstr(res)); + goto error; + } + + tk = strtok_r(NULL, "", &tk_ctx); + if(!tk) { + htrdr_log_err(mtl->htrdr, + "%s:%lu: missing the MruMtl file for the material `%s'.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + str_cget(str)); + res = RES_BAD_ARG; + goto error; + } + + res = mrumtl_create + (&mtl->htrdr->logger, mtl->htrdr->allocator, mtl->htrdr->verbose, &mrumtl); + if(res != RES_OK) { + htrdr_log_err(mtl->htrdr, + "%s:%lu: error creating the MruMtl loader for the material `%s'-- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + str_cget(str), res_to_cstr(res)); + goto error; + } + + res = mrumtl_load(mrumtl, tk); + if(res != RES_OK) goto error; + + /* Register the material */ + res = htable_name2mtl_set(&mtl->name2mtl, str, &mrumtl); + if(res != RES_OK) { + htrdr_log_err(mtl->htrdr, + "%s:%lu: could not register the material `%s' -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + str_cget(str), res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + if(mrumtl) MRUMTL(ref_put(mrumtl)); + goto exit; +} + +static res_T +parse_materials_list + (struct htrdr_mtl* mtl, + const char* filename, + const char* func_name) +{ + struct txtrdr* txtrdr = NULL; + struct str str; + res_T res = RES_OK; + ASSERT(mtl && filename && func_name); + + str_init(mtl->htrdr->allocator, &str); + + res = txtrdr_file(mtl->htrdr->allocator, filename, '#', &txtrdr); + if(res != RES_OK) { + htrdr_log_err(mtl->htrdr, + "%s: could not create the text reader for the material file `%s' -- %s.\n", + func_name, filename, res_to_cstr(res)); + goto error; + } + + for(;;) { + res = txtrdr_read_line(txtrdr); + if(res != RES_OK) { + htrdr_log_err(mtl->htrdr, + "%s: error reading a line in the material file `%s' -- %s.\n", + func_name, filename, res_to_cstr(res)); + goto error; + } + + if(!txtrdr_get_cline(txtrdr)) break; + + res = parse_material(mtl, txtrdr, &str); + if(res != RES_OK) goto error; + } + +exit: + str_release(&str); + if(txtrdr) txtrdr_ref_put(txtrdr); + return res; +error: + goto exit; +} + +static void +mtl_release(ref_T* ref) +{ + struct htable_name2mtl_iterator it, it_end; + struct htrdr_mtl* mtl; + ASSERT(ref); + mtl = CONTAINER_OF(ref, struct htrdr_mtl, ref); + + htable_name2mtl_begin(&mtl->name2mtl, &it); + htable_name2mtl_end(&mtl->name2mtl, &it_end); + while(!htable_name2mtl_iterator_eq(&it, &it_end)) { + struct mrumtl* mrumtl = *htable_name2mtl_iterator_data_get(&it); + MRUMTL(ref_put(mrumtl)); + htable_name2mtl_iterator_next(&it); + } + htable_name2mtl_release(&mtl->name2mtl); + MEM_RM(mtl->htrdr->allocator, mtl); +} + +/******************************************************************************* + * Local symbol + ******************************************************************************/ +res_T +htrdr_mtl_load + (struct htrdr* htrdr, + const char* filename, + struct htrdr_mtl** out_mtl) +{ + struct htrdr_mtl* mtl = NULL; + res_T res = RES_OK; + ASSERT(htrdr && filename && mtl); + + mtl = MEM_CALLOC(htrdr->allocator, 1, sizeof(*mtl)); + if(!mtl) { + res = RES_MEM_ERR; + htrdr_log_err(htrdr, + "%s: could not allocate the mtl data structure -- %s.\n", + FUNC_NAME, res_to_cstr(res)); + goto error; + } + ref_init(&mtl->ref); + mtl->htrdr = htrdr; + htable_name2mtl_init(htrdr->allocator, &mtl->name2mtl); + + res = parse_materials_list(mtl, filename, FUNC_NAME); + if(res != RES_OK) goto error; + +exit: + if(out_mtl) *out_mtl = mtl; + return res; +error: + if(mtl) { + htrdr_mtl_ref_put(mtl); + mtl = NULL; + } + goto exit; +} + +void +htrdr_mtl_ref_get(struct htrdr_mtl* mtl) +{ + ASSERT(mtl); + ref_get(&mtl->ref); +} + +void +htrdr_mtl_ref_put(struct htrdr_mtl* mtl) +{ + ASSERT(mtl); + ref_put(&mtl->ref, mtl_release); +} + +const struct mrumtl* +htrdr_mtl_get(struct htrdr_mtl* mtl, const char* name) +{ + struct str str; + struct mrumtl** pmrumtl = NULL; + struct mrumtl* mrumtl = NULL; + ASSERT(mtl && name); + + str_init(mtl->htrdr->allocator, &str); + CHK(str_set(&str, name) == RES_OK); + + pmrumtl = htable_name2mtl_find(&mtl->name2mtl, &str); + if(pmrumtl) mrumtl = *pmrumtl; + + str_release(&str); + return mrumtl; +} + diff --git a/src/htrdr_mtl.h b/src/htrdr_mtl.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2018, 2019 CNRS, Université Paul Sabatier + * Copyright (C) 2018, 2019, 2020 |Meso|Star> (contact@meso-star.com) + * + * 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/>. */ + +#ifndef HTRDR_MTL_H +#define HTRDR_MTL_H + +struct htrdr_mtl; +struct mrumtl; + +extern LOCAL_SYM res_T +htrdr_mtl_load + (struct htrdr* htrdr, + const char* filename, + struct htrdr_mtl** mtl); + +extern LOCAL_SYM void +htrdr_mtl_ref_get + (struct htrdr_mtl* mtl); + +extern LOCAL_SYM void +htrdr_mtl_ref_put + (struct htrdr_mtl* mtl); + +/* Return NULL if the material name does not exist */ +extern const struct mrumtl* +htrdr_mtl_get + (struct htrdr_mtl* mtl, + const char* mtl_name); + +#endif /* HTRDR_MTL_H */ +