star-schiff

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

commit 7d369dadd6c16daaf06a5f400d84632bc94e1d57
parent 15eab01084012d7c9ca042601f61ecbeb04fa1b0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Sat, 21 Sep 2019 15:28:07 +0200

Upd the schiff_geometry_distribution API

Split the "sample" function in 2 functions. The sample function samples
the shape of the geometry only. Its volume scaling is now sampled
through the sample_volume_scaling function. Thanks to this split, the
volume scaling is sampled at the same frequency that the orientation,
i.e. several times per sampled geometry.

Diffstat:
Msrc/sschiff.h | 7+++++--
Msrc/sschiff_estimator.c | 55++++++++++++++++++++++++++++++++-----------------------
Msrc/test_sschiff_estimator_cylinder.c | 19+++++++++++++++----
Msrc/test_sschiff_estimator_rhodo.c | 15+++++++++++++--
Msrc/test_sschiff_estimator_sphere.c | 3---
5 files changed, 65 insertions(+), 34 deletions(-)

diff --git a/src/sschiff.h b/src/sschiff.h @@ -70,16 +70,19 @@ static const struct sschiff_material SSCHIFF_NULL_MATERIAL = { NULL, NULL }; struct sschiff_geometry_distribution { struct sschiff_material material; /* Material of the geometry distribution */ double characteristic_length; - res_T (*sample) /* Sample a geometry i.e. a shape and its material */ + res_T (*sample) /* Sample a geometry i.e. a shape */ (struct ssp_rng* rng, struct s3d_shape* shape, /* Sampled shape */ + void* context); + res_T (*sample_volume_scaling) /* Can be NULL <=> No volume scaling */ + (struct ssp_rng* rng, double* scale_factor, /* Scale factor to apply to the shape volume */ void* context); void* context; }; static const struct sschiff_geometry_distribution -SSCHIFF_NULL_GEOMETRY_DISTRIBUTION = { {NULL, NULL}, -1.0, NULL, NULL }; +SSCHIFF_NULL_GEOMETRY_DISTRIBUTION = { {NULL, NULL}, -1.0, NULL, NULL, NULL }; /* State of the Monte Carlo estimation */ struct sschiff_state { diff --git a/src/sschiff_estimator.c b/src/sschiff_estimator.c @@ -498,8 +498,7 @@ radiative_properties (struct sschiff_device* dev, const int istep, const size_t ndirs, - const double area_scaling, /* Scale factor to apply to the areas */ - const double dist_scaling, /* Scale factor to apply to the distances */ + struct sschiff_geometry_distribution* distrib, struct integrator_context* ctx) { float lower[3], upper[3]; @@ -509,7 +508,7 @@ radiative_properties size_t iwlen; int i; res_T res = RES_OK; - ASSERT(dev && ndirs && ctx && area_scaling > 0 && dist_scaling > 0); + ASSERT(dev && ndirs && distrib && ctx); (void)istep; S3D(scene_view_get_aabb(ctx->view, lower, upper)); @@ -554,7 +553,31 @@ radiative_properties float basis[9]; float transform[12]; float pt[8][3]; + double volume_scaling = 1.0; + double area_scaling = 1.0; + double dist_scaling = 1.0; + + /* Sample a volume scaling factor if necessary */ + if(distrib->sample_volume_scaling) { + res = distrib->sample_volume_scaling + (ctx->rng, &volume_scaling, distrib->context); + if(res != RES_OK) { + log_error(dev, "Error in sampling a volume scaling.\n"); + goto error; + } + if(volume_scaling <= 0) { + log_error(dev, "Invalid volume scale factor `%g'.\n", volume_scaling); + res = RES_BAD_ARG; + goto error; + } + /* Define the scale factor to apply the the area and the distance from the + * scale factor of the volume */ + area_scaling = pow(volume_scaling, 2.0/3.0); + dist_scaling = pow(volume_scaling, 1.0/3.0); + } + + /* Sample an orientation */ ssp_ran_sphere_uniform_float(ctx->rng, dir, NULL); /* Build the transformation matrix from world to footprint space. Use the @@ -1087,7 +1110,8 @@ static char check_distribution(struct sschiff_geometry_distribution* distrib) { ASSERT(distrib); - return distrib->sample != NULL && distrib->characteristic_length > 0; + return distrib->sample != NULL + && distrib->characteristic_length > 0; } static void @@ -1221,24 +1245,18 @@ static res_T begin_realisation (struct sschiff_device* dev, struct sschiff_geometry_distribution* distrib, - double* volume_scaling, struct integrator_context* ctx) { res_T res = RES_OK; - ASSERT(dev && distrib && volume_scaling && ctx && !ctx->view); + ASSERT(dev && distrib && ctx && !ctx->view); /* Sample a particle */ res = distrib->sample - (ctx->rng, ctx->shape, volume_scaling, distrib->context); + (ctx->rng, ctx->shape, distrib->context); if(res != RES_OK) { log_error(dev, "Error in sampling a particle.\n"); goto error; } - if(*volume_scaling <= 0) { - log_error(dev, "Invalid volume scale factor `%g'.\n", *volume_scaling); - res = RES_BAD_ARG; - goto error; - } /* Build the Star-3D representation of the sampled shape */ S3D(scene_view_create(ctx->scene, S3D_TRACE, &ctx->view)); @@ -1578,28 +1596,19 @@ sschiff_integrate #pragma omp parallel for schedule(static) for(igeom=0; igeom < (int)ngeoms; ++igeom) { const int ithread = omp_get_thread_num(); - double volume_scaling; - double area_scaling; - double dist_scaling; ATOMIC res_local = RES_OK; if(ATOMIC_GET(&res) != RES_OK) continue; /* Setup the data for the current realisation */ - res_local = begin_realisation(dev, distrib, &volume_scaling, ctxs+ithread); + res_local = begin_realisation(dev, distrib, ctxs+ithread); if(res_local != RES_OK) { ATOMIC_CAS(&res, res_local, RES_OK); continue; } - /* Define the scale factor to apply the the area and the distance from the - * scale factor of the volume */ - area_scaling = pow(volume_scaling, 2.0/3.0); - dist_scaling = pow(volume_scaling, 1.0/3.0); - /* Schiff Estimation */ - res_local = radiative_properties - (dev, igeom, ndirs, area_scaling, dist_scaling, ctxs+ithread); + res_local = radiative_properties(dev, igeom, ndirs, distrib, ctxs+ithread); if(res_local != RES_OK) ATOMIC_CAS(&res, res_local, RES_OK); end_realisation(ctxs + ithread); diff --git a/src/test_sschiff_estimator_cylinder.c b/src/test_sschiff_estimator_cylinder.c @@ -59,19 +59,29 @@ static res_T sample_cylinder (struct ssp_rng* rng, struct s3d_shape* shape, + void* sampler_context) +{ + struct sampler_context* sampler_ctx = sampler_context; + ASSERT(sampler_context); + (void)rng; + return s3d_mesh_copy(sampler_ctx->shape, shape); +} + +static res_T +sample_volume_scaling + (struct ssp_rng* rng, double* volume_scaling, void* sampler_context) { struct sampler_context* sampler_ctx = sampler_context; - double sphere_volume; double sample; - - CHK(volume_scaling != NULL); + double sphere_volume; + ASSERT(sampler_context); sample = ssp_ran_lognormal(rng, log(sampler_ctx->mean_radius), log(sampler_ctx->sigma)); sphere_volume = 4.0*PI*sample*sample*sample / 3.0; *volume_scaling = sphere_volume / sampler_ctx->cylinder_volume; - return s3d_mesh_copy(sampler_ctx->shape, shape); + return RES_OK; } static INLINE void @@ -451,6 +461,7 @@ main(int argc, char** argv) distrib.material.get_property = get_material_property; distrib.material.material = &sampler_ctx; distrib.sample = sample_cylinder; + distrib.sample_volume_scaling = sample_volume_scaling; distrib.context = &sampler_ctx; time_current(&t0); diff --git a/src/test_sschiff_estimator_rhodo.c b/src/test_sschiff_estimator_rhodo.c @@ -2554,19 +2554,29 @@ static res_T sample_cylinder (struct ssp_rng* rng, struct s3d_shape* shape, + void* sampler_context) +{ + struct sampler_context* sampler_ctx = sampler_context; + CHK(sampler_context); + (void)rng; + return s3d_mesh_copy(sampler_ctx->shape, shape); +} + +static res_T +sample_volume_scaling + (struct ssp_rng* rng, double* volume_scaling, void* sampler_context) { struct sampler_context* sampler_ctx = sampler_context; double sphere_volume; double sample; - CHK(volume_scaling != NULL); sample = ssp_ran_lognormal(rng, log(sampler_ctx->mean_radius), log(sampler_ctx->sigma)); sphere_volume = 4.0*PI*sample*sample*sample / 3.0; *volume_scaling = sphere_volume / sampler_ctx->cylinder_volume; - return s3d_mesh_copy(sampler_ctx->shape, shape); + return RES_OK; } struct cross_section_result { @@ -2642,6 +2652,7 @@ main(int argc, char** argv) distrib.material.get_property = get_material_property; distrib.material.material = &sampler_ctx; distrib.sample = sample_cylinder; + distrib.sample_volume_scaling = sample_volume_scaling; distrib.context = &sampler_ctx; CHK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1, diff --git a/src/test_sschiff_estimator_sphere.c b/src/test_sschiff_estimator_sphere.c @@ -64,19 +64,16 @@ static res_T sample_sphere (struct ssp_rng* rng, struct s3d_shape* shape, - double* volume_scaling, void* sampler_context) { struct sampler_context* sampler_ctx = sampler_context; struct sphere sphere; CHK(rng != NULL); - CHK(volume_scaling != NULL); sphere.geometry = &sampler_ctx->geometry; sphere.radius = (float)ssp_ran_lognormal (rng, log(sampler_ctx->mean_radius), log(sampler_ctx->sigma)); - *volume_scaling = 1.0; return sphere_setup_s3d_shape(&sphere, shape); }