commit 8240840d2b1d1e3bf22bdbd245da8c73cbf987be
parent 10e2d67427b685828bea7b84a1e1446982f89fa3
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 24 Mar 2021 18:22:42 +0100
Update the laser API
Add wavelength and flux density to the laser parameters. Add the
htrdr_combustion_laser_get_mesh, htrdr_combustion_laser_get_direction
and htrdr_combustion_laser_compute_surface_plane_distance functions.
Diffstat:
5 files changed, 222 insertions(+), 24 deletions(-)
diff --git a/src/combustion/htrdr_combustion.c b/src/combustion/htrdr_combustion.c
@@ -139,6 +139,8 @@ setup_laser
ASSERT(cmd && args);
cmd->wavelength = args->wavelength;
laser_args.surface = args->laser;
+ laser_args.wavelength = args->wavelength;
+ laser_args.flux_density = args->laser_flux_density;
return htrdr_combustion_laser_create(cmd->htrdr, &laser_args, &cmd->laser);
}
@@ -193,7 +195,7 @@ setup_medium
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_prefactor = args->fractal_prefactor;
atrstm_args.fractal_dimension = args->fractal_dimension;
atrstm_args.optical_thickness = args->optical_thickness;
atrstm_args.precompute_normals = args->precompute_normals;
diff --git a/src/combustion/htrdr_combustion_args.c b/src/combustion/htrdr_combustion_args.c
@@ -15,10 +15,14 @@
* 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 "combustion/htrdr_combustion_args.h"
#include <rsys/cstr.h>
+
#include <getopt.h>
+#include <string.h>
/*******************************************************************************
* Helper functions
@@ -38,19 +42,26 @@ print_help(const char* cmd)
" -C <camera> define the rendering point of view. Refer to the\n"
" %s man page for the list of camera options.\n", cmd);
printf(
+" -D FLUX_DENSITY\n"
+" flux density of the laser in W/m^2. By default the\n"
+" 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");
printf(
-" -F FRACTAL_DIM value of the fractal dimension to use in the RDG-FA\n"
-" model. Its default value is %g.\n",
+" -F <fractal-coefs>"
+" value of the fractal prefactor and fractal dimension\n"
+" to use in the RDG-FA model. Refer to the %s man page\n"
+" for the syntax of the <fractal-coefs> option. Default\n"
+" fractal prefactor is %g and the default fractal\n"
+" dimension is %g.\n",
+ cmd,
+ HTRDR_COMBUSTION_ARGS_DEFAULT.fractal_prefactor,
HTRDR_COMBUSTION_ARGS_DEFAULT.fractal_dimension);
printf(
" -f overwrite the OUTPUT file if it already exists.\n");
printf(
-" -G PREFACTOR value gyration radius prefactor to use in the RDG-FA\n"
-" model. Its default value is %g.\n",
- HTRDR_COMBUSTION_ARGS_DEFAULT.gyration_radius_prefactor);
- printf(
" -g <geometry> define the combustion chamber geometry. Refer to the\n"
" %s man page for the list of geometry options.\n", cmd);
printf(
@@ -147,6 +158,46 @@ error:
goto exit;
}
+static res_T
+parse_fractal_parameters(const char* str, void* ptr)
+{
+ char buf[128];
+ struct htrdr_combustion_args* args = ptr;
+ char* key;
+ char* val;
+ char* ctx;
+ res_T res = RES_OK;
+ ASSERT(ptr && str);
+
+ if(strlen(str) >= sizeof(buf) -1/*NULL char*/) {
+ fprintf(stderr,
+ "Could not duplicate the fractal option string `%s'.\n", str);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ strncpy(buf, str, sizeof(buf));
+
+ key = strtok_r(buf, "=", &ctx);
+ val = strtok_r(NULL, "", &ctx);
+
+ if(!strcmp(key, "prefactor")) {
+ res = cstr_to_double(val, &args->fractal_prefactor);
+ if(res != RES_OK) goto error;
+ } else if(!strcmp(key, "dimension")) {
+ res = cstr_to_double(val, &args->fractal_dimension);
+ if(res != RES_OK) goto error;
+ } else {
+ fprintf(stderr, "Invalid fractal parameter `%s'.\n", key);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -162,25 +213,22 @@ htrdr_combustion_args_init
*args = HTRDR_COMBUSTION_ARGS_DEFAULT;
- while((opt = getopt(argc, argv, "C:dF:fG:g:hi:l:m:NO:o:p:r:T:t:V:vw:")) != -1) {
+ while((opt = getopt(argc, argv, "C:D:dF: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);
break;
+ case 'D':
+ res = cstr_to_double(optarg, &args->laser_flux_density);
+ if(res == RES_OK && args->laser_flux_density <= 0) res = RES_BAD_ARG;
+ break;
case 'd':
args->dump_volumetric_acceleration_structure = 1;
break;
case 'F':
- res = cstr_to_double(optarg, &args->fractal_dimension);
- if(res == RES_OK && args->fractal_dimension <= 0)
- res = RES_BAD_ARG;
+ res = cstr_parse_list(optarg, ':', parse_fractal_parameters, args);
break;
case 'f': args->force_overwriting = 1; break;
- case 'G':
- res = cstr_to_double(optarg, &args->gyration_radius_prefactor);
- if(res == RES_OK && args->gyration_radius_prefactor <= 0)
- res = RES_BAD_ARG;
- break;
case 'g':
res = htrdr_args_geometry_parse(&args->geom, optarg);
break;
diff --git a/src/combustion/htrdr_combustion_args.h b/src/combustion/htrdr_combustion_args.h
@@ -58,11 +58,12 @@ struct htrdr_combustion_args {
struct htrdr_args_rectangle laser; /* Laser surface emission */
double wavelength; /* Wavelength of the laser in nanometer */
+ double laser_flux_density; /* In W/m^2 */
struct htrdr_args_image image; /* Output Image */
/* RDG-FA parameters */
- double gyration_radius_prefactor;
+ double fractal_prefactor;
double fractal_dimension;
struct htrdr_combustion_args_grid_definition grid;
@@ -92,6 +93,7 @@ struct htrdr_combustion_args {
\
HTRDR_ARGS_RECTANGLE_DEFAULT__, /* Laser surface emission */ \
532, /* Wavelength in nanometer */ \
+ 1, /* FIXME Flux density */ \
\
HTRDR_ARGS_IMAGE_DEFAULT__, /* Image */ \
\
diff --git a/src/combustion/htrdr_combustion_laser.c b/src/combustion/htrdr_combustion_laser.c
@@ -30,6 +30,8 @@ struct htrdr_combustion_laser {
struct htrdr_rectangle* surface; /* Surface emission */
double world2local[12];
double low_ls[3], upp_ls[3]; /* Local space AABB */
+ double flux_density; /* In W/m^2 */
+ double wavelength; /* In nm */
ref_T ref;
struct htrdr* htrdr;
};
@@ -63,15 +65,29 @@ htrdr_combustion_laser_create
res_T res = RES_OK;
ASSERT(htrdr && args && out_laser);
+ if(args->flux_density <= 0) {
+ htrdr_log_err(htrdr, "Invalid flux density %g W.m^2\n", args->flux_density);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(args->wavelength <= 0) {
+ htrdr_log_err(htrdr, "Invalid wavelength %g nm\n", args->wavelength);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
laser = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*laser));
if(!laser) {
htrdr_log_err(htrdr, "Could not allocate the laser data structure.\n");
- res = RES_BAD_ARG;
+ res = RES_MEM_ERR;
goto error;
}
ref_init(&laser->ref);
htrdr_ref_get(htrdr);
laser->htrdr = htrdr;
+ laser->flux_density = args->flux_density;
+ laser->wavelength = args->wavelength;
res = htrdr_rectangle_create
(laser->htrdr,
@@ -93,7 +109,7 @@ htrdr_combustion_laser_create
laser->upp_ls[1] = args->surface.size[1] * 0.5;
laser->upp_ls[2] = 0;
laser->low_ls[0] = -laser->upp_ls[0];
- laser->low_ls[2] = -laser->upp_ls[1];
+ laser->low_ls[1] = -laser->upp_ls[1];
laser->upp_ls[2] = INF;
exit:
@@ -163,3 +179,88 @@ htrdr_combustion_laser_trace_ray
distance[1] = t_max;
}
+void
+htrdr_combustion_laser_get_mesh
+ (const struct htrdr_combustion_laser* laser,
+ const double extend,
+ struct htrdr_combustion_laser_mesh* mesh)
+{
+ double transform[12];
+ double low[3];
+ double upp[3];
+ ASSERT(laser && extend > 0 && mesh);
+
+ htrdr_rectangle_get_transform(laser->surface, transform);
+
+ /* Define the laser sheet vertices in local space */
+ low[0] = laser->low_ls[0];
+ low[1] = laser->low_ls[1];
+ low[2] = laser->low_ls[2];
+ upp[0] = laser->upp_ls[0];
+ upp[1] = laser->upp_ls[1];
+ upp[2] = laser->low_ls[2] + extend;
+
+ /* Transform the laser sheet vertices in world space */
+ d3(mesh->vertices + 0*3, low[0], low[1], low[2]);
+ d3(mesh->vertices + 1*3, upp[0], low[1], low[2]);
+ d3(mesh->vertices + 2*3, low[0], upp[1], low[2]);
+ d3(mesh->vertices + 3*3, upp[0], upp[1], low[2]);
+ d3(mesh->vertices + 4*3, low[0], low[1], upp[2]);
+ d3(mesh->vertices + 5*3, upp[0], low[1], upp[2]);
+ d3(mesh->vertices + 6*3, low[0], upp[1], upp[2]);
+ d3(mesh->vertices + 7*3, upp[0], upp[1], upp[2]);
+ mesh->nvertices = 8;
+
+ /* Define the laser sheet triangles */
+ mesh->triangles[0] = 0; mesh->triangles[1] = 2; mesh->triangles[2] = 1;
+ mesh->triangles[3] = 1; mesh->triangles[4] = 2; mesh->triangles[5] = 3;
+ mesh->triangles[6] = 0; mesh->triangles[7] = 4; mesh->triangles[8] = 2;
+ mesh->triangles[9] = 2; mesh->triangles[10] = 4; mesh->triangles[11] = 6;
+ mesh->triangles[12] = 1; mesh->triangles[13] = 3; mesh->triangles[14] = 5;
+ mesh->triangles[15] = 5; mesh->triangles[16] = 3; mesh->triangles[17] = 7;
+ mesh->triangles[18] = 1; mesh->triangles[19] = 5; mesh->triangles[20] = 0;
+ mesh->triangles[21] = 0; mesh->triangles[22] = 5; mesh->triangles[23] = 4;
+ mesh->triangles[24] = 3; mesh->triangles[25] = 2; mesh->triangles[26] = 7;
+ mesh->triangles[27] = 7; mesh->triangles[28] = 2; mesh->triangles[29] = 6;
+ mesh->ntriangles = 10;
+}
+
+void
+htrdr_combustion_laser_get_direction
+ (const struct htrdr_combustion_laser* laser,
+ double dir[3])
+{
+ ASSERT(laser && dir);
+ htrdr_rectangle_get_normal(laser->surface, dir);
+}
+
+double
+htrdr_combustion_laser_get_flux_density
+ (const struct htrdr_combustion_laser* laser)
+{
+ ASSERT(laser);
+ return laser->flux_density;
+}
+
+double
+htrdr_combustion_laser_get_wavelength
+ (const struct htrdr_combustion_laser* laser)
+{
+ ASSERT(laser);
+ return laser->wavelength;
+}
+
+double
+htrdr_combustion_laser_compute_surface_plane_distance
+ (const struct htrdr_combustion_laser* laser,
+ const double pos[3])
+{
+ double center[3];
+ double normal[3];
+ double vec[3];
+ ASSERT(laser && pos);
+ htrdr_rectangle_get_normal(laser->surface, normal);
+ htrdr_rectangle_get_center(laser->surface, center);
+ d3_sub(vec, pos, center);
+ return d3_dot(normal, vec);
+}
diff --git a/src/combustion/htrdr_combustion_laser.h b/src/combustion/htrdr_combustion_laser.h
@@ -22,35 +22,53 @@
#include <rsys/rsys.h>
+/* Monochromatic laser */
struct htrdr_combustion_laser_create_args {
struct htrdr_args_rectangle surface; /* Surface emission */
+ double wavelength; /* In nanometers */
+ double flux_density; /* In W/m^2 */
};
#define HTRDR_COMBUSTION_LASER_CREATE_ARGS_DEFAULT__ { \
- HTRDR_ARGS_RECTANGLE_DEFAULT__ \
+ HTRDR_ARGS_RECTANGLE_DEFAULT__, \
+ -1, /* Wavelength */ \
+ -1, /* Flux density */ \
}
static const struct htrdr_combustion_laser_create_args
HTRDR_COMBUSTION_LASER_CREATE_ARGS_DEFAULT =
HTRDR_COMBUSTION_LASER_CREATE_ARGS_DEFAULT__;
+struct htrdr_combustion_laser_mesh {
+ double vertices[8/*#vertices*/*3/*#coords per vertex*/];
+ /* Triangle are clock wise ordered from the inside of the laser sheet */
+ unsigned triangles[10/*#triangles*/*3/*#vertices per triangle*/];
+ unsigned nvertices;
+ unsigned ntriangles;
+};
+
+/* Syntactic sugar to check if a laser sheet hit is valid */
+#define HTRDR_COMBUSTION_LASER_HIT_NONE(Hit) ((Hit)[0] >= DBL_MAX)
+
/* Forward declaration */
struct htrdr;
struct htrdr_combustion_laser;
-extern LOCAL_SYM res_T
+BEGIN_DECLS
+
+HTRDR_API res_T
htrdr_combustion_laser_create
(struct htrdr* htrdr,
const struct htrdr_combustion_laser_create_args* args,
struct htrdr_combustion_laser** laser);
-extern LOCAL_SYM void
+HTRDR_API void
htrdr_combustion_laser_ref_get
(struct htrdr_combustion_laser* laser);
-extern LOCAL_SYM void
+HTRDR_API void
htrdr_combustion_laser_ref_put
(struct htrdr_combustion_laser* laser);
-extern LOCAL_SYM void
+HTRDR_API void
htrdr_combustion_laser_trace_ray
(struct htrdr_combustion_laser* laser,
const double pos[3],
@@ -58,4 +76,31 @@ htrdr_combustion_laser_trace_ray
const double range[2],
double distance[2]);
+HTRDR_API void
+htrdr_combustion_laser_get_mesh
+ (const struct htrdr_combustion_laser* laser,
+ /* Max distance of the laser mesh along its infinite dimension */
+ const double extend,
+ struct htrdr_combustion_laser_mesh* mesh);
+
+HTRDR_API void
+htrdr_combustion_laser_get_direction
+ (const struct htrdr_combustion_laser* laser,
+ double dir[3]); /* Normalized */
+
+HTRDR_API double /* In W.m^2 */
+htrdr_combustion_laser_get_flux_density
+ (const struct htrdr_combustion_laser* laser);
+
+HTRDR_API double /* In nm */
+htrdr_combustion_laser_get_wavelength
+ (const struct htrdr_combustion_laser* laser);
+
+HTRDR_API double
+htrdr_combustion_laser_compute_surface_plane_distance
+ (const struct htrdr_combustion_laser* laser,
+ const double pos[3]);
+
+END_DECLS
+
#endif /* HTRDR_COMBUSTION_LASER_H */