htrdr

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

commit 7e64e3bd99960fbcc8c4fce1f7173a8759434953
parent 4890f4897eff37a037c0f9eb3a4c8757083cd859
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu,  4 Mar 2021 14:48:10 +0100

Implement the htrdr_combustion_<create|ref_put|ref_get> functions

Diffstat:
Mcmake/combustion/CMakeLists.txt | 2++
Msrc/atmosphere/htrdr_atmosphere.c | 5+++--
Msrc/atmosphere/htrdr_atmosphere_c.h | 18+++++-------------
Msrc/atmosphere/htrdr_atmosphere_draw_map.c | 2+-
Asrc/combustion/htrdr_combustion.c | 334+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/combustion/htrdr_combustion.h | 18++++++++++++++++++
Msrc/combustion/htrdr_combustion_args.c | 30++++++++++++++++--------------
Msrc/combustion/htrdr_combustion_args.h | 26++++++++++++++------------
Asrc/combustion/htrdr_combustion_c.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/combustion/htrdr_combustion_main.c | 28++++++++++++++++++++++++++++
Msrc/core/htrdr_args.c | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/core/htrdr_args.h.in | 24+++++++++++++++++++++---
Msrc/core/htrdr_buffer.h | 8++++++++
Msrc/core/htrdr_rectangle.c | 2+-
14 files changed, 635 insertions(+), 51 deletions(-)

