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/LambertianDistribution.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/math/ArrayOperators.hh"
0010 #include "corecel/math/ArrayUtils.hh"
0011 #include "corecel/random/distribution/UniformRealDistribution.hh"
0012 #include "celeritas/optical/Types.hh"
0013 #include "celeritas/phys/InteractionUtils.hh"
0014 
0015 namespace celeritas
0016 {
0017 namespace optical
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Sample a reflected vector from a diffuse Lambertian distribution.
0022  *
0023  * Lambertian reflectance is an approximation of a diffuse material where the
0024  * apparent brightness is equal for observers at all angles. Reflected vectors
0025  * follow Lambert's cosine law, which states the intensity of reflected light
0026  * is proportional to the cosine of the reflection angle \f( \alpha \f):
0027  *
0028  * \f[ I = I_0 \cos \alpha \f]
0029  *
0030  * Treating the incident light as a collection of photons, they are reflected
0031  * with probability \f( p(\alpha) = \cos\alpha \f) about the surface normal,
0032  * and the azimuthal angle is uniformly randomly sampled.
0033  */
0034 class LambertianDistribution
0035 {
0036   public:
0037     // Construct distribution about a given normal
0038     explicit inline CELER_FUNCTION LambertianDistribution(Real3 const& normal);
0039 
0040     // Sample by Lambertian cosine law
0041     template<class Engine>
0042     inline CELER_FUNCTION Real3 operator()(Engine&) const;
0043 
0044   private:
0045     Real3 const& normal_;
0046 };
0047 
0048 //---------------------------------------------------------------------------//
0049 // INLINE DEFINITIONS
0050 //---------------------------------------------------------------------------//
0051 /*!
0052  * Construct distribution about a normal.
0053  */
0054 CELER_FUNCTION LambertianDistribution::LambertianDistribution(
0055     Real3 const& normal)
0056     : normal_(normal)
0057 {
0058     CELER_EXPECT(is_soft_unit_vector(normal_));
0059 }
0060 
0061 //---------------------------------------------------------------------------//
0062 /*!
0063  * Sample by Lambertian cosine law.
0064  */
0065 template<class Engine>
0066 CELER_FUNCTION Real3 LambertianDistribution::operator()(Engine& rng) const
0067 {
0068     real_type cos_theta = sqrt(UniformRealDistribution{}(rng));
0069     return ExitingDirectionSampler{cos_theta, normal_}(rng);
0070 }
0071 
0072 //---------------------------------------------------------------------------//
0073 }  // namespace optical
0074 }  // namespace celeritas