Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:11:39

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/optical/surface/model/ReflectionFormCalculator.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "celeritas/optical/ParticleTrackView.hh"
0010 #include "celeritas/optical/surface/SurfacePhysicsTrackView.hh"
0011 #include "celeritas/optical/surface/SurfacePhysicsUtils.hh"
0012 
0013 #include "LambertianDistribution.hh"
0014 #include "SurfaceInteraction.hh"
0015 
0016 namespace celeritas
0017 {
0018 namespace optical
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Calculator for UNIFIED reflection model.
0023  *
0024  * The model specifies 4 different reflection modes:
0025  *  1. Specular spike: geometric reflection about global normal
0026  *  2. Specular lobe: geometric reflection about facet normal
0027  *  3. Back-scattering: reversed photon direction and polarization
0028  *  4. Diffuse Lambertian: reflection following Lambert's cosine law
0029  */
0030 class ReflectionFormCalculator
0031 {
0032   public:
0033     // Construct from photon and surface data
0034     explicit inline CELER_FUNCTION ReflectionFormCalculator(
0035         Real3 const& direction,
0036         Real3 const& polarization,
0037         Real3 const& global_normal,
0038         Real3 const& facet_normal);
0039 
0040     // Construct from track views
0041     explicit inline CELER_FUNCTION ReflectionFormCalculator(
0042         Real3 const& inc_direction,
0043         ParticleTrackView const& photon,
0044         SurfacePhysicsTrackView const& surface_physics);
0045 
0046     // Calculate specular spike reflection
0047     inline CELER_FUNCTION SurfaceInteraction calc_specular_spike() const;
0048 
0049     // Calculate specular lobe reflection
0050     inline CELER_FUNCTION SurfaceInteraction calc_specular_lobe() const;
0051 
0052     // Calculate back-scattering reflection
0053     inline CELER_FUNCTION SurfaceInteraction calc_backscatter() const;
0054 
0055     // Sample diffuse Lambertian reflection
0056     template<class Engine>
0057     inline CELER_FUNCTION SurfaceInteraction sample_lambertian_reflection(
0058         Engine& rng) const;
0059 
0060   private:
0061     Real3 const& direction_;
0062     Real3 const& polarization_;
0063     Real3 global_normal_;
0064     Real3 const& facet_normal_;
0065 
0066     // Calculate specular reflection about the given normal
0067     inline CELER_FUNCTION SurfaceInteraction calc_specular_reflection(
0068         Real3 const& normal) const;
0069 };
0070 
0071 //---------------------------------------------------------------------------//
0072 /*!
0073  * Construct calculator from photon and surface data.
0074  */
0075 CELER_FUNCTION ReflectionFormCalculator::ReflectionFormCalculator(
0076     Real3 const& direction,
0077     Real3 const& polarization,
0078     Real3 const& global_normal,
0079     Real3 const& facet_normal)
0080     : direction_(direction)
0081     , polarization_(polarization)
0082     , global_normal_(global_normal)
0083     , facet_normal_(facet_normal)
0084 {
0085     CELER_EXPECT(is_soft_unit_vector(global_normal_));
0086     CELER_EXPECT(is_soft_unit_vector(facet_normal_));
0087     CELER_EXPECT(is_entering_surface(direction_, global_normal_));
0088     CELER_EXPECT(is_entering_surface(direction_, facet_normal_));
0089 }
0090 
0091 //---------------------------------------------------------------------------//
0092 /*!
0093  * Construct calculator from a given track's views.
0094  */
0095 CELER_FUNCTION ReflectionFormCalculator::ReflectionFormCalculator(
0096     Real3 const& inc_direction,
0097     ParticleTrackView const& photon,
0098     SurfacePhysicsTrackView const& surface_physics)
0099     : ReflectionFormCalculator(inc_direction,
0100                                photon.polarization(),
0101                                surface_physics.global_normal(),
0102                                surface_physics.facet_normal())
0103 {
0104 }
0105 
0106 //---------------------------------------------------------------------------//
0107 /*!
0108  * Calculate specular spike reflection.
0109  *
0110  * This is geometric reflection about the global normal.
0111  */
0112 CELER_FUNCTION SurfaceInteraction
0113 ReflectionFormCalculator::calc_specular_spike() const
0114 {
0115     return this->calc_specular_reflection(global_normal_);
0116 }
0117 
0118 //---------------------------------------------------------------------------//
0119 /*!
0120  * Calculate specular lobe reflection.
0121  *
0122  * This is geometric reflection about the facet normal.
0123  */
0124 CELER_FUNCTION SurfaceInteraction
0125 ReflectionFormCalculator::calc_specular_lobe() const
0126 {
0127     return this->calc_specular_reflection(facet_normal_);
0128 }
0129 
0130 //---------------------------------------------------------------------------//
0131 /*!
0132  * Calculate back-scattering reflection.
0133  *
0134  * The photon direction and polarization are reversed.
0135  */
0136 CELER_FUNCTION SurfaceInteraction
0137 ReflectionFormCalculator::calc_backscatter() const
0138 {
0139     SurfaceInteraction result;
0140     result.action = SurfaceInteraction::Action::reflected;
0141     result.direction = -direction_;
0142     result.polarization = -polarization_;
0143     return result;
0144 }
0145 
0146 //---------------------------------------------------------------------------//
0147 /*!
0148  * Sample diffuse Lambertian reflection.
0149  *
0150  * Ideal diffuse reflection following Lambert's cosine law.
0151  */
0152 template<class Engine>
0153 CELER_FUNCTION SurfaceInteraction
0154 ReflectionFormCalculator::sample_lambertian_reflection(Engine& rng) const
0155 {
0156     SurfaceInteraction result;
0157     result.action = SurfaceInteraction::Action::reflected;
0158     result.direction = LambertianDistribution{global_normal_}(rng);
0159     auto n = make_unit_vector(result.direction - direction_);
0160     result.polarization = -geometric_reflected_from(polarization_, n);
0161     return result;
0162 }
0163 
0164 //---------------------------------------------------------------------------//
0165 /*!
0166  * Helper function to calculate geometric reflection about a given normal.
0167  */
0168 CELER_FUNCTION SurfaceInteraction
0169 ReflectionFormCalculator::calc_specular_reflection(Real3 const& normal) const
0170 {
0171     SurfaceInteraction result;
0172     result.action = SurfaceInteraction::Action::reflected;
0173     result.direction = geometric_reflected_from(direction_, normal);
0174     result.polarization = -geometric_reflected_from(polarization_, normal);
0175     return result;
0176 }
0177 
0178 //---------------------------------------------------------------------------//
0179 }  // namespace optical
0180 }  // namespace celeritas