Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
isotropic_tensor.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2023, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
15 #pragma once
16 
17 #include <iostream>
18 #include <type_traits>
19 
20 namespace serac {
21 
31 template <typename T, int... n>
33 
38 template <typename T, int n>
39 struct isotropic_tensor<T, n> {
40  static_assert(::detail::always_false<T>{}, "error: there is no such thing as a rank-1 isotropic tensor!");
41 };
42 
48 template <typename T, int m>
49 struct isotropic_tensor<T, m, m> {
51  SERAC_HOST_DEVICE constexpr T operator()(int i, int j) const { return (i == j) * value; }
52 
53  T value;
54 };
55 
60 template <int m>
62 {
64 }
65 
76 template <typename S, typename T, int m>
78 {
79  return isotropic_tensor<decltype(S{} * T{}), m, m>{I.value * scale};
80 }
81 
83 template <typename S, typename T, int m>
85 {
86  return isotropic_tensor<decltype(S{}, T{}), m, m>{I.value * scale};
87 }
88 
99 template <typename S, typename T, int m>
101 {
102  return isotropic_tensor<decltype(S{} + T{}), m, m>{I1.value + I2.value};
103 }
104 
115 template <typename S, typename T, int m>
117 {
118  return isotropic_tensor<decltype(S{} - T{}), m, m>{I1.value - I2.value};
119 }
120 
131 template <typename S, typename T, int m>
133 {
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];
138  }
139  }
140  return output;
141 }
142 
144 template <typename S, typename T, int m>
146 {
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);
151  }
152  }
153  return output;
154 }
155 
166 template <typename S, typename T, int m>
168 {
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];
173  }
174  }
175  return output;
176 }
177 
179 template <typename S, typename T, int m>
181 {
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);
186  }
187  }
188  return output;
189 }
190 
202 template <typename S, typename T, int m, int... n>
204 {
205  return I.value * A;
206 }
207 
209 template <typename S, typename T, int m, int... n>
211 {
212  constexpr int dimensions[sizeof...(n)] = {n...};
213  static_assert(dimensions[sizeof...(n) - 1] == m);
214  return A * I.value;
215 }
216 
228 template <typename S, typename T, int m>
230 {
231  return I.value * tr(A);
232 }
233 
242 template <typename T, int m>
244 {
245  return I;
246 }
247 
255 template <typename T, int m>
257 {
258  return zero{};
259 }
260 
269 template <typename T, int m>
271 {
272  return I.value * m;
273 }
274 
283 template <typename T, int m>
285 {
286  return I;
287 }
288 
297 template <typename T, int m>
299 {
300  return isotropic_tensor<T, m, m>{1.0 / I.value};
301 }
302 
310 template <typename T, int m>
312 {
313  return std::pow(I.value, m);
314 }
315 
323 template <typename T, int m>
325 {
326  return sqrt(I.value * I.value * m);
327 }
328 
336 template <typename T, int m>
338 {
339  return I.value * I.value * m;
340 }
341 
346 template <typename T>
347 struct isotropic_tensor<T, 3, 3, 3> {
349  SERAC_HOST_DEVICE constexpr T operator()(int i, int j, int k) const
350  {
351  return 0.5 * (i - j) * (j - k) * (k - i) * value;
352  }
353 
354  T value;
355 };
356 
363 template <typename T, int m>
364 struct isotropic_tensor<T, m, m, m, m> {
366  SERAC_HOST_DEVICE constexpr T operator()(int i, int j, int k, int l) const
367  {
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;
370  }
371 
372  T c1;
373  T c2;
374  T c3;
375 };
376 
382 template <int m>
384 {
385  return isotropic_tensor<double, m, m, m, m>{0.0, 1.0, 0.0};
386 }
387 
393 template <int m>
395 {
396  return isotropic_tensor<double, m, m, m, m>{0.0, 0.0, 1.0};
397 }
398 
409 template <typename S, typename T, int m>
411 {
412  return isotropic_tensor<decltype(S{} * T{}), m, m, m, m>{I.c1 * scale, I.c2 * scale, I.c3 * scale};
413 }
414 
416 template <typename S, typename T, int m>
418 {
419  return isotropic_tensor<decltype(S{} * T{}), m, m, m, m>{I.c1 * scale, I.c2 * scale, I.c3 * scale};
420 }
421 
432 template <typename S, typename T, int m>
434 {
435  return isotropic_tensor<decltype(S{} + T{}), m, m, m, m>{I1.c1 + I2.c1, I1.c2 + I2.c2, I1.c3 + I2.c3};
436 }
437 
448 template <typename S, typename T, int m>
450 {
451  return isotropic_tensor<decltype(S{} - T{}), m, m, m, m>{I1.c1 - I2.c1, I1.c2 - I2.c2, I1.c3 - I2.c3};
452 }
453 
465 template <typename S, typename T, int m, int... n>
467 {
468  return I.c1 * tr(A) * Identity<m>() + I.c2 * sym(A) + I.c3 * antisym(A);
469 }
470 
471 } // namespace serac
#define SERAC_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc and does nothing on a host compi...
Definition: accelerator.hpp:38
Accelerator functionality.
Definition: serac.cpp:38
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
Definition: dual.hpp:109
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
Definition: domain.cpp:500
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
Definition: dual.hpp:376
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
Definition: dual.hpp:279
constexpr SERAC_HOST_DEVICE auto operator+(dual< gradient_type > a, double b)
addition of a dual number and a non-dual number
Definition: dual.hpp:60
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.
Definition: tensor.hpp:29
A sentinel struct for eliding no-op tensor operations.
Definition: tensor.hpp:123