htrdr

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

commit 2f750b569caaadd75b76420ca50a8a07cb66b81d
parent 9f8f4c9b826a21cbd9de12cfb2a8222eeea6f8c9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 23 Apr 2021 17:27:52 +0200

Add writing of the geometry of the laser sheet

Diffstat:
Msrc/combustion/htrdr_combustion.c | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/combustion/htrdr_combustion_args.c | 33+++++++++++++++++++++++++++++----
Msrc/combustion/htrdr_combustion_args.h | 13++++++++++---
Msrc/combustion/htrdr_combustion_c.h | 4+++-
Msrc/combustion/htrdr_combustion_main.c | 2+-
5 files changed, 159 insertions(+), 18 deletions(-)

diff --git a/src/combustion/htrdr_combustion.c b/src/combustion/htrdr_combustion.c @@ -218,7 +218,7 @@ setup_buffer res_T res = RES_OK; ASSERT(cmd && args); - if(cmd->dump_volumetric_acceleration_structure) goto exit; + if(cmd->output_type != HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE) goto exit; combustion_get_pixel_format(cmd, &pixfmt); @@ -318,6 +318,106 @@ error: goto exit; } +static double +compute_laser_mesh_extent(const struct htrdr_combustion* cmd) +{ + double mdm_upp[3]; + double mdm_low[3]; + double laser_dir[3]; + double laser_pos[3]; + double t[2]; + int max_axis; + ASSERT(cmd); + + /* Retrieve the medium axis aligned bounding box */ + atrstm_get_aabb(cmd->medium, mdm_low, mdm_upp); + + /* Retrieve laser parameters */ + htrdr_combustion_laser_get_position(cmd->laser, laser_pos); + htrdr_combustion_laser_get_direction(cmd->laser, laser_dir); + + /* Compute the dominant axis of the laser direction */ + max_axis = + fabs(laser_dir[0]) > fabs(laser_dir[1]) + ? (fabs(laser_dir[0]) > fabs(laser_dir[2]) ? 0 : 2) + : (fabs(laser_dir[1]) > fabs(laser_dir[2]) ? 1 : 2); + + /* Define the intersection of the laser along its dominant axis with the + * medium bounds along this axis */ + t[0] = (mdm_low[max_axis] - laser_pos[max_axis]) / laser_dir[max_axis]; + t[1] = (mdm_upp[max_axis] - laser_pos[max_axis]) / laser_dir[max_axis]; + if(t[0] > t[1]) SWAP(double, t[0], t[1]); + + /* Use the far intersection distance as the extent of the laser mesh */ + return t[1]; +} + +static res_T +dump_laser_sheet(const struct htrdr_combustion* cmd) +{ + struct htrdr_combustion_laser_mesh laser_mesh; + double extent; + unsigned i; + res_T res = RES_OK; + ASSERT(cmd); + + /* Compute the extent of the geometry that will represent the laser sheet */ + extent = compute_laser_mesh_extent(cmd); + + /* Retreive the mesh of the laser sheet */ + htrdr_combustion_laser_get_mesh(cmd->laser, extent, &laser_mesh); + + #define FPRINTF(Fmt, Args) { \ + const int err = fprintf(cmd->output, Fmt COMMA_##Args LIST_##Args); \ + if(err < 0) { \ + htrdr_log_err(cmd->htrdr, "Error writing data to `%s'.\n", \ + str_cget(&cmd->output_name)); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + + /* Write header */ + FPRINTF("# vtk DataFile Version 2.0\n", ARG0()); + FPRINTF("Laser sheet\n", ARG0()); + FPRINTF("ASCII\n", ARG0()); + FPRINTF("DATASET POLYDATA\n", ARG0()); + + /* Write the vertices */ + FPRINTF("POINTS %u double\n", ARG1(laser_mesh.nvertices)); + FOR_EACH(i, 0, laser_mesh.nvertices) { + FPRINTF("%g %g %g\n", ARG3 + (laser_mesh.vertices[i*3+0], + laser_mesh.vertices[i*3+1], + laser_mesh.vertices[i*3+2])); + } + + /* Write the triangles */ + FPRINTF("POLYGONS %u %u\n",ARG2 + (laser_mesh.ntriangles, + laser_mesh.ntriangles*4)); + FOR_EACH(i, 0, laser_mesh.ntriangles) { + FPRINTF("3 %u %u %u\n", ARG3 + (laser_mesh.triangles[i*3+0], + laser_mesh.triangles[i*3+1], + laser_mesh.triangles[i*3+2])); + } + + /* Write flux density */ + FPRINTF("CELL_DATA %u\n", ARG1(laser_mesh.ntriangles)); + FPRINTF("SCALARS Flux_density double 1\n", ARG0()); + FPRINTF("LOOKUP_TABLE default\n", ARG0()); + FOR_EACH(i, 0, laser_mesh.ntriangles) { + FPRINTF("%g\n", ARG1(htrdr_combustion_laser_get_flux_density(cmd->laser))); + } + #undef FPRINTF + +exit: + return res; +error: + goto exit; +} + static void combustion_release(ref_T* ref) { @@ -368,8 +468,7 @@ htrdr_combustion_create cmd->htrdr = htrdr; cmd->spp = args->image.spp; - cmd->dump_volumetric_acceleration_structure = - args->dump_volumetric_acceleration_structure; + cmd->output_type = args->output_type; res = setup_output(cmd, args); if(res != RES_OK) goto error; @@ -419,12 +518,20 @@ htrdr_combustion_run(struct htrdr_combustion* cmd) res_T res = RES_OK; ASSERT(cmd); - if(cmd->dump_volumetric_acceleration_structure) { - res = dump_volumetric_acceleration_structure(cmd); - if(res != RES_OK) goto error; - } else { - res = combustion_draw_map(cmd); - if(res != RES_OK) goto error; + switch(cmd->output_type) { + case HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE: + res = combustion_draw_map(cmd); + break; + case HTRDR_COMBUSTION_ARGS_OUTPUT_LASER_SHEET: + res = dump_laser_sheet(cmd); + break; + case HTRDR_COMBUSTION_ARGS_OUTPUT_OCTREES: + res = dump_volumetric_acceleration_structure(cmd); + break; + default: FATAL("Unreachable code.\n"); break; + } + if(res != RES_OK) { + goto error; } exit: diff --git a/src/combustion/htrdr_combustion_args.c b/src/combustion/htrdr_combustion_args.c @@ -47,8 +47,9 @@ print_help(const char* cmd) " flux density is %g W/m^2.\n", HTRDR_COMBUSTION_ARGS_DEFAULT.laser_flux_density); printf( -" -d dump volumetric acceleration structures to OUTPUT\n" -" and exit.\n"); +" -d <octrees|laser>\n" +" output the volumetric acceleration structures or the\n" +" the geometry of the laser sheet and exit.\n"); printf( " -F <fractal-coefs>\n" " value of the fractal prefactor and fractal dimension\n" @@ -197,6 +198,30 @@ error: goto exit; } +static res_T +parse_dump_parameter + (const char* str, + enum htrdr_combustion_args_output_type* output_type) +{ + res_T res = RES_OK; + ASSERT(str && output_type); + + if(!strcmp(str, "octrees")) { + *output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_OCTREES; + } else if(!strcmp(str, "laser")) { + *output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_LASER_SHEET; + } else { + fprintf(stderr, "Invalid dump parameter `%s'.\n", str); + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -212,7 +237,7 @@ htrdr_combustion_args_init *args = HTRDR_COMBUSTION_ARGS_DEFAULT; - while((opt = getopt(argc, argv, "C:D:dF:fg:hi:l:m:NO:o:p:r:T:t:V:vw:")) != -1) { + while((opt = getopt(argc, argv, "C:D:d:F:fg:hi:l:m:NO:o:p:r:T:t:V:vw:")) != -1) { switch(opt) { case 'C': res = htrdr_args_camera_parse(&args->camera, optarg); @@ -222,7 +247,7 @@ htrdr_combustion_args_init if(res == RES_OK && args->laser_flux_density <= 0) res = RES_BAD_ARG; break; case 'd': - args->dump_volumetric_acceleration_structure = 1; + res = parse_dump_parameter(optarg, &args->output_type); break; case 'F': res = cstr_parse_list(optarg, ':', parse_fractal_parameters, args); diff --git a/src/combustion/htrdr_combustion_args.h b/src/combustion/htrdr_combustion_args.h @@ -23,9 +23,16 @@ #include <limits.h> /* UINT_MAX support */ +enum htrdr_combustion_args_output_type { + HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE, + HTRDR_COMBUSTION_ARGS_OUTPUT_LASER_SHEET, + HTRDR_COMBUSTION_ARGS_OUTPUT_OCTREES, + HTRDR_COMBUSTION_ARGS_OUTPUT_TYPES_COUNT__ +}; + enum htrdr_combustion_args_grid_definition_type { - HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_FIXED, HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_AUTO, + HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_FIXED, HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_TYPES_COUNT__ }; @@ -72,9 +79,9 @@ struct htrdr_combustion_args { /* Miscellaneous parameters */ unsigned nthreads; /* Hint on the number of threads to use */ + enum htrdr_combustion_args_output_type output_type; int precompute_normals; /* Pre-compute the tetrahedra normals */ int force_overwriting; - int dump_volumetric_acceleration_structure; int verbose; /* Verbosity level */ int quit; /* Stop the command */ }; @@ -105,9 +112,9 @@ struct htrdr_combustion_args { 1, /* Optical thickness */ \ \ UINT_MAX, /* #threads */ \ + HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE, /* Output type */ \ 0, /* Precompute normals */ \ 0, /* Force overwriting */ \ - 0, /* dump volumetric acceleration structure */ \ 0, /* Verbose flag */ \ 0 /* Stop the command */ \ } diff --git a/src/combustion/htrdr_combustion_c.h b/src/combustion/htrdr_combustion_c.h @@ -18,6 +18,8 @@ #ifndef HTRDR_COMBUSTION_C_H #define HTRDR_COMBUSTION_C_H +#include "combustion/htrdr_combustion_args.h" + #include "core/htrdr_accum.h" #include "core/htrdr_args.h" #include "core/htrdr_buffer.h" @@ -65,7 +67,7 @@ struct htrdr_combustion { FILE* output; /* Output stream */ struct str output_name; /* Name of the output stream */ - int dump_volumetric_acceleration_structure; + enum htrdr_combustion_args_output_type output_type; /* Type of output data */ ref_T ref; struct htrdr* htrdr; diff --git a/src/combustion/htrdr_combustion_main.c b/src/combustion/htrdr_combustion_main.c @@ -54,7 +54,7 @@ htrdr_combustion_main(int argc, char** argv) res = htrdr_create(&mem_default_allocator, &htrdr_args, &htrdr); if(res != RES_OK) goto error; - if(cmd_args.dump_volumetric_acceleration_structure + if(cmd_args.output_type != HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE && htrdr_get_mpi_rank(htrdr) != 0) { goto exit; /* Nothing to do except for the master process */ }