htrdr

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

commit 16fc032a3f487568352803984b2ab6e7d201fb7d
parent 9eca25041ca9e4ce0c4e8e12b371e6982b91d5fc
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 26 Oct 2022 10:05:15 +0200

Implement the htrdr_planeto_<create|ref_get|ref_put> functions

Diffstat:
Mcmake/planeto/CMakeLists.txt | 4+++-
Asrc/planeto/htrdr_planeto.c | 295+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planeto/htrdr_planeto_c.h | 46++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 344 insertions(+), 1 deletion(-)

diff --git a/cmake/planeto/CMakeLists.txt b/cmake/planeto/CMakeLists.txt @@ -16,7 +16,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. cmake_minimum_required(VERSION 3.1) -project(htrdr-planet) +project(htrdr-planeto) ################################################################################ # Check dependencies @@ -51,11 +51,13 @@ include_directories( # Configure and define targets ################################################################################ set(HTRDR_PLANETO_FILES_SRC + htrdr_planeto.c htrdr_planeto_args.c htrdr_planeto_main.c) set(HTRDR_PLANETO_FILES_INC htrdr_planeto.h + htrdr_planeto_c.h htrdr_planeto_args.h) # Prepend each file in the `HTRDR_FILES_<SRC|INC>' list by `HTRDR_SOURCE_DIR' diff --git a/src/planeto/htrdr_planeto.c b/src/planeto/htrdr_planeto.c @@ -0,0 +1,295 @@ +/* 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 + * + * 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 /* fdopen */ + +#include "core/htrdr.h" +#include "core/htrdr_log.h" + +#include "planeto/htrdr_planeto.h" +#include "planeto/htrdr_planeto_args.h" +#include "planeto/htrdr_planeto_c.h" + +#include <rad-net/rnatm.h> +#include <rad-net/rngrd.h> + +#include <rsys/cstr.h> +#include <rsys/mem_allocator.h> + +#include <fcntl.h> /* open */ +#include <unistd.h> /* close */ +#include <sys/stat.h> + +/******************************************************************************* + * Helper function + ******************************************************************************/ +static res_T +setup_octree_storage + (struct htrdr_planeto* cmd, + const struct htrdr_planeto_args* args, + struct rnatm_create_args* rnatm_args) +{ + struct stat file_stat; + int fd = -1; + int err = 0; + res_T res = RES_OK; + ASSERT(cmd && args && rnatm_args); + + rnatm_args->octrees_storage = NULL; + rnatm_args->load_octrees_from_storage = 0; + + if(!args->octrees_storage) goto exit; + + fd = open(args->octrees_storage, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); + if(fd < 0) { res = RES_IO_ERR; goto error; } + + rnatm_args->octrees_storage = fdopen(fd, "w+"); + if(!rnatm_args->octrees_storage) { res = RES_IO_ERR; goto error; } + + /* From now on, manage the opened file from its pointer and not from its + * descriptor */ + fd = -1; + + err = stat(args->octrees_storage, &file_stat); + if(err < 0) { res = RES_IO_ERR; goto error; } + + if(file_stat.st_size == 0) { + /* The file is not empty and therefore must contain valid octrees */ + rnatm_args->load_octrees_from_storage = 1; + } + +exit: + cmd->octrees_storage = rnatm_args->octrees_storage; + return res; +error: + htrdr_log_err(cmd->htrdr, "error opening the octree storage `%s' -- %s\n", + args->octrees_storage, res_to_cstr(res)); + + if(fd >= 0) CHK(close(fd) == 0); + if(rnatm_args->octrees_storage) CHK(fclose(rnatm_args->octrees_storage) == 0); + rnatm_args->octrees_storage = NULL; + rnatm_args->load_octrees_from_storage = 1; + goto exit; +} + +static res_T +setup_atmosphere + (struct htrdr_planeto* cmd, + const struct htrdr_planeto_args* args) +{ + struct rnatm_create_args rnatm_args = RNATM_CREATE_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(cmd && args); + + rnatm_args.gas = args->gas; + rnatm_args.aerosols = args->aerosols; + rnatm_args.naerosols = args->naerosols; + rnatm_args.name = "atmosphere"; + rnatm_args.spectral_range[0] = args->spectral_domain.wlen_range[0]; + rnatm_args.spectral_range[1] = args->spectral_domain.wlen_range[1]; + rnatm_args.optical_thickness = args->optical_thickness; + rnatm_args.grid_definition_hint = args->octree_definition_hint; + rnatm_args.precompute_normals = 0; + rnatm_args.logger = htrdr_get_logger(cmd->htrdr); + rnatm_args.allocator = htrdr_get_allocator(cmd->htrdr); + rnatm_args.nthreads = args->nthreads; + rnatm_args.verbose = args->verbose; + + res = setup_octree_storage(cmd, args, &rnatm_args); + if(res != RES_OK) goto error; + + res = rnatm_create(&rnatm_args, &cmd->atmosphere); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->atmosphere) { + RNATM(ref_put(cmd->atmosphere)); + cmd->atmosphere = NULL; + } + goto exit; +} + +static res_T +setup_ground + (struct htrdr_planeto* cmd, + const struct htrdr_planeto_args* args) +{ + struct rngrd_create_args rngrd_args = RNGRD_CREATE_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(cmd && args); + + rngrd_args.smsh_filename = args->ground.smsh_filename; + rngrd_args.props_filename = args->ground.props_filename; + rngrd_args.mtllst_filename = args->ground.mtllst_filename; + rngrd_args.name = args->ground.name; + rngrd_args.logger = htrdr_get_logger(cmd->htrdr); + rngrd_args.allocator = htrdr_get_allocator(cmd->htrdr); + rngrd_args.verbose = args->verbose; + + res = rngrd_create(&rngrd_args, &cmd->ground); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->ground) { + RNGRD(ref_put(cmd->ground)); + cmd->ground = NULL; + } + goto exit; +} + +static INLINE res_T +setup_spectral_domain + (struct htrdr_planeto* cmd, + const struct htrdr_planeto_args* args) +{ + ASSERT(cmd && args); + cmd->spectral_domain = args->spectral_domain; + return RES_OK; +} + +static res_T +setup_output + (struct htrdr_planeto* cmd, + const struct htrdr_planeto_args* args) +{ + const char* output_name = NULL; + res_T res = RES_OK; + ASSERT(cmd && args); + + /* No output stream on non master processes */ + if(htrdr_get_mpi_rank(cmd->htrdr) != 0) { + cmd->output = NULL; + output_name = "<null>"; + + /* Write results on stdout */ + } else if(!args->output) { + cmd->output = stdout; + output_name = "<stdout>"; + + /* Open the output stream */ + } else { + res = htrdr_open_output_stream(cmd->htrdr, args->output, 0/*read*/, + args->force_output_overwrite, &cmd->output); + if(res != RES_OK) goto error; + output_name = args->output; + } + + res = str_set(&cmd->output_name, output_name); + if(res != RES_OK) { + htrdr_log_err(cmd->htrdr, "error storing output stream name `%s' -- %s\n", + output_name, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + str_clear(&cmd->output_name); + if(cmd->output && cmd->output != stdout) { + CHK(fclose(cmd->output) == 0); + cmd->output = NULL; + } + goto exit; +} + +static void +planeto_release(ref_T* ref) +{ + struct htrdr_planeto* cmd = CONTAINER_OF(ref, struct htrdr_planeto, ref); + struct htrdr* htrdr = NULL; + + ASSERT(ref); + + if(cmd->atmosphere) RNATM(ref_put(cmd->atmosphere)); + if(cmd->ground) RNGRD(ref_put(cmd->ground)); + if(cmd->octrees_storage) CHK(fclose(cmd->octrees_storage) == 0); + if(cmd->output && cmd->output != stdout) CHK(fclose(cmd->output) == 0); + str_release(&cmd->output_name); + + htrdr = cmd->htrdr; + MEM_RM(htrdr_get_allocator(htrdr), cmd); + htrdr_ref_put(htrdr); +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +htrdr_planeto_create + (struct htrdr* htrdr, + const struct htrdr_planeto_args* args, + struct htrdr_planeto** out_cmd) +{ + struct htrdr_planeto* cmd = NULL; + res_T res = RES_OK; + ASSERT(htrdr && out_cmd); + + res = htrdr_planeto_args_check(args); + if(res != RES_OK) { + htrdr_log_err(htrdr, "Invalid htrdr_planeto arguments -- %s\n", + res_to_cstr(res)); + goto error; + } + + cmd = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*cmd)); + if(!cmd) { + htrdr_log_err(htrdr, "Error allocating htrdr_planeto command\n"); + res = RES_MEM_ERR; + goto error; + } + ref_init(&cmd->ref); + htrdr_ref_get(htrdr); + cmd->htrdr = htrdr; + str_init(htrdr_get_allocator(htrdr), &cmd->output_name); + + res = setup_output(cmd, args); + if(res != RES_OK) goto error; + res = setup_spectral_domain(cmd, args); + if(res != RES_OK) goto error; + res = setup_ground(cmd, args); + if(res != RES_OK) goto error; + res = setup_atmosphere(cmd, args); + if(res != RES_OK) goto error; + +exit: + *out_cmd = cmd; + return res; +error: + if(cmd) { + htrdr_planeto_ref_put(cmd); + cmd = NULL; + } + goto exit; +} + +void +htrdr_planeto_ref_get(struct htrdr_planeto* cmd) +{ + ASSERT(cmd); + ref_get(&cmd->ref); +} + +void +htrdr_planeto_ref_put(struct htrdr_planeto* cmd) +{ + ASSERT(cmd); + ref_put(&cmd->ref, planeto_release); +} diff --git a/src/planeto/htrdr_planeto_c.h b/src/planeto/htrdr_planeto_c.h @@ -0,0 +1,46 @@ +/* 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 + * + * 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_PLANETO_C_H +#define HTRDR_PLANETO_C_H + +#include "core/htrdr_args.h" + +#include <rsys/ref_count.h> +#include <rsys/str.h> + +/* Forward declarations */ +struct htrdr; +struct rnatm; +struct rngrd; + +struct htrdr_planeto { + struct rnatm* atmosphere; + struct rngrd* ground; + + struct htrdr_args_spectral spectral_domain; + + FILE* octrees_storage; + + FILE* output; + struct str output_name; + + ref_T ref; + struct htrdr* htrdr; +}; + +#endif /* HTRDR_PLANETO_C_H */