Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:05:57

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file orange/transform/TransformSimplifier.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Macros.hh"
0011 #include "orange/OrangeTypes.hh"
0012 
0013 #include "VariantTransform.hh"
0014 
0015 namespace celeritas
0016 {
0017 //---------------------------------------------------------------------------//
0018 /*!
0019  * Return a simplified version of a transformation.
0020  *
0021  * Like surface simplification, we want to consider whether two different
0022  * transformations will result in a distance change of \f$\epsilon\f$ for a
0023  * point that's at the length scale from the origin. Setting the length scale
0024  * to unity (the default), we use the relative tolerance.
0025  *
0026  * A *translation* can be deleted if its magnitude is less than epsilon.
0027  *
0028  * For a translation, we use the fact that the trace (sum of diagonal elements)
0029  * of any proper (non-reflecting) rotation matrix has an angle of rotation \f[
0030    \mathrm{Tr}[R] = 2 \cos \theta + 1
0031  * \f] about an axis of rotation. Applying the rotation to a point
0032  * at a unit distance will yield an iscoceles triangle with sides 1 and inner
0033  * angle \f$\theta\f$. For the displacement to be no more than \f$\epsilon\f$
0034  * then the angle must be \f[
0035   \sin \theta/2 \le \epsilon/2
0036   \f]
0037  * which with some manipulation means that a "soft zero" rotation has a trace
0038  * \f[
0039  \mathrm{Tr}[R] \ge 3 - \epsilon^2 \,.
0040  \f]
0041  *
0042  * Note that this means no rotational simplifications may be performed when the
0043  * geometry tolerance is less than the square root of machine precision.
0044  */
0045 class TransformSimplifier
0046 {
0047   public:
0048     // Construct with tolerance
0049     explicit inline TransformSimplifier(Tolerance<> const& tol);
0050 
0051     //! No simplification can be applied to a null transformation
0052     VariantTransform operator()(NoTransformation const& nt) { return nt; }
0053 
0054     // Translation may simplify to no transformation
0055     VariantTransform operator()(Translation const& nt);
0056 
0057     // Simplify, possibly to translation or no transform
0058     VariantTransform operator()(Transformation const& nt);
0059 
0060   private:
0061     real_type eps_;
0062 };
0063 
0064 //---------------------------------------------------------------------------//
0065 // INLINE DEFINITIONS
0066 //---------------------------------------------------------------------------//
0067 /*!
0068  * Construct with tolerance.
0069  */
0070 TransformSimplifier::TransformSimplifier(Tolerance<> const& tol)
0071     : eps_{tol.rel}
0072 {
0073     CELER_EXPECT(tol);
0074 }
0075 
0076 //---------------------------------------------------------------------------//
0077 }  // namespace celeritas