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:
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);
}