DiFfRG
Loading...
Searching...
No Matches
math.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
7
8// standard library
9#include <cmath>
10#include <type_traits>
11
12// external libraries
13#include <Eigen/Dense>
14#include <autodiff/forward/real.hpp>
15#include <deal.II/lac/block_vector.h>
16#include <deal.II/lac/vector.h>
17
18namespace DiFfRG
19{
26 template <size_t N, typename T> bool isfinite(const autodiff::Real<N, T> &x)
27 {
28 return std::isfinite(autodiff::val(x)) && std::isfinite(autodiff::derivative(x));
29 }
30 using std::isfinite;
31
40 template <int n, typename NumberType>
41 requires requires(NumberType x) {
42 x *x;
43 NumberType(1.) / x;
44 }
45 constexpr __forceinline__ __host__ __device__ NumberType powr(const NumberType x)
46 {
47 if constexpr (n == 0)
48 return NumberType(1.);
49 else if constexpr (n < 0)
50 return NumberType(1.) / powr<-n, NumberType>(x);
51 else if constexpr (n > 1)
52 return x * powr<n - 1, NumberType>(x);
53 else
54 return x;
55 }
56
63 template <typename NT> constexpr __forceinline__ __host__ __device__ double V_d(NT d)
64 {
65 using std::pow;
66 using std::tgamma;
67 return pow(M_PI, d / 2.) / tgamma(d / 2. + 1.);
68 }
69
78 template <typename NT1, typename NT2> constexpr __forceinline__ __host__ __device__ double V_d(NT1 d, NT2 extent)
79 {
80 using std::pow;
81 using std::tgamma;
82 return pow(M_PI, d / 2.) / tgamma(d / 2. + 1.) * pow(extent, d);
83 }
84
91 template <typename NT> constexpr __forceinline__ __host__ __device__ double S_d(NT d)
92 {
93 using std::pow;
94 using std::tgamma;
95 return 2. * pow(M_PI, d / 2.) / tgamma(d / 2.);
96 }
97
104 template <typename NT> consteval NT S_d_prec(uint d)
105 {
106 if (d == 1)
107 return 2;
108 else if (d == 2)
109 return static_cast<NT>(2) * static_cast<NT>(M_PI);
110 else if (d == 3)
111 return static_cast<NT>(4) * static_cast<NT>(M_PI);
112 else if (d == 4)
113 return static_cast<NT>(2) * powr<2>(static_cast<NT>(M_PI));
114 else if (d == 5)
115 return static_cast<NT>(8) * powr<2>(static_cast<NT>(M_PI)) / static_cast<NT>(3);
116 else if (d == 6)
117 return powr<3>(static_cast<NT>(M_PI));
118 else if (d == 7)
119 return static_cast<NT>(16) * powr<3>(static_cast<NT>(M_PI)) / static_cast<NT>(15);
120 return std::numeric_limits<NT>::quiet_NaN();
121 }
122
126 template <typename NumberType>
127 requires requires(NumberType x) { x >= 0; }
128 constexpr __forceinline__ __host__ __device__ auto heaviside_theta(const NumberType x)
129 {
130 if constexpr (std::is_same_v<NumberType, autodiff::real>)
131 return x >= 0. ? 1. : 0.;
132 else
133 return x >= static_cast<NumberType>(0) ? static_cast<NumberType>(1) : static_cast<NumberType>(0);
134 }
135
139 template <typename NumberType>
140 requires requires(NumberType x) { x >= 0; }
141 constexpr __forceinline__ __host__ __device__ auto sign(const NumberType x)
142 {
143 if constexpr (std::is_same_v<NumberType, autodiff::real>)
144 return x >= 0. ? 1. : -1.;
145 else
146 return x >= static_cast<NumberType>(0) ? static_cast<NumberType>(1) : static_cast<NumberType>(-1);
147 }
148
156 template <typename T1, typename T2, typename T3>
157 requires(std::is_floating_point<T1>::value || std::is_same_v<T1, autodiff::real> || is_complex<T1>::value) &&
158 (std::is_floating_point<T2>::value || std::is_same_v<T2, autodiff::real> || is_complex<T2>::value) &&
159 std::is_floating_point<T3>::value
160 bool __forceinline__ __host__ __device__ is_close(T1 a, T2 b, T3 eps_)
161 {
163 return is_close(real(a), real(b), eps_) && is_close(imag(a), imag(b), eps_);
164 } else if constexpr (std::is_same_v<T1, autodiff::real> || std::is_same_v<T2, autodiff::real>)
165 return is_close((double)a, (double)b, (double)eps_);
166 else {
167 T1 diff = std::fabs(a - b);
168 if (diff <= eps_) return true;
169 if (diff <= std::fmax(std::fabs(a), std::fabs(b)) * eps_) return true;
170 }
171 return false;
172 }
173
180 template <typename T1, typename T2>
181 requires(std::is_floating_point<T1>::value || std::is_same_v<T1, autodiff::real> || is_complex<T1>::value) &&
182 (std::is_floating_point<T2>::value || std::is_same_v<T2, autodiff::real> || is_complex<T1>::value)
183 bool __forceinline__ __host__ __device__ is_close(T1 a, T2 b)
184 {
186 return is_close(real(a), real(b)) && is_close(imag(a), imag(b));
187 } else if constexpr (std::is_same_v<T1, autodiff::real> || std::is_same_v<T2, autodiff::real>) {
188 constexpr auto eps_ = std::numeric_limits<double>::epsilon() * 10.;
189 return is_close((double)a, (double)b, eps_);
190 } else {
191 constexpr auto eps_ = std::max(std::numeric_limits<T1>::epsilon(), std::numeric_limits<T2>::epsilon());
192 return is_close(a, b, eps_);
193 }
194 return false;
195 }
196
201 template <uint n, typename NT, typename A1, typename A2>
202 requires requires(A1 a1, A2 a2) { a1[0] * a2[0]; }
203 NT dot(const A1 &a1, const A2 &a2)
204 {
205 NT ret = a1[0] * a2[0];
206 for (uint i = 1; i < n; ++i)
207 ret += a1[i] * a2[i];
208 return ret;
209 }
210
217 void dealii_to_eigen(const dealii::Vector<double> &dealii, Eigen::VectorXd &eigen);
218
225 void dealii_to_eigen(const dealii::BlockVector<double> &dealii, Eigen::VectorXd &eigen);
226
233 void eigen_to_dealii(const Eigen::VectorXd &eigen, dealii::Vector<double> &dealii);
234
241 void eigen_to_dealii(const Eigen::VectorXd &eigen, dealii::BlockVector<double> &dealii);
242} // namespace DiFfRG
Definition complex_math.hh:14
void eigen_to_dealii(const Eigen::VectorXd &eigen, dealii::Vector< double > &dealii)
Converts an Eigen vector to a dealii vector.
constexpr __forceinline__ __host__ __device__ NumberType powr(const NumberType x)
A compile-time evaluatable power function for whole number exponents.
Definition math.hh:45
bool __forceinline__ __host__ __device__ is_close(T1 a, T2 b, T3 eps_)
Function to evaluate whether two floats are equal to numerical precision. Tests for both relative and...
Definition math.hh:160
NT dot(const A1 &a1, const A2 &a2)
A dot product which takes the dot product between a1 and a2, assuming each has n entries which can be...
Definition math.hh:203
AUTODIFF_DEVICE_FUNC auto real(const autodiff::Real< N, T > &a)
Definition complex_math.hh:148
constexpr __forceinline__ __host__ __device__ double S_d(NT d)
Surface of a d-dimensional sphere.
Definition math.hh:91
consteval NT S_d_prec(uint d)
Surface of a d-dimensional sphere (precompiled)
Definition math.hh:104
constexpr __forceinline__ __host__ __device__ double V_d(NT d)
Volume of a d-dimensional sphere.
Definition math.hh:63
unsigned int uint
Definition utils.hh:22
void dealii_to_eigen(const dealii::Vector< double > &dealii, Eigen::VectorXd &eigen)
Converts a dealii vector to an Eigen vector.
constexpr __forceinline__ __host__ __device__ auto heaviside_theta(const NumberType x)
A compile-time evaluatable theta function.
Definition math.hh:128
constexpr __forceinline__ __host__ __device__ auto sign(const NumberType x)
A compile-time evaluatable sign function.
Definition math.hh:141
constexpr AUTODIFF_DEVICE_FUNC auto imag(const autodiff::Real< N, T > &)
Definition complex_math.hh:149
bool isfinite(const autodiff::Real< N, T > &x)
Finite-ness check for autodiff::real.
Definition math.hh:26
Definition complex_math.hh:141