propagate.h : propagate_to_boundary / propagate_at_boundary_geant4_style¶
Table of Contents
- propagate.h : propagate_to_boundary / propagate_at_boundary_geant4_style
- propagate.h : propagate_to_boundary absorb/scatter/sail
- propagate.h : propagate_at_boundary_geant4_style
- propagate.h : propagate_at_specular_reflector / propagate_at_specular_reflector_geant4_style
- propagate.h : propagate_at_diffuse_reflector / propagate_at_diffuse_reflector_geant4_style
- propagate.h : propagate_at_surface
propagate.h : propagate_to_boundary absorb/scatter/sail¶
- absorb
- advance p.time and p.position to absorption point
- if BULK_REEMIT(CONTINUE) change p.direction p.polarization p.wavelength
- if BULK_ABSORB(BREAK) .last_hit_triangle -1
- scatter
- advance p.time and p.position to scattering point
- RAYLEIGH_SCATTER(CONTINUE) change p.direction p.polarization
- sail
- advance p.position p.time to boundary
- sail to boundary(PASS)
- consumes 3u
Inputs:
- p.time
- p.position
- p.direction
- s.distance_to_boundary
- s.material1.x refractive_index
- s.material1.y absorption_length
- s.material1.z scattering_length
- s.material1.w reemission_prob
Outputs:
- p.time
- p.position
- p.direction
- p.wavelength
- p.polarization
- p.flags.i.x (boundary)
- p.flags.i.w (history)
Returns:
- BREAK(BULK_ABSORB)
- CONTINUE(BULK_REEMIT)
- CONTINUE(RAYLEIGH_SCATTER)
- PASS(“SAIL”)
propagate.h : propagate_at_boundary_geant4_style¶
See env-/g4op-/G4OpBoundaryProcess.cc annotations to follow this and compare the Opticks and Geant4 implementations.
Inputs:
- p.direction
- p.polarization
- s.material1.x : refractive index
- s.material2.x : refractive index
- s.surface_normal
Outputs:
- p.direction
- p.polarization
- p.flags.i.x (boundary)
- p.flags.i.w (history)
Tacitly returns CONTINUE
Notes:
- when geometry dictates TIR there is no dependence on u_reflect, just always get reflection
fresnel reflect/transmit conventional directions¶
s1
+----+
\ . / ^
c1 i\ . / r /|\
\ . / |
material1 \./ | n
---------------+----------+----------
material2 .\
. \
c2 . \ t
. \
+----+
s2
- i, incident photons
- pointing down to interface (from material1 towards material2)
- n, surface normal (s.surface_normal)
- pointing up from interface (from material2 back into material1) Orientation is arranged by flipping geometric normal based on photon direction.
- t, transmitted photons
- from interface into material2
- r, reflected photons
- from interface back into material1
- c1, costheta_1
- cosine of incident angle, c1 = dot(-i, n) = - dot(i, n) arranged to be positive via normal flipping and corresponding flip of which material is labelled 1 and 2
polarisation¶
S polarized : E field perpendicular to plane of incidence
P polarized : E field within plane of incidence
normal incidence photons¶
- no unique plane of incidence,
- artifically setting incident_plane_normal to initial p.polarisation yields normal_coefficient = 1.0f so always treated as S polarized
- initial momentum dir
- -s.surface_normal
- final momentum dir (c1 = 1.f)
- -s.surface_normal + 2.0f*c1*s.surface_normal = +s.surface_normal = -p.direction
minimise use of trancendental functions¶
Obtain c2c2 from Snells Law without lots of expensive function calls.:
n1 s1 = n2 s2
s2 = eta * s1 eta = n1/n2
c2c2 = 1 - s2s2
= 1 - eta eta s1 s1
= 1 - eta eta (1 - c1c1)
c2c2 - 1 = (c1c1 - 1) eta eta
TIR : total internal reflection¶
Total internal reflection, occurs when c2c2 < 0.f (c2 imaginary)
Handled by:
- artificially setting c2 = 0.f
- results in reflection_coefficient = 1.0f so will always reflect for both S and P cases
propagate.h : propagate_at_specular_reflector / propagate_at_specular_reflector_geant4_style¶
Inputs:
- p.direction
- p.polarization
- s.surface_normal
- s.cos_theta
Outputs:
- p.direction
- p.polarization
- p.flags.i.x
- p.flags.i.w
Returns:
CONTINUE
propagate.h : propagate_at_diffuse_reflector / propagate_at_diffuse_reflector_geant4_style¶
Changes p.direction, p.polarization and p.flags.i.x
propagate.h : propagate_at_surface¶
Inputs:
- s.surface.x detect
- s.surface.y absorb (1.f - reflectivity ) ?
- s.surface.z reflect_specular
- s.surface.w reflect_diffuse
These properties are setup in GSurfaceLib::createStandardSurface which then get interveaved with material properties into the boundary_texture for GPU access.
Surface and material properties are read from the texture for the relevant boundary index that results from the ray trace.
- optixrap/cu/state.h:fill_state
- optixrap/cu/boundary_lookup.h
Returns:
- BREAK(SURFACE_ABSORB)
- BREAK(SURFACE_DETECT)
- CONTINUE(SURFACE_DREFLECT)
- CONTINUE(SURFACE_SREFLECT)
Known differences vs counterpart DsG4OpBoundaryProcess::DoAbsorption¶
- u_surface_burn not compared against theEfficiency to decide on detect
TODO¶
arrange values to do equivalent to G4 ?
absorb + detect + reflect_diffuse + reflect_specular = 1 ??
How to handle special casing of some surfaces…
- SPECULARLOBE…