diff --git a/cmake/combustion/CMakeLists.txt b/cmake/combustion/CMakeLists.txt @@ -47,11 +47,13 @@ include_directories( # Configure and define targets ################################################################################ set(HTRDR_COMBUSTION_FILES_SRC + htrdr_combustion.c htrdr_combustion_args.c htrdr_combustion_main.c) set(HTRDR_COMBUSTION_FILES_INC htrdr_combustion.h + htrdr_combustion_c.h htrdr_combustion_args.h) # Prepend each file in the `HTRDR_FILES_<SRC|INC>' list by `HTRDR_SOURCE_DIR' diff --git a/src/atmosphere/htrdr_atmosphere.c b/src/atmosphere/htrdr_atmosphere.c @@ -391,7 +391,7 @@ htrdr_atmosphere_create if(!cmd->dump_volumetric_acceleration_structure) { - struct atmosphere_pixel_format pixfmt = ATMOSPHERE_PIXEL_FORMAT_NULL; + struct htrdr_pixel_format pixfmt = HTRDR_PIXEL_FORMAT_NULL; atmosphere_get_pixel_format(cmd, &pixfmt); /* Setup the buffer layout */ @@ -459,8 +459,9 @@ error: void atmosphere_get_pixel_format (const struct htrdr_atmosphere* cmd, - struct atmosphere_pixel_format* fmt) + struct htrdr_pixel_format* fmt) { + ASSERT(cmd && fmt); switch(cmd->sensor.type) { case HTRDR_SENSOR_RECTANGLE: fmt->size = sizeof(struct atmosphere_pixel_flux); diff --git a/src/atmosphere/htrdr_atmosphere_c.h b/src/atmosphere/htrdr_atmosphere_c.h @@ -36,14 +36,6 @@ enum atmosphere_radiance_cpnt_flag { | ATMOSPHERE_RADIANCE_DIFFUSE }; -struct atmosphere_pixel_format { - size_t size; /* In bytes */ - size_t alignment; /* Power of two, in Bytes */ -}; -#define ATMOSPHERE_PIXEL_FORMAT_NULL__ {0, 0} -static const struct atmosphere_pixel_format ATMOSPHERE_PIXEL_FORMAT_NULL = - ATMOSPHERE_PIXEL_FORMAT_NULL__; - struct atmosphere_pixel_xwave { struct htrdr_estimate radiance; /* In W/m^2/sr */ struct htrdr_estimate radiance_temperature; /* In K */ @@ -52,7 +44,7 @@ struct atmosphere_pixel_xwave { #define ATMOSPHERE_PIXEL_XWAVE_NULL__ { \ HTRDR_ESTIMATE_NULL__, /* Radiance */ \ HTRDR_ESTIMATE_NULL__, /* Radiance temperature */ \ - HTRDR_ACCUM_NULL /* Time */ \ + HTRDR_ACCUM_NULL__ /* Time */ \ } static const struct atmosphere_pixel_xwave ATMOSPHERE_PIXEL_XWAVE_NULL = ATMOSPHERE_PIXEL_XWAVE_NULL__; @@ -62,8 +54,8 @@ struct atmosphere_pixel_flux { struct htrdr_accum time; }; #define ATMOSPHERE_PIXEL_FLUX_NULL__ { \ - HTRDR_ACCUM_NULL, \ - HTRDR_ACCUM_NULL \ + HTRDR_ACCUM_NULL__, \ + HTRDR_ACCUM_NULL__ \ } static const struct atmosphere_pixel_flux ATMOSPHERE_PIXEL_FLUX_NULL = ATMOSPHERE_PIXEL_FLUX_NULL__; @@ -78,7 +70,7 @@ struct atmosphere_pixel_image { HTRDR_ESTIMATE_NULL__, /* X */ \ HTRDR_ESTIMATE_NULL__, /* Y */ \ HTRDR_ESTIMATE_NULL__, /* Z */ \ - HTRDR_ACCUM_NULL /* Time */ \ + HTRDR_ACCUM_NULL__ /* Time */ \ } static const struct atmosphere_pixel_image ATMOSPHERE_PIXEL_IMAGE_NULL = ATMOSPHERE_PIXEL_IMAGE_NULL__; @@ -129,7 +121,7 @@ struct htrdr_atmosphere { extern LOCAL_SYM void atmosphere_get_pixel_format (const struct htrdr_atmosphere* cmd, - struct atmosphere_pixel_format* fmt); + struct htrdr_pixel_format* fmt); extern LOCAL_SYM res_T atmosphere_draw_map diff --git a/src/atmosphere/htrdr_atmosphere_draw_map.c b/src/atmosphere/htrdr_atmosphere_draw_map.c @@ -540,7 +540,7 @@ dump_buffer struct htrdr_accum* flux_acc, /* May be NULL */ FILE* stream) { - struct atmosphere_pixel_format pixfmt; + struct htrdr_pixel_format pixfmt; struct htrdr_buffer_layout layout; size_t x, y; ASSERT(cmd && buf && stream); diff --git a/src/combustion/htrdr_combustion.c b/src/combustion/htrdr_combustion.c @@ -0,0 +1,334 @@ +/* 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/>. */ + +#include "combustion/htrdr_combustion.h" +#include "combustion/htrdr_combustion_args.h" +#include "combustion/htrdr_combustion_c.h" + +#include "core/htrdr.h" +#include "core/htrdr_camera.h" +#include "core/htrdr_log.h" +#include "core/htrdr_geometry.h" +#include "core/htrdr_materials.h" +#include "core/htrdr_rectangle.h" + +#include <astoria/atrstm.h> + +#include <rsys/cstr.h> +#include <rsys/mem_allocator.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static res_T +setup_output + (struct htrdr_combustion* cmd, + const struct htrdr_combustion_args* args) +{ + const char* output_name = NULL; + res_T res = RES_OK; + ASSERT(cmd && args); + + if(htrdr_get_mpi_rank(cmd->htrdr) != 0) { + /* No output stream on non master processes */ + cmd->output = NULL; + output_name = "<null>"; + + } else if(!args->path_output) { + /* Write results to standard output when no destination file is defined */ + cmd->output = stdout; + output_name = "<stdout>"; + + } else { + /* Open the output stream */ + res = htrdr_open_output_stream(cmd->htrdr, args->path_output, + 0/*read*/, args->force_overwriting, &cmd->output); + if(res != RES_OK) goto error; + output_name = args->path_output; + } + + /* Setup the output name */ + str_set(&cmd->output_name, output_name); + if(res != RES_OK) { + htrdr_log_err(cmd->htrdr, + "Could not store the name of the output stream `%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 res_T +setup_geometry + (struct htrdr_combustion* cmd, + const struct htrdr_combustion_args* args) +{ + res_T res = RES_OK; + + if(!args->geom.path_obj) goto exit; + ASSERT(args->geom.path_mats); + + res = htrdr_materials_create(cmd->htrdr, args->geom.path_mats, &cmd->mats); + if(res != RES_OK) goto error; + + res = htrdr_geometry_create + (cmd->htrdr, args->geom.path_obj, cmd->mats, &cmd->geom); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->mats) { htrdr_materials_ref_put(cmd->mats); cmd->mats = NULL; } + if(cmd->geom) { htrdr_geometry_ref_put(cmd->geom); cmd->geom = NULL; } + goto exit; +} + +static res_T +setup_camera + (struct htrdr_combustion* cmd, + const struct htrdr_combustion_args* args) +{ + double proj_ratio = 0; + ASSERT(cmd && args && args->image.definition[0] && args->image.definition[1]); + + proj_ratio = + (double)args->image.definition[0] + / (double)args->image.definition[1]; + + return htrdr_camera_create + (cmd->htrdr, + args->camera.position, + args->camera.target, + args->camera.up, + proj_ratio, + MDEG2RAD(args->camera.fov_y), + &cmd->camera); +} + +static res_T +setup_laser + (struct htrdr_combustion* cmd, + const struct htrdr_combustion_args* args) +{ + ASSERT(cmd && args); + cmd->wavelength = args->wavelength; + return htrdr_rectangle_create + (cmd->htrdr, + args->laser.size, + args->laser.position, + args->laser.target, + args->laser.up, + &cmd->laser); +} + +static res_T +setup_buffer + (struct htrdr_combustion* cmd, + const struct htrdr_combustion_args* args) +{ + struct htrdr_pixel_format pixfmt = HTRDR_PIXEL_FORMAT_NULL; + res_T res = RES_OK; + ASSERT(cmd && args); + + if(cmd->dump_volumetric_acceleration_structure) goto exit; + + combustion_get_pixel_format(cmd, &pixfmt); + + /* Setup the buffer layout */ + cmd->buf_layout.width = args->image.definition[0]; + cmd->buf_layout.height = args->image.definition[1]; + cmd->buf_layout.pitch = args->image.definition[0] * pixfmt.size; + cmd->buf_layout.elmt_size = pixfmt.size; + cmd->buf_layout.alignment = pixfmt.alignment; + + /* Create the image buffer only on the master process; the image parts + * rendered by the others processes are gathered onto the master process */ + if(!htrdr_get_mpi_rank(cmd->htrdr) != 0) goto exit; + + res = htrdr_buffer_create(cmd->htrdr, &cmd->buf_layout, &cmd->buf); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->buf) { htrdr_buffer_ref_put(cmd->buf); cmd->buf = NULL; } + goto exit; +} + +static res_T +setup_medium + (struct htrdr_combustion* cmd, + const struct htrdr_combustion_args* args) +{ + struct atrstm_args atrstm_args = ATRSTM_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(cmd && args); + + /* Setup the semi-transaprent medium arguments */ + atrstm_args.sth_filename = args->path_tetra; + atrstm_args.atrtp_filename = args->path_therm_props; + atrstm_args.atrri_filename = args->path_refract_ids; + atrstm_args.cache_filename = args->path_cache; + atrstm_args.spectral_type = ATRSTM_SPECTRAL_SW; + atrstm_args.wlen_range[0] = args->wavelength; + atrstm_args.wlen_range[1] = args->wavelength; + atrstm_args.gyration_radius_prefactor = args->gyration_radius_prefactor; + atrstm_args.fractal_dimension = args->fractal_dimension; + atrstm_args.optical_thickness = args->optical_thickness; + atrstm_args.precompute_normals = args->precompute_normals; + atrstm_args.nthreads = args->nthreads; + atrstm_args.verbose = args->verbose; + + switch(args->grid.type) { + case HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_AUTO: + atrstm_args.auto_grid_definition = 1; + atrstm_args.auto_grid_definition_hint = args->grid.definition.hint; + break; + case HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_FIXED: + atrstm_args.auto_grid_definition = 0; + atrstm_args.grid_max_definition[0] = args->grid.definition.fixed[0]; + atrstm_args.grid_max_definition[1] = args->grid.definition.fixed[1]; + atrstm_args.grid_max_definition[2] = args->grid.definition.fixed[2]; + break; + default: FATAL("Unreachable code.\n"); break; + } + + /* Here we go! Create the semi-transparent medium */ + res = atrstm_create + (htrdr_get_logger(cmd->htrdr), + htrdr_get_allocator(cmd->htrdr), + &atrstm_args, + &cmd->medium); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->medium) { ATRSTM(ref_put(cmd->medium)); cmd->medium = NULL; } + goto exit; +} + +static void +combustion_release(ref_T* ref) +{ + struct htrdr_combustion* cmd = CONTAINER_OF(ref, struct htrdr_combustion, ref); + struct htrdr* htrdr = NULL; + ASSERT(ref); + + if(cmd->geom) htrdr_geometry_ref_put(cmd->geom); + if(cmd->mats) htrdr_materials_ref_put(cmd->mats); + if(cmd->medium) ATRSTM(ref_put(cmd->medium)); + if(cmd->camera) htrdr_camera_ref_put(cmd->camera); + if(cmd->laser) htrdr_rectangle_ref_put(cmd->laser); + if(cmd->buf) htrdr_buffer_ref_put(cmd->buf); + 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_combustion_create + (struct htrdr* htrdr, + const struct htrdr_combustion_args* args, + struct htrdr_combustion** out_cmd) +{ + struct htrdr_combustion* cmd = NULL; + res_T res = RES_OK; + ASSERT(htrdr && args && out_cmd); + + cmd = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*cmd)); + if(!cmd) { + htrdr_log_err(htrdr, "Could not allocate the htrdr_combustion data.\n"); + res = RES_BAD_ARG; + goto error; + } + ref_init(&cmd->ref); + str_init(htrdr_get_allocator(htrdr), &cmd->output_name); + + /* Get the ownership on the htrdr structure */ + htrdr_ref_get(htrdr); + cmd->htrdr = htrdr; + + cmd->dump_volumetric_acceleration_structure = + args->dump_volumetric_acceleration_structure; + + res = setup_output(cmd, args); + if(res != RES_OK) goto error; + res = setup_geometry(cmd, args); + if(res != RES_OK) goto error; + res = setup_camera(cmd, args); + if(res != RES_OK) goto error; + res = setup_laser(cmd, args); + if(res != RES_OK) goto error; + res = setup_buffer(cmd, args); + if(res != RES_OK) goto error; + res = setup_medium(cmd, args); + if(res != RES_OK) goto error; + +exit: + *out_cmd = cmd; + return res; +error: + if(cmd) { + htrdr_combustion_ref_put(cmd); + cmd = NULL; + } + goto exit; +} + +void +htrdr_combustion_ref_get(struct htrdr_combustion* cmd) +{ + ASSERT(cmd); + ref_get(&cmd->ref); +} + +void +htrdr_combustion_ref_put(struct htrdr_combustion* cmd) +{ + ASSERT(cmd); + ref_put(&cmd->ref, combustion_release); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +void +combustion_get_pixel_format + (const struct htrdr_combustion* cmd, + struct htrdr_pixel_format* fmt) +{ + ASSERT(cmd && fmt); + (void)cmd; + fmt->size = sizeof(struct combustion_pixel); + fmt->alignment = ALIGNOF(struct combustion_pixel); +} diff --git a/src/combustion/htrdr_combustion.h b/src/combustion/htrdr_combustion.h @@ -21,8 +21,26 @@ #include "core/htrdr.h" #include <rsys/rsys.h> +struct htrdr; +struct htrdr_combustion; +struct htrdr_combustion_args; + BEGIN_DECLS +HTRDR_API res_T +htrdr_combustion_create + (struct htrdr* htrdr, + const struct htrdr_combustion_args* args, + struct htrdr_combustion** cmd); + +HTRDR_API void +htrdr_combustion_ref_get + (struct htrdr_combustion* cmd); + +HTRDR_API void +htrdr_combustion_ref_put + (struct htrdr_combustion* cmd); + HTRDR_API int htrdr_combustion_main (int argc, diff --git a/src/combustion/htrdr_combustion_args.c b/src/combustion/htrdr_combustion_args.c @@ -51,12 +51,13 @@ print_help(const char* cmd) " model. Its default value is %g.\n", HTRDR_COMBUSTION_ARGS_DEFAULT.gyration_radius_prefactor); printf( -" -g GEOMETRY filename of the combustion chamber.\n"); +" -g <geometry> define the combustion chamber geometry. Refer to the\n" +" %s man page for the list of geometry options.\n", cmd); printf( " -h display this help and exit.\n"); printf( " -i <image> define the image to compute. Refer to the %s man\n" -" page for the list of image options\n", cmd); +" page for the list of image options.\n", cmd); printf( " -l <laser> define the geometry of the laser sheet. Refer to the\n" " %s man page for the list of laser options.\n", cmd); @@ -65,7 +66,7 @@ print_help(const char* cmd) printf( " -N precompute the tetrahedra normals.\n"); printf( -" -O CACHE filename of the cache file used to store/restore the\n" +" -O CACHE path of the cache file used to store/restore the\n" " volumetric data. By default do not use any cache.\n"); printf( " -o OUTPUT file where data are written. If not defined, data are\n" @@ -182,7 +183,7 @@ htrdr_combustion_args_init res = RES_BAD_ARG; break; case 'g': - args->filename_geom = optarg; + res = htrdr_args_geometry_parse(&args->geom, optarg); break; case 'h': print_help(argv[0]); @@ -196,12 +197,12 @@ htrdr_combustion_args_init res = htrdr_args_rectangle_parse(&args->laser, optarg); laser_is_defined = 1; break; - case 'm': args->filename_tetra = optarg; break; + case 'm': args->path_tetra = optarg; break; case 'N': args->precompute_normals = 1; break; - case 'O': args->filename_cache = optarg; break; - case 'o': args->filename_output = optarg; break; - case 'p': args->filename_therm_props = optarg; break; - case 'r': args->filename_refract_ids = optarg; break; + case 'O': args->path_cache = optarg; break; + case 'o': args->path_output = optarg; break; + case 'p': args->path_therm_props = optarg; break; + case 'r': args->path_refract_ids = optarg; break; case 'T': res = cstr_to_double(optarg, &args->optical_thickness); if(res == RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG; @@ -214,7 +215,7 @@ htrdr_combustion_args_init res = parse_grid_definition(&args->grid, optarg); break; case 'v': args->verbose = 1; break; - case 'w': + case 'w': res = cstr_to_double(optarg, &args->wavelength); break; default: res = RES_BAD_ARG; break; @@ -228,22 +229,22 @@ htrdr_combustion_args_init } } - if(!laser_is_defined) { + if(!args->dump_volumetric_acceleration_structure && !laser_is_defined) { fprintf(stderr, "Missing the laser definition -- option '-l'\n"); res = RES_BAD_ARG; goto error; } - if(!args->filename_tetra) { + if(!args->path_tetra) { fprintf(stderr, "Missing the volumetric mesh -- option '-m'\n"); res = RES_BAD_ARG; goto error; } - if(!args->filename_therm_props) { + if(!args->path_therm_props) { fprintf(stderr, "Missing the thermodynamic properties -- option '-p'\n"); res = RES_BAD_ARG; goto error; } - if(!args->filename_refract_ids) { + if(!args->path_refract_ids) { fprintf(stderr, "Missing the refractive indices -- option '-r'\n"); res = RES_BAD_ARG; goto error; @@ -260,6 +261,7 @@ void htrdr_combustion_args_release(struct htrdr_combustion_args* args) { ASSERT(args); + htrdr_args_geometry_free(&args->geom); *args = HTRDR_COMBUSTION_ARGS_DEFAULT; } diff --git a/src/combustion/htrdr_combustion_args.h b/src/combustion/htrdr_combustion_args.h @@ -45,13 +45,14 @@ HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_DEFAULT = HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_DEFAULT__; struct htrdr_combustion_args { - const char* filename_geom; /* Obj of the combustion chamber */ - const char* filename_tetra; /* Volumetric mesh of the medium */ - const char* filename_therm_props; /* Termodynamic properties of the medium */ - const char* filename_refract_ids; /* Refractive indices in the medium */ + struct htrdr_args_geometry geom; /* Combustion chamber geometry */ - const char* filename_cache; /* Path of the file to store/restore cached data */ - const char* filename_output; /* Name of the output file */ + const char* path_tetra; /* Volumetric mesh of the medium */ + const char* path_therm_props; /* Termodynamic properties of the medium */ + const char* path_refract_ids; /* Refractive indices in the medium */ + + const char* path_cache; /* Path of the file to store/restore cached data */ + const char* path_output; /* Name of the output file */ struct htrdr_args_camera camera; /* Pinhole Camera */ @@ -78,13 +79,14 @@ struct htrdr_combustion_args { }; #define HTRDR_COMBUSTION_ARGS_DEFAULT__ { \ - NULL, /* Geom filename */ \ - NULL, /* Tetra filename */ \ - NULL, /* Therm props filename */ \ - NULL, /* Refractive ids filename */ \ + HTRDR_ARGS_GEOMETRY_NULL__, \ + \ + NULL, /* Tetra path */ \ + NULL, /* Therm props path */ \ + NULL, /* Refractive ids path */ \ \ - NULL, /* Cache filename */ \ - NULL, /* Output filename */ \ + NULL, /* Cache path */ \ + NULL, /* Output path */ \ \ HTRDR_ARGS_CAMERA_DEFAULT__, /* Pinhole camera */ \ \ diff --git a/src/combustion/htrdr_combustion_c.h b/src/combustion/htrdr_combustion_c.h @@ -0,0 +1,73 @@ +/* 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_COMBUSTION_C_H +#define HTRDR_COMBUSTION_C_H + +#include "core/htrdr_accum.h" +#include "core/htrdr_args.h" +#include "core/htrdr_buffer.h" + +#include <rsys/ref_count.h> +#include <rsys/str.h> + +/* Forward declarations */ +struct atrstm; +struct htrdr; +struct htrdr_camera; +struct htrdr_geometry; +struct htrdr_materials; +struct htrdr_rectangle; + +struct combustion_pixel { + struct htrdr_estimate radiance; /* In W/m^2/sr */ + struct htrdr_accum time; /* In microseconds */ +}; +#define COMBUSTION_PIXEL_NULL__ { \ + HTRDR_ESTIMATE_NULL__, /* Radiance */ \ + HTRDR_ACCUM_NULL__, /* Time */ \ +} +static const struct combustion_pixel COMBUSTION_PIXEL_NULL = + COMBUSTION_PIXEL_NULL__; + +struct htrdr_combustion { + struct htrdr_geometry* geom; /* Combustion chamber geometry */ + struct htrdr_materials* mats; /* Materials of the combustion chamber */ + struct atrstm* medium; /* Semi transparent medium */ + + struct htrdr_camera* camera; /* Pinhole camera */ + struct htrdr_rectangle* laser; /* Laser surface emission */ + double wavelength; /* Wavelength of the laser in nanometer */ + + struct htrdr_args_image image; /* Image definition */ + struct htrdr_buffer_layout buf_layout; + struct htrdr_buffer* buf; /* NULL on non master processes */ + + FILE* output; /* Output stream */ + struct str output_name; /* Name of the output stream */ + int dump_volumetric_acceleration_structure; + + ref_T ref; + struct htrdr* htrdr; +}; + +extern LOCAL_SYM void +combustion_get_pixel_format + (const struct htrdr_combustion* cmd, + struct htrdr_pixel_format* fmt); + +#endif /* HTRDR_COMBUSTION_C_H */ diff --git a/src/combustion/htrdr_combustion_main.c b/src/combustion/htrdr_combustion_main.c @@ -18,6 +18,8 @@ #include "combustion/htrdr_combustion.h" #include "combustion/htrdr_combustion_args.h" +#include "core/htrdr.h" +#include "core/htrdr_args.h" #include "core/htrdr_log.h" #include <rsys/mem_allocator.h> @@ -26,21 +28,47 @@ int htrdr_combustion_main(int argc, char** argv) { char cmd_name[] = "htrdr-combustion"; + struct htrdr_args htrdr_args = HTRDR_ARGS_DEFAULT; struct htrdr_combustion_args cmd_args = HTRDR_COMBUSTION_ARGS_DEFAULT; + struct htrdr* htrdr = NULL; + struct htrdr_combustion* cmd = NULL; const size_t memsz_begin = MEM_ALLOCATED_SIZE(&mem_default_allocator); size_t memsz_end; + int is_mpi_init = 0; res_T res = RES_OK; int err = 0; /* Overwrite command name */ argv[0] = cmd_name; + res = htrdr_mpi_init(argc, argv); + if(res != RES_OK) goto error; + is_mpi_init = 1; + res = htrdr_combustion_args_init(&cmd_args, argc, argv); if(res != RES_OK) goto error; if(cmd_args.quit) goto exit; + htrdr_args.nthreads = cmd_args.nthreads; + htrdr_args.verbose = cmd_args.verbose; + res = htrdr_create(&mem_default_allocator, &htrdr_args, &htrdr); + if(res != RES_OK) goto error; + + if(cmd_args.dump_volumetric_acceleration_structure + && htrdr_get_mpi_rank(htrdr) != 0) { + goto exit; /* Nothing to do except for the master process */ + } + + res = htrdr_combustion_create(htrdr, &cmd_args, &cmd); + if(res != RES_OK) goto error; + + /* TODO run the command */ + exit: htrdr_combustion_args_release(&cmd_args); + if(is_mpi_init) htrdr_mpi_finalize(); + if(htrdr) htrdr_ref_put(htrdr); + if(cmd) htrdr_combustion_ref_put(cmd); /* Check memory leaks */ memsz_end = MEM_ALLOCATED_SIZE(&mem_default_allocator); diff --git a/src/core/htrdr_args.c b/src/core/htrdr_args.c @@ -23,6 +23,7 @@ #include <rsys/cstr.h> #include <rsys/double3.h> +#include <rsys/str.h> #include <string.h> @@ -329,25 +330,88 @@ error: } static res_T +parse_geometry_parameter(void* ptr, const char* str) +{ + struct str buf; + struct htrdr_args_geometry* geom = ptr; + char* key; + char* val; + char* ctx; + res_T res = RES_OK; + ASSERT(geom && str); + + str_init(NULL, &buf); + res = str_set(&buf, str); + if(res != RES_OK) { + fprintf(stderr, + "Could not duplicate the geometry option string `%s' -- %s.\n", + str, res_to_cstr(res)); + goto error; + } + + key = strtok_r(str_get(&buf), "=", &ctx); + val = strtok_r(NULL, "", &ctx); + + if(!val) { + fprintf(stderr, "Missing value to the geometry parameter `%s'.\n", key); + res = RES_BAD_ARG; + goto error; + } + + htrdr_args_geometry_free(geom); + + #define SET_VALUE(Key, Val, Str) { \ + const size_t len = strlen(Val) + 1; \ + Str = mem_alloc(len); \ + if(!Str) { \ + fprintf(stderr, \ + "Could not duplicate the value `%s' of the geometry parameter `%s'.\n",\ + (Val), (Key)); \ + res = RES_MEM_ERR; \ + goto error; \ + } \ + strncpy(Str, Val, len); \ + } (void)0 + if(!strcmp(key, "obj")) { + SET_VALUE(key, val, geom->path_obj); + } else if(!strcmp(key, "mats")) { + SET_VALUE(key, val, geom->path_mats); + } else { + fprintf(stderr, "Invalid geometry parameter `%s'.\n", key); + res = RES_BAD_ARG; + goto error; + } + #undef SET_VALUE + +exit: + str_release(&buf); + return res; +error: + htrdr_args_geometry_free(geom); + goto exit; +} + +static res_T parse_multiple_parameters (void* args, const char* str, res_T (*parse_parameter)(void* args, const char* str)) { - char buf[512]; + struct str buf; char* tk; char* ctx; res_T res = RES_OK; ASSERT(args && str); - if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + str_init(NULL, &buf); + res = str_set(&buf, str); + if(res != RES_OK) { fprintf(stderr, "Could not duplicate the option string `%s'.\n", str); res = RES_MEM_ERR; goto error; } - strncpy(buf, str, sizeof(buf)); - tk = strtok_r(buf, ":", &ctx); + tk = strtok_r(str_get(&buf), ":", &ctx); do { res = parse_parameter(args, tk); if(res != RES_OK) goto error; @@ -355,6 +419,7 @@ parse_multiple_parameters } while(tk); exit: + str_release(&buf); return res; error: goto exit; @@ -376,7 +441,7 @@ htrdr_args_rectangle_parse(struct htrdr_args_rectangle* rect, const char* str) if(!rect || !str) return RES_BAD_ARG; return parse_multiple_parameters(rect, str, parse_rectangle_parameter); } - + res_T htrdr_args_image_parse(struct htrdr_args_image* img, const char* str) { @@ -391,3 +456,44 @@ htrdr_args_spectral_parse(struct htrdr_args_spectral* spectral, const char* str) return parse_multiple_parameters(spectral, str, parse_spectral_parameter); } +void +htrdr_args_geometry_free(struct htrdr_args_geometry* geom) +{ + ASSERT(geom); + if(geom->path_obj) mem_rm(geom->path_obj); + if(geom->path_mats) mem_rm(geom->path_mats); + *geom = HTRDR_ARGS_GEOMETRY_NULL; +} + +res_T +htrdr_args_geometry_parse(struct htrdr_args_geometry* geom, const char* str) +{ + res_T res = RES_OK; + + if(!geom || !str) { + res = RES_BAD_ARG; + goto error; + } + + res = parse_multiple_parameters(geom, str, parse_geometry_parameter); + if(res != RES_OK) goto error; + + if(!geom->path_obj) { + fprintf(stderr, "Missing the `obj' geometry parameter.\n"); + res = RES_BAD_ARG; + goto error; + } + + if(!geom->path_mats) { + fprintf(stderr, "Missing the `mats' geometry parameter.\n"); + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + if(geom) htrdr_args_geometry_free(geom); + goto exit; +} + diff --git a/src/core/htrdr_args.h.in b/src/core/htrdr_args.h.in @@ -67,6 +67,15 @@ struct htrdr_args_image { static const struct htrdr_args_image HTRDR_ARGS_IMAGE_DEFAULT = HTRDR_ARGS_IMAGE_DEFAULT__; +/* Arguments of a geometry */ +struct htrdr_args_geometry { + char* path_obj; /* Path toward a htrdr-obj */ + char* path_mats; /* Path toward a htrdr-materials */ +}; +#define HTRDR_ARGS_GEOMETRY_NULL__ {NULL, NULL} +static const struct htrdr_args_geometry HTRDR_ARGS_GEOMETRY_NULL = + HTRDR_ARGS_GEOMETRY_NULL__; + /* Arguments of the spectral domain */ struct htrdr_args_spectral { double wlen_range[2]; /* Spectral range of integration in nm */ @@ -84,18 +93,18 @@ static const struct htrdr_args_spectral HTRDR_ARGS_SPECTRAL_DEFAULT = /******************************************************************************* * Exported functions ******************************************************************************/ -BEGIN_DECLS +BEGIN_DECLS HTRDR_CORE_API res_T htrdr_args_camera_parse - (struct htrdr_args_camera* cam, + (struct htrdr_args_camera* cam, const char* str); HTRDR_CORE_API res_T htrdr_args_rectangle_parse (struct htrdr_args_rectangle* rect, const char* str); - + HTRDR_CORE_API res_T htrdr_args_image_parse (struct htrdr_args_image* img, @@ -106,6 +115,15 @@ htrdr_args_spectral_parse (struct htrdr_args_spectral* spectral, const char* str); +HTRDR_CORE_API void +htrdr_args_geometry_free + (struct htrdr_args_geometry* geom); + +HTRDR_CORE_API res_T +htrdr_args_geometry_parse + (struct htrdr_args_geometry* geom, + const char* str); + END_DECLS #endif /* HTRDR_ARGS_H */ diff --git a/src/core/htrdr_buffer.h b/src/core/htrdr_buffer.h @@ -27,6 +27,14 @@ * Row major ordered 2D buffer */ +struct htrdr_pixel_format { + size_t size; /* In bytes */ + size_t alignment; /* Power of two, in Bytes */ +}; +#define HTRDR_PIXEL_FORMAT_NULL__ {0, 0} +static const struct htrdr_pixel_format HTRDR_PIXEL_FORMAT_NULL = + HTRDR_PIXEL_FORMAT_NULL__; + struct htrdr_buffer_layout { size_t width; /* #elements in X */ size_t height; /* #elements in Y */ diff --git a/src/core/htrdr_rectangle.c b/src/core/htrdr_rectangle.c @@ -50,7 +50,7 @@ rectangle_release(ref_T* ref) } /******************************************************************************* - * Local fuuction + * Exported functions ******************************************************************************/ res_T htrdr_rectangle_create