generate.cu

generate.cu:generate : generate + propagate filling photon_buffer

Prior to bounce loop

  • get genstep_id from seed_buffer and access the genstep for the photon_id
  • generate Cerenkov/Scintillation/Torch photons using implementations from the corresponding headers

Inside bounce loop before record save

                        /\
 *--> . . . . . . m1  ./  \ - m2 - - - -
p                     / su \
                     /______\
  • rtTrace finds intersect along ray from p.position in p.direction, and geometry closest hit function sets prd.boundary
  • prd.boundary and p.wavelength used to lookup surface/material properties from the boundary texture
  • note that so far there is no change to p.direction/p.position/p.time they are still at their generated OR last changed positions from CONTINUE-ers from the below propagation code

In summary before record save are looking ahead to see where to go next while the photon remains with the existing position, direction and flags from the prior “step” or generation.

Inside bounce loop after record save

  • changes p.position p.time p.direction p.polarization … then CONTINUEs back to the above to find the next intersection or BREAKs
.       BULK_SCATTER/BULK_REEMIT
            ^
            |           /\
 *--> . # . *. . . m1  /  \ - m2 - - - -
p       .             / su \
     BULK_ABSORB     /______\
  • each turn of the loop only sets a single history bit
  • bit position is used rather than the full mask in the photon record to save bits
  • control the or-ing of that flag into photon history at this level
  • integrate surface optical props: finish=polished/ground

RSAVE Macro

Writes compressed step points into the record buffer

Two in/outputs seqhis and seqmat, the rest are inputs specifying sources of the data and where to write it.

seqhis
shifts in “his” nibble obtained from ffs of s.flag
seqmat
shifts in “mat” nibble obtained from s.index.x

FLAGS Macro

Sets the photon flags p.flags using values from state s and per-ray-data prd

p.flags.u.x
packed signed int boundary and unsigned sensorIndex which are assumed to fit in 16 bits into 32 bits, see SPack::unsigned_as_int
p.flags.u.y
now getting s.identity.x (nodeIndex) thanks to the packing
s.identity.x
node index
s.identity.w
sensor index arriving from GVolume::getIdentity.w
256 glm::uvec4 GVolume::getIdentity() const
257 {
258     glm::uvec4 id(getIndex(), getTripletIdentity(), getShapeIdentity(), getSensorIndex()) ;
259     return id ;
260 }

NumPy array access:

boundary    = (( flags[:,0].view(np.uint32) & 0xffff0000 ) >> 16 ).view(np.int16)[1::2]
sensorIndex = (( flags[:,0].view(np.uint32) & 0x0000ffff ) >>  0 ).view(np.int16)[0::2]

In [2]: nidx = a.ox[:,3,1].view(np.uint32) ; nidx
Out[2]: A([106122,  67843, 129818, ...,  94170,  67843, 125090], dtype=uint32)

Formerly:

p.flags.i.x = prd.boundary ;  \
p.flags.u.y = s.identity.w ;  \
p.flags.u.w |= s.flag ; \