Links

Content Skeleton

This Page

Previous topic

Chroma Use Of CURand

Next topic

llvm

Chroma ReemissionΒΆ

chroma/chroma/cuda/photon.h:

335     // absorption
336     //   #. advance .time and .position to absorption point
337     //   #. if BULK_REEMIT(CONTINUE) change .direction .polarization .wavelength
338     //   #. if BULK_ABSORB(BREAK)  .last_hit_triangle -1
339     //
340     //  huh, branch BULK_REEMIT(CONTINUE) does not set .last_hit_triangle -1 ?
341     //
342     if (absorption_distance <= scattering_distance) {
343         if (absorption_distance <= s.distance_to_boundary)
344         {
345             p.time += absorption_distance/(SPEED_OF_LIGHT/s.refractive_index1);
346             p.position += absorption_distance*p.direction;
347
348             float uniform_sample_reemit = curand_uniform(&rng);
349             if (uniform_sample_reemit < s.reemission_prob)
350             {
351                 p.wavelength = sample_cdf(&rng, s.material1->n,
352                                           s.material1->wavelength0,
353                                           s.material1->step,
354                                           s.material1->reemission_cdf);
                    //
                    // generating a wavelength according to
                    // the source distribution used in construction
                    // of the reemission_cdf
                    //

355                 p.direction = uniform_sphere(&rng);
356                 p.polarization = cross(uniform_sphere(&rng), p.direction);
357                 p.polarization /= norm(p.polarization);
358                 p.history |= BULK_REEMIT;
359                 return CONTINUE;
360             } // photon is reemitted isotropically
361             else
362             {
363                 p.last_hit_triangle = -1;
364                 p.history |= BULK_ABSORB;
365                 return BREAK;
366             } // photon is absorbed in material1
367         }
368     }

See env/geant4/geometry/collada/g4daeview/sample_cdf.py for review of sample_cdf using inverse CDF sampling to generate distributions.

chroma/chroma/cuda/random.h:

25 // Draw a random sample given a cumulative distribution function
26 // Assumptions: ncdf >= 2, cdf_y[0] is 0.0, and cdf_y[ncdf-1] is 1.0
27 __device__ float
28 sample_cdf(curandState *rng, int ncdf, float *cdf_x, float *cdf_y)
29 {
30     return interp(curand_uniform(rng),ncdf,cdf_y,cdf_x);
31 }
32
33 // Sample from a uniformly-sampled CDF
34 __device__ float
35 sample_cdf(curandState *rng, int ncdf, float x0, float delta, float *cdf_y)
36 {
37     float u = curand_uniform(rng);

       //
       // u, uniform random number between 0 and 1
       //
38
39     int lower = 0;
40     int upper = ncdf - 1;
41
42     while(lower < upper-1)
43     {
44         int half = (lower + upper) / 2;
45
46         if (u < cdf_y[half])
47             upper = half;
48         else
49             lower = half;
50     }

       //
       // find bin of cdf_y that straddles u
       //
       //     * cdf_y needs to range from 0:1
       //       (ie a cumulative distribution normalized to 1 at RHS)
       //

51
52     float delta_cdf_y = cdf_y[upper] - cdf_y[lower];
53

       //  translate bin int into domain float

54     return x0 + delta*lower + delta*(u-cdf_y[lower])/delta_cdf_y;
55 }