star-schiff

Library for estimating radiative properties
git clone git://git.meso-star.com/star-schiff.git
Log | Files | Refs | README | LICENSE

commit f383438b2f5de3c9e2fe98be37ed691c6fe452eb
parent eeee76acf3d587adfdcadd36c08444def80b684a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 13 Oct 2015 15:25:35 +0200

Update the schiff_integrate API

One can control the number of sampled geometries and the number of
sampled direction per geometry.

Diffstat:
Msrc/sschiff.h | 10++++++----
Msrc/sschiff_estimator.c | 62++++++++++++++++++++++++++++++++------------------------------
Msrc/test_sschiff_estimator_sphere.c | 50++++++++++++++++++++++++++++----------------------
3 files changed, 66 insertions(+), 56 deletions(-)

diff --git a/src/sschiff.h b/src/sschiff.h @@ -73,6 +73,7 @@ struct sschiff_material { static const struct sschiff_material SSCHIFF_NULL_MATERIAL = { NULL, NULL }; +/* Descriptor of an integration */ struct sschiff_integrator_desc { res_T (*sample_geometry) /* Sample a geometry i.e. a shape and its material */ (struct ssp_rng* rng, @@ -80,11 +81,14 @@ struct sschiff_integrator_desc { struct s3d_shape* shape, /* Sampled shape */ void* sampler_context); void* sampler_context; + double wavelength; /* Wavelenght to estimate */ size_t scattering_angles_count; /* # of scattering angles to handle */ + size_t sampled_geometries_count; /* # geometries to sample */ + size_t sampled_directions_count; /* # directions to sample per geometry */ }; static const struct sschiff_integrator_desc SSCHIFF_NULL_INTEGRATOR_DESC = { - NULL, NULL, 0 + NULL, NULL, 0, 0, 0, 0 }; /* Result of the Monte Carlo estimation */ @@ -92,7 +96,7 @@ struct sschiff_estimator_status { double E; /* Expected value */ double V; /* Variance */ double SE; /* Standard error */ - size_t nsteps; + size_t nsteps; /* # Monte Carlo weights */ }; /* Opaque types */ @@ -125,8 +129,6 @@ sschiff_integrate (struct sschiff_device* dev, struct ssp_rng* rng, struct sschiff_integrator_desc* desc, - const double wavelength, /* Wavelength to integrate */ - const size_t steps_count, /* #realisations */ struct sschiff_estimator** estimator); SSCHIFF_API res_T diff --git a/src/sschiff_estimator.c b/src/sschiff_estimator.c @@ -44,7 +44,7 @@ #include <math.h> -#define NDIRS 1 /* # Sampled directions */ +#define NDIRS 1000 /* # Sampled directions */ struct accum { double weight; @@ -53,7 +53,6 @@ struct accum { }; struct sschiff_estimator { - size_t nsteps; double wavelength; struct accum extinction_cross_section; @@ -125,7 +124,8 @@ build_transform static res_T compute_path_length - (struct s3d_scene* scn, + (struct sschiff_device* dev, + struct s3d_scene* scn, const struct s3d_hit* first_hit, const float ray_org[3], const float ray_dir[3], @@ -145,7 +145,10 @@ compute_path_length S3D(scene_trace_ray(scn, ray_org, ray_dir, range, &hit)); } while(S3D_PRIMITIVE_EQ(&hit.prim, &prim_from)); /* Self-intersection */ - if(S3D_HIT_NONE(&hit)) return RES_BAD_ARG; + if(S3D_HIT_NONE(&hit)) { + log_error(dev, "Error in computing the radiative path length.\n"); + return RES_BAD_ARG; + } len += hit.distance - range[0]; range[0] = hit.distance; @@ -167,7 +170,8 @@ compute_path_length static res_T compute_monte_carlo_weight - (struct s3d_scene* scn, + (struct sschiff_device* dev, + struct s3d_scene* scn, struct ssp_rng* rng, struct sschiff_material* mtl, const double wavelength, @@ -179,7 +183,6 @@ compute_monte_carlo_weight { struct s3d_hit hit; double sample[2]; - double weight; const float range[2] = { 0, FLT_MAX }; float axis_x[3], axis_y[3], axis_z[3]; float plane_size[2]; @@ -210,15 +213,14 @@ compute_monte_carlo_weight f3_add(ray_org, f3_add(ray_org, x, y), org); S3D(scene_trace_ray(scn, ray_org, axis_z, range, &hit)); - if(S3D_HIT_NONE(&hit)) { - weight = 0.0; - } else { + if(!S3D_HIT_NONE(&hit)) { struct sschiff_material_properties props; double n_r, k_r; double n_e, k_e, lambda_e; double path_length; + double weight; - res = compute_path_length(scn, &hit, ray_org, axis_z, &path_length); + res = compute_path_length(dev, scn, &hit, ray_org, axis_z, &path_length); if(res != RES_OK) goto error; mtl->get_property(mtl->material, wavelength, &props); @@ -232,10 +234,10 @@ compute_monte_carlo_weight weight = 2.0 * rcp_pdf * (1.0 - exp(-k_e*k_r*path_length) * cos(k_e*(n_r - 1.0)*path_length)); - } - accum->weight += weight; - accum->sqr_weight += weight * weight; + accum->weight += weight; + accum->sqr_weight += weight * weight; + } accum->naccums += 1; exit: @@ -323,7 +325,6 @@ radiative_properties (struct sschiff_device* dev, struct ssp_rng* rng, struct sschiff_integrator_desc* desc, - const double wavelength, const int istep, struct s3d_scene* scene, struct s3d_shape* shape, @@ -333,7 +334,8 @@ radiative_properties float lower[3], upper[3]; float aabb_pt[8][3]; float centroid[3]; - int idir; + size_t idir; + int mask; res_T res = RES_OK; ASSERT(dev && rng && desc && accum); @@ -364,7 +366,7 @@ radiative_properties f3_mulf(centroid, f3_add(centroid, lower, upper), 0.5f); - FOR_EACH(idir, 0, NDIRS) { + FOR_EACH(idir, 0, desc->sampled_directions_count) { float dir[4]; float basis[9]; float transform[12]; @@ -392,14 +394,13 @@ radiative_properties #if 1 (void)istep; - res = compute_monte_carlo_weight - (scene, rng, &material, wavelength, basis, centroid, lower, upper, accum); - if(res != RES_OK) goto error; + res = compute_monte_carlo_weight(dev, scene, rng, &material, + desc->wavelength, basis, centroid, lower, upper, accum); + /*if(res != RES_OK) goto error;*/ #else /* Compute an image of the shape transformed in the footprint space */ { char thumb_name[64]; - (void)wavelength; sprintf(thumb_name, "%d_%d.ppm", istep, idir); draw_thumbnail(scene, basis, centroid, lower, upper, thumb_name); } @@ -408,6 +409,8 @@ radiative_properties S3D(scene_end_session(scene)); exit: + S3D(scene_get_session_mask(scene, &mask)); + if(mask) S3D(scene_end_session(scene)); return res; error: goto exit; @@ -418,7 +421,10 @@ check_desc(struct sschiff_integrator_desc* desc) { ASSERT(desc); return desc->sample_geometry - && desc->scattering_angles_count; + && desc->scattering_angles_count + && desc->sampled_geometries_count + && desc->sampled_directions_count + && desc->wavelength > 0.f; } static void @@ -471,26 +477,22 @@ sschiff_integrate (struct sschiff_device* dev, struct ssp_rng* rng, struct sschiff_integrator_desc* desc, - const double wavelength, /* Wavelength to integrate */ - const size_t steps_count, /* #realisations */ struct sschiff_estimator** out_estimator) { struct sschiff_estimator* estimator = NULL; struct s3d_shape* shape = NULL; struct s3d_scene* scene = NULL; - int i; + size_t i; res_T res = RES_OK; - if(!dev || !rng || !desc || !check_desc(desc) || wavelength < 0.0 - || !steps_count || !out_estimator) { + if(!dev || !rng || !desc || !check_desc(desc) || !out_estimator) { res = RES_BAD_ARG; goto error; } res = estimator_create(dev, &estimator); if(res != RES_OK) goto error; - estimator->nsteps = steps_count; - estimator->wavelength = wavelength; + estimator->wavelength = desc->wavelength; res = s3d_shape_create_mesh(dev->s3d, &shape); if(res != RES_OK) { @@ -510,8 +512,8 @@ sschiff_integrate } memset(&estimator->extinction_cross_section, 0, sizeof(struct accum)); - FOR_EACH(i, 0, (int)steps_count) { - res = radiative_properties(dev, rng, desc, wavelength, i, scene, shape, + FOR_EACH(i, 0, desc->sampled_geometries_count) { + res = radiative_properties(dev, rng, desc, (int)i, scene, shape, &estimator->extinction_cross_section); if(res != RES_OK) goto error; } diff --git a/src/test_sschiff_estimator_sphere.c b/src/test_sschiff_estimator_sphere.c @@ -36,8 +36,6 @@ #include <star/s3d.h> #include <star/ssp.h> -#define NSTEPS 1000 - struct result { double mean_radius; double extinction_cross_section; @@ -252,6 +250,9 @@ check_schiff_estimation desc.sample_geometry = sample_sphere; desc.scattering_angles_count = 1; desc.sampler_context = sampler_ctx; + desc.sampled_geometries_count = 500; + desc.sampled_directions_count = 5; + desc.wavelength = 6.e-7; printf("Schiff sphere estimation - m: %g; n_r: %g; kappa_r: %g; n_e: %g\n", sampler_ctx->wavelength, @@ -263,11 +264,13 @@ check_schiff_estimation sampler_ctx->mean_radius = results[i].mean_radius; time_current(&t0); - CHECK(sschiff_integrate(dev, rng, &desc, 6.e-7, NSTEPS, &estimator), RES_OK); + CHECK(sschiff_integrate(dev, rng, &desc, &estimator), RES_OK); time_current(&t1); CHECK(sschiff_estimator_get_extinction_cross_section(estimator, &status), RES_OK); + + time_sub(&t0, &t1, &t0); time_dump(&t0, TIME_MIN|TIME_SEC|TIME_MSEC, NULL, buf, sizeof(buf)); printf( @@ -280,7 +283,7 @@ check_schiff_estimation status.E, status.SE, buf); - CHECK(eq_eps(status.E, results[i].extinction_cross_section, 2*status.SE), 1); + CHECK(eq_eps(status.E, results[i].extinction_cross_section, 3*status.SE), 1); CHECK(sschiff_estimator_ref_put(estimator), RES_OK); } } @@ -335,25 +338,28 @@ main(int argc, char** argv) sampler_ctx.mean_radius = 1.0; desc.sample_geometry = sample_sphere; - desc.scattering_angles_count = 1; desc.sampler_context = &sampler_ctx; - - CHECK(sschiff_integrate(NULL, NULL, NULL, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &desc, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &desc, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &desc, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &desc, 6e-7, 0, NULL), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, NULL, 6e-7, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, NULL, 6e-7, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, NULL, 6e-7, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, NULL, 6e-7, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, NULL, &desc, 6e-7, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, NULL, &desc, 6e-7, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(NULL, rng, &desc, 6e-7, 1, &estimator), RES_BAD_ARG); - CHECK(sschiff_integrate(dev, rng, &desc, 6e-7, 1, &estimator), RES_OK); + desc.wavelength = sampler_ctx.wavelength; + desc.scattering_angles_count = 1; + desc.sampled_geometries_count = 1; + desc.sampled_directions_count = 1; + + CHECK(sschiff_integrate(NULL, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &desc, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &desc, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &desc, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &desc, NULL), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, NULL, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, NULL, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, NULL, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, NULL, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, NULL, &desc, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, NULL, &desc, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(NULL, rng, &desc, &estimator), RES_BAD_ARG); + CHECK(sschiff_integrate(dev, rng, &desc, &estimator), RES_OK); CHECK(sschiff_estimator_get_extinction_cross_section(NULL, NULL), RES_BAD_ARG); CHECK(sschiff_estimator_get_extinction_cross_section(estimator, NULL), RES_BAD_ARG);