18 #include <type_traits>
31 template <
typename T,
int... n>
38 template <
typename T,
int n>
40 static_assert(::detail::always_false<T>{},
"error: there is no such thing as a rank-1 isotropic tensor!");
48 template <
typename T,
int m>
76 template <
typename S,
typename T,
int m>
83 template <
typename S,
typename T,
int m>
99 template <
typename S,
typename T,
int m>
115 template <
typename S,
typename T,
int m>
131 template <
typename S,
typename T,
int m>
134 tensor<decltype(S{} + T{}), m, m> output{};
135 for (
int i = 0; i < m; i++) {
136 for (
int j = 0; j < m; j++) {
137 output[i][j] = I.value * (i == j) + A[i][j];
144 template <
typename S,
typename T,
int m>
147 tensor<decltype(S{} + T{}), m, m> output{};
148 for (
int i = 0; i < m; i++) {
149 for (
int j = 0; j < m; j++) {
150 output[i][j] = A[i][j] + I.
value * (i == j);
166 template <
typename S,
typename T,
int m>
169 tensor<decltype(S{} - T{}), m, m> output{};
170 for (
int i = 0; i < m; i++) {
171 for (
int j = 0; j < m; j++) {
172 output[i][j] = I.value * (i == j) - A[i][j];
179 template <
typename S,
typename T,
int m>
182 tensor<decltype(S{} - T{}), m, m> output{};
183 for (
int i = 0; i < m; i++) {
184 for (
int j = 0; j < m; j++) {
185 output[i][j] = A[i][j] - I.
value * (i == j);
202 template <
typename S,
typename T,
int m,
int... n>
209 template <
typename S,
typename T,
int m,
int... n>
212 constexpr
int dimensions[
sizeof...(n)] = {n...};
213 static_assert(dimensions[
sizeof...(n) - 1] == m);
228 template <
typename S,
typename T,
int m>
231 return I.value *
tr(A);
242 template <
typename T,
int m>
255 template <
typename T,
int m>
269 template <
typename T,
int m>
283 template <
typename T,
int m>
297 template <
typename T,
int m>
310 template <
typename T,
int m>
323 template <
typename T,
int m>
336 template <
typename T,
int m>
346 template <
typename T>
351 return 0.5 * (i - j) * (j - k) * (k - i) * value;
363 template <
typename T,
int m>
368 return c1 * (i == j) * (k == l) + c2 * ((i == k) * (j == l) + (i == l) * (j == k)) * 0.5 +
369 c3 * ((i == k) * (j == l) - (i == l) * (j == k)) * 0.5;
409 template <
typename S,
typename T,
int m>
416 template <
typename S,
typename T,
int m>
419 return isotropic_tensor<decltype(S{} * T{}), m, m, m, m>{I.c1 * scale, I.c2 * scale, I.c3 * scale};
432 template <
typename S,
typename T,
int m>
448 template <
typename S,
typename T,
int m>
465 template <
typename S,
typename T,
int m,
int... n>
468 return I.c1 *
tr(A) * Identity<m>() + I.c2 *
sym(A) + I.c3 *
antisym(A);
#define SERAC_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc and does nothing on a host compi...
Accelerator functionality.
constexpr SERAC_HOST_DEVICE auto tr(const isotropic_tensor< T, m, m > &I)
calculate the trace of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto dot(const isotropic_tensor< S, m, m > &I, const tensor< T, m, n... > &A)
dot product between an isotropic and (nonisotropic) tensor
constexpr SERAC_HOST_DEVICE auto operator*(const dual< gradient_type > &a, double b)
multiplication of a dual number and a non-dual number
constexpr SERAC_HOST_DEVICE auto AntisymmetricIdentity()
a helper function for creating the rank-4 isotropic tensor defined by: d(antisym(A)_{ij}) / d(A_{kl})
Domain operator-(const Domain &a, const Domain &b)
create a new domain that is the set difference of a and b
constexpr SERAC_HOST_DEVICE auto antisym(const isotropic_tensor< T, m, m > &)
return the antisymmetric part of an isotropic tensor
SERAC_HOST_DEVICE auto pow(dual< gradient_type > a, dual< gradient_type > b)
implementation of a (dual) raised to the b (dual) power
constexpr SERAC_HOST_DEVICE auto sym(const isotropic_tensor< T, m, m > &I)
return the symmetric part of an isotropic tensor
SERAC_HOST_DEVICE auto sqrt(dual< gradient_type > x)
implementation of square root for dual numbers
constexpr SERAC_HOST_DEVICE auto operator+(dual< gradient_type > a, double b)
addition of a dual number and a non-dual number
constexpr SERAC_HOST_DEVICE auto double_dot(const isotropic_tensor< S, m, m > &I, const tensor< T, m, m > &A)
double-dot product between an isotropic and (nonisotropic) tensor
constexpr SERAC_HOST_DEVICE auto det(const isotropic_tensor< T, m, m > &I)
compute the determinant of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto norm(const isotropic_tensor< T, m, m > &I)
compute the Frobenius norm (sqrt(tr(dot(transpose(I), I)))) of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto inv(const isotropic_tensor< T, m, m > &I)
return the inverse of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto transpose(const isotropic_tensor< T, m, m > &I)
return the transpose of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto squared_norm(const isotropic_tensor< T, m, m > &I)
compute the squared Frobenius norm (tr(dot(transpose(I), I))) of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto SymmetricIdentity()
a helper function for creating the rank-4 isotropic tensor defined by: d(sym(A)_{ij}) / d(A_{kl})
constexpr SERAC_HOST_DEVICE isotropic_tensor< double, m, m > Identity()
return the identity matrix of the specified size
T value
coefficient of proportionality
constexpr SERAC_HOST_DEVICE T operator()(int i, int j, int k) const
access the (i,j,k) entry of a rank-3 isotropic tensor
there are 3 independent rank-4 isotropic tensors (dilatational, symmetric, antisymmetric),...
T c2
the coefficient on the symmetric identity isotropic tensor
T c1
the coefficient on the dilatational isotropic tensor
T c3
the coefficient on the antisymmetric identity isotropic tensor
constexpr SERAC_HOST_DEVICE T operator()(int i, int j, int k, int l) const
access the (i,j,k,l) entry of a rank-4 isotropic tensor
a rank-2 isotropic tensor is essentially just the Identity matrix, with a constant of proportionality
constexpr SERAC_HOST_DEVICE T operator()(int i, int j) const
access the (i,j) entry of an isotropic matrix
T value
the value on the diagonal
an object representing a highly symmetric kind of tensor, that is interoperable with serac::tensor,...
Arbitrary-rank tensor class.
A sentinel struct for eliding no-op tensor operations.