Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:07:50

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 orange/surf/RecursiveSimplifier.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <utility>
0010 #include <variant>
0011 
0012 #include "orange/OrangeTypes.hh"
0013 
0014 #include "VariantSurface.hh"
0015 
0016 #include "detail/AllSurfaces.hh"
0017 #include "detail/RecursiveSimplifierImpl.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Recursively simplify, then call the given function on the final surface.
0024  *
0025  * The tolerance for this class should be relative.
0026  *
0027  * Example:
0028  * \code
0029   RecursiveSimplifier print_simplified([](Sense s, auto&& surf) {
0030       cout << to_char(s) << surf << endl;
0031   }, 1e-10);
0032   // Invoke on a compile-time surface type
0033   print_simplified(Sense::inside, Plane{{1,0,0}, 4});
0034   // Invoke on a run-time surface type
0035   for (auto&& [sense, surf] : my_senses_and_variants)
0036   {
0037       print_simplified(sense, surf);
0038   }
0039   \endcode
0040  *
0041  */
0042 template<class F>
0043 class RecursiveSimplifier
0044 {
0045   public:
0046     // Construct with tolerance and function to apply
0047     inline RecursiveSimplifier(F&& func, real_type tol);
0048 
0049     //! Construct with tolerance and function to apply
0050     RecursiveSimplifier(F&& func, Tolerance<> tol)
0051         : RecursiveSimplifier(std::forward<F>(func), tol.rel)
0052     {
0053     }
0054 
0055     // Apply to a surface with a known type
0056     template<class S>
0057     void operator()(Sense s, S const& surf);
0058 
0059     // Apply to a surface with unknown type
0060     void operator()(Sense s, VariantSurface const& surf);
0061 
0062   private:
0063     F func_;
0064     real_type tol_;
0065 };
0066 
0067 //---------------------------------------------------------------------------//
0068 // DEDUCTION GUIDES
0069 //---------------------------------------------------------------------------//
0070 template<class F, class... Ts>
0071 RecursiveSimplifier(F&&, Ts...) -> RecursiveSimplifier<F>;
0072 
0073 //---------------------------------------------------------------------------//
0074 // INLINE DEFINITIONS
0075 //---------------------------------------------------------------------------//
0076 /*!
0077  * Construct with tolerance and function to apply.
0078  */
0079 template<class F>
0080 RecursiveSimplifier<F>::RecursiveSimplifier(F&& func, real_type tol)
0081     : func_{std::forward<F>(func)}, tol_{tol}
0082 {
0083     CELER_EXPECT(tol_ >= 0);
0084 }
0085 
0086 //---------------------------------------------------------------------------//
0087 /*!
0088  * Apply to a surface with a known type.
0089  */
0090 template<class F>
0091 template<class S>
0092 void RecursiveSimplifier<F>::operator()(Sense sense, S const& surf)
0093 {
0094     return detail::RecursiveSimplifierImpl<F>{func_, sense, tol_}(surf);
0095 }
0096 
0097 //---------------------------------------------------------------------------//
0098 /*!
0099  * Apply to a surface with an unknown type.
0100  */
0101 template<class F>
0102 void RecursiveSimplifier<F>::operator()(Sense sense, VariantSurface const& surf)
0103 {
0104     return std::visit(detail::RecursiveSimplifierImpl<F>{func_, sense, tol_},
0105                       surf);
0106 }
0107 
0108 //---------------------------------------------------------------------------//
0109 }  // namespace celeritas