Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:54:08

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 corecel/math/Turn.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cmath>
0010 #include <type_traits>
0011 
0012 #include "corecel/Constants.hh"
0013 #include "corecel/Types.hh"
0014 
0015 #include "Algorithms.hh"
0016 #include "Quantity.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 //! Unit for 2*pi radians
0022 struct TwoPi
0023 {
0024     static CELER_CONSTEXPR_FUNCTION Constant value()
0025     {
0026         return 2 * constants::pi;
0027     }
0028     //! Text label for output
0029     static char const* label() { return "tr"; }
0030 };
0031 
0032 //---------------------------------------------------------------------------//
0033 //! Unit for pi/2 radians
0034 struct HalfPi
0035 {
0036     static CELER_CONSTEXPR_FUNCTION Constant value()
0037     {
0038         return constants::pi / 2;
0039     }
0040     //! Text label for output
0041     static char const* label() { return "qtr"; }
0042 };
0043 
0044 //---------------------------------------------------------------------------//
0045 /*!
0046  * Quantity denoting a full turn.
0047  *
0048  * Turns are a useful way of representing angles without the historical
0049  * arbitrariness of degrees or the roundoff errors of radians. See, for
0050  * example, https://www.computerenhance.com/p/turns-are-better-than-radians .
0051  */
0052 template<class T>
0053 using Turn_t = Quantity<TwoPi, T>;
0054 
0055 //! Turn with default precision (DEPRECATEDish)
0056 using Turn = Turn_t<real_type>;
0057 //! Turn with default precision
0058 using RealTurn = Turn_t<real_type>;
0059 
0060 //! Create a turn using template deduction
0061 template<class T>
0062 CELER_CONSTEXPR_FUNCTION Turn_t<T> make_turn(T value)
0063 {
0064     static_assert(std::is_floating_point_v<T>,
0065                   "turn type must be floating point");
0066     return Turn_t<T>{value};
0067 }
0068 
0069 //---------------------------------------------------------------------------//
0070 //! Quantity for an integer number of turns for axis swapping (DEPRECATEDish)
0071 using QuarterTurn = Quantity<HalfPi, int>;
0072 //! Quantity for an integer number of turns for axis swapping
0073 using IntQuarterTurn = Quantity<HalfPi, int>;
0074 
0075 //---------------------------------------------------------------------------//
0076 //!@{
0077 //! Special overrides for math functions for more precise arithmetic
0078 template<class T>
0079 CELER_FORCEINLINE_FUNCTION T sin(Turn_t<T> r)
0080 {
0081     return sinpi(r.value() * 2);
0082 }
0083 
0084 template<class T>
0085 CELER_FORCEINLINE_FUNCTION T cos(Turn_t<T> r)
0086 {
0087     return cospi(r.value() * 2);
0088 }
0089 
0090 template<class T>
0091 CELER_FORCEINLINE_FUNCTION void sincos(Turn_t<T> r, T* sinv, T* cosv)
0092 {
0093     return sincospi(r.value() * 2, sinv, cosv);
0094 }
0095 
0096 CELER_CONSTEXPR_FUNCTION int cos(IntQuarterTurn r)
0097 {
0098     constexpr int cosval[] = {1, 0, -1, 0};
0099     return cosval[(r.value() > 0 ? r.value() : -r.value()) % 4];
0100 }
0101 
0102 CELER_CONSTEXPR_FUNCTION int sin(IntQuarterTurn r)
0103 {
0104     // Define in terms of the symmetric "cos"
0105     return cos(IntQuarterTurn{r.value() - 1});
0106 }
0107 
0108 CELER_CONSTEXPR_FUNCTION void sincos(IntQuarterTurn r, int* sinv, int* cosv)
0109 {
0110     *sinv = sin(r);
0111     *cosv = cos(r);
0112 }
0113 //!@}
0114 
0115 //! Math functions that return turns from types
0116 template<class T>
0117 CELER_FORCEINLINE_FUNCTION Turn_t<T> atan2turn(T y, T x)
0118 {
0119     // TODO: some OS/lib has this natively; use that instad
0120     return native_value_to<Turn_t<T>>(std::atan2(y, x));
0121 }
0122 
0123 //---------------------------------------------------------------------------//
0124 }  // namespace celeritas