https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SymmetricRankFourTensor.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12#include "Moose.h"
17#include "MooseUtils.h"
18#include "MathUtils.h"
19
20#include "libmesh/libmesh.h"
21#include "libmesh/tuple_of.h"
22#include "libmesh/int_range.h"
23
24#include "metaphysicl/raw_type.h"
25
26#include <petscsys.h>
27
28// Eigen includes
29#include <Eigen/Core>
30#include <Eigen/Dense>
31
32#include <array>
33
34using libMesh::Real;
36namespace libMesh
37{
38template <typename>
39class TensorValue;
40template <typename>
41class TypeTensor;
42template <typename>
43class VectorValue;
44}
45
46// Forward declarations
47class MooseEnum;
48
49namespace MathUtils
50{
55template <>
57template <>
59}
60
66template <typename T>
68{
69public:
71 static constexpr unsigned int Ndim = LIBMESH_DIM;
72 static constexpr unsigned int N = Ndim + Ndim * (Ndim - 1) / 2;
73 static constexpr unsigned int N2 = N * N;
75
76 // Full tensor indices in the Mandel/Voigt representation
77 static constexpr unsigned int full_index[6][6][4] = {
78 {{0, 0, 0, 0}, {0, 0, 1, 1}, {0, 0, 2, 2}, {0, 0, 1, 2}, {0, 0, 0, 2}, {0, 0, 0, 1}},
79 {{1, 1, 0, 0}, {1, 1, 1, 1}, {1, 1, 2, 2}, {1, 1, 1, 2}, {1, 1, 0, 2}, {1, 1, 0, 1}},
80 {{2, 2, 0, 0}, {2, 2, 1, 1}, {2, 2, 2, 2}, {2, 2, 1, 2}, {2, 2, 0, 2}, {2, 2, 0, 1}},
81 {{1, 2, 0, 0}, {1, 2, 1, 1}, {1, 2, 2, 2}, {1, 2, 1, 2}, {1, 2, 0, 2}, {1, 2, 0, 1}},
82 {{0, 2, 0, 0}, {0, 2, 1, 1}, {0, 2, 2, 2}, {0, 2, 1, 2}, {0, 2, 0, 2}, {0, 2, 0, 1}},
83 {{0, 1, 0, 0}, {0, 1, 1, 1}, {0, 1, 2, 2}, {0, 1, 1, 2}, {0, 1, 0, 2}, {0, 1, 0, 1}}};
84
86 static constexpr Real mandelFactor(unsigned int i, unsigned int j)
87 {
90 }
91
99
106 {
107 symmetric9, // fillSymmetric9FromInputVector
108 symmetric21, // fillSymmetric21FromInputVector
109 symmetric_isotropic, // fillSymmetricIsotropicFromInputVector
110 symmetric_isotropic_E_nu, // fillSymmetricIsotropicEandNu
111 axisymmetric_rz, // fillAxisymmetricRZFromInputVector
112 principal, // fillPrincipalFromInputVector
113 orthotropic // fillGeneralOrthotropicFromInputVector
114 };
115
116 template <template <typename> class Tensor, typename Scalar>
118 {
119 static const bool value = false;
120 };
121 template <typename Scalar>
126 template <typename Scalar>
127 struct TwoTensorMultTraits<TensorValue, Scalar>
128 {
130 };
131 template <typename Scalar>
132 struct TwoTensorMultTraits<TypeTensor, Scalar>
133 {
135 };
136
139
142
144 SymmetricRankFourTensorTempl(const std::vector<T> &, FillMethod);
145
148
152 template <typename T2>
154
157
159 explicit operator RankFourTensorTempl<T>();
160
161 // Named constructors
170
172 inline T & operator()(unsigned int i, unsigned int j) { return _vals[i * N + j]; }
173
178 inline const T & operator()(unsigned int i, unsigned int j) const { return _vals[i * N + j]; }
179
181 void zero();
182
184 void print(std::ostream & stm = Moose::out) const;
185
187 void printReal(std::ostream & stm = Moose::out) const;
188
189 friend std::ostream & operator<<(std::ostream & os, const SymmetricRankFourTensorTempl<T> & t)
190 {
191 t.print(os);
192 return os;
193 }
194
197
203 template <typename Scalar>
204 typename std::enable_if<libMesh::ScalarTraits<Scalar>::value,
206 operator=(const Scalar & libmesh_dbg_var(p))
207 {
208 libmesh_assert_equal_to(p, Scalar(0));
209 this->zero();
210 return *this;
211 }
212
214 template <typename T2>
215 auto operator*(const SymmetricRankTwoTensorTempl<T2> & b) const
216 -> SymmetricRankTwoTensorTempl<decltype(T() * T2())>;
217
219 template <typename T2>
220 auto operator*(const T2 & a) const ->
221 typename std::enable_if<libMesh::ScalarTraits<T2>::value,
222 SymmetricRankFourTensorTempl<decltype(T() * T2())>>::type;
223
226
228 template <typename T2>
229 auto operator/(const T2 & a) const ->
230 typename std::enable_if<libMesh::ScalarTraits<T2>::value,
231 SymmetricRankFourTensorTempl<decltype(T() / T2())>>::type;
232
235
238
240 template <typename T2>
241 auto operator+(const SymmetricRankFourTensorTempl<T2> & a) const
242 -> SymmetricRankFourTensorTempl<decltype(T() + T2())>;
243
246
248 template <typename T2>
249 auto operator-(const SymmetricRankFourTensorTempl<T2> & a) const
250 -> SymmetricRankFourTensorTempl<decltype(T() - T2())>;
251
254
256 template <typename T2>
257 auto operator*(const SymmetricRankFourTensorTempl<T2> & a) const
258 -> SymmetricRankFourTensorTempl<decltype(T() * T2())>;
259
261 T L2norm() const;
262
268
275 static SymmetricRankFourTensorTempl<T> rotationMatrix(const TypeTensor<T> & R);
276
281 void rotate(const TypeTensor<T> & R);
282
289
294
296 static MooseEnum fillMethodEnum();
297
304 void fillFromInputVector(const std::vector<T> & input, FillMethod fill_method);
305
307 void fillSymmetricIsotropic(const T & i0, const T & i1);
308 void fillSymmetricIsotropicEandNu(const T & E, const T & nu);
310
321 template <typename T2>
322 void fillSymmetric9FromInputVector(const T2 & input);
323
332 template <typename T2>
333 void fillSymmetric21FromInputVector(const T2 & input);
334
336 T sum3x3() const;
337
340
342 bool isSymmetric() const;
343
345 bool isIsotropic() const;
346
347protected:
349 std::array<T, N2> _vals;
350
358 void fillSymmetricIsotropicFromInputVector(const std::vector<T> & input);
359
369 void fillSymmetricIsotropicEandNuFromInputVector(const std::vector<T> & input);
370
378 void fillAxisymmetricRZFromInputVector(const std::vector<T> & input);
379
394 void fillPrincipalFromInputVector(const std::vector<T> & input);
395
402 void fillGeneralOrthotropicFromInputVector(const std::vector<T> & input);
403
404 template <class T2>
405 friend void dataStore(std::ostream &, SymmetricRankFourTensorTempl<T2> &, void *);
406
407 template <class T2>
408 friend void dataLoad(std::istream &, SymmetricRankFourTensorTempl<T2> &, void *);
409
410 template <typename T2>
412 template <typename T2>
414 template <typename T2>
416};
417
418namespace MetaPhysicL
419{
420template <typename T>
422{
424
426 {
427 value_type ret;
428 for (unsigned int i = 0; i < SymmetricRankFourTensorTempl<T>::N; ++i)
429 for (unsigned int j = 0; j < SymmetricRankFourTensorTempl<T>::N; ++j)
430 ret(i, j) = raw_value(in(i, j));
431
432 return ret;
433 }
434};
435}
436
437template <typename T1, typename T2>
438inline auto
440 typename std::enable_if<libMesh::ScalarTraits<T1>::value,
441 SymmetricRankFourTensorTempl<decltype(T1() * T2())>>::type
442{
443 return b * a;
444}
445
446template <typename T>
447template <typename T2>
450{
451 for (const auto i : make_range(N2))
452 _vals[i] = copy._vals[i];
453}
454
455template <typename T>
456template <typename T2>
457auto
459 typename std::enable_if<libMesh::ScalarTraits<T2>::value,
460 SymmetricRankFourTensorTempl<decltype(T() * T2())>>::type
461{
462 typedef decltype(T() * T2()) ValueType;
464
465 for (const auto i : make_range(N2))
466 result._vals[i] = _vals[i] * b;
467
468 return result;
469}
470
471template <typename T>
472template <typename T2>
473auto
475 -> SymmetricRankTwoTensorTempl<decltype(T() * T2())>
476{
477 typedef decltype(T() * T2()) ValueType;
479
480 std::size_t index = 0;
481 for (const auto i : make_range(N))
482 {
483 ValueType tmp = 0.0;
484 for (const auto j : make_range(N))
485 tmp += _vals[index++] * b._vals[j];
486 result._vals[i] = tmp;
487 }
488
489 return result;
490}
491
492template <typename T>
493template <typename T2>
494auto
496 typename std::enable_if<libMesh::ScalarTraits<T2>::value,
497 SymmetricRankFourTensorTempl<decltype(T() / T2())>>::type
498{
499 SymmetricRankFourTensorTempl<decltype(T() / T2())> result;
500 for (const auto i : make_range(N2))
501 result._vals[i] = _vals[i] / b;
502 return result;
503}
504
505template <typename T>
506template <typename T2>
507void
509{
510 mooseAssert(LIBMESH_DIM == 3, "This method assumes LIBMESH_DIM == 3");
511 mooseAssert(input.size() == 9,
512 "To use fillSymmetric9FromInputVector, your input must have size 9.");
513 zero();
514
515 _vals[0] = input[0]; // C1111
516 _vals[7] = input[3]; // C2222
517 _vals[14] = input[5]; // C3333
518
519 _vals[1] = _vals[6] = input[1]; // C1122
520 _vals[2] = _vals[12] = input[2]; // C1133
521 _vals[8] = _vals[13] = input[4]; // C2233
522
523 static constexpr std::size_t C2323 = 21;
524 static constexpr std::size_t C1313 = 28;
525 static constexpr std::size_t C1212 = 35;
526
527 _vals[C2323] = 2.0 * input[6];
528 _vals[C1313] = 2.0 * input[7];
529 _vals[C1212] = 2.0 * input[8];
530}
531
532template <typename T>
533template <typename T2>
534void
536{
537 // C1111 C1122 C1133 C1123 C1113 C1112
538 // C2222 C2233 C2223 C2213 C2212
539 // C3333 C3323 C3313 C3312
540 // C2323 C2313 C2312
541 // C1313 C1312
542 // C1212
543
544 mooseAssert(LIBMESH_DIM == 3, "This method assumes LIBMESH_DIM == 3");
545 mooseAssert(input.size() == 21,
546 "To use fillSymmetric21FromInputVector, your input must have size 21.");
547 std::size_t index = 0;
548 for (const auto i : make_range(N))
549 for (const auto j : make_range(i, N))
550 {
551 _vals[i + N * j] = mandelFactor(i, j) * input[index];
552 _vals[j + N * i] = mandelFactor(j, i) * input[index];
553 index++;
554 }
555}
556
557template <typename T>
560{
561 SymmetricRankFourTensorTempl<T> result(initNone);
562
563 if constexpr (SymmetricRankFourTensorTempl<T>::N2 * sizeof(T) > EIGEN_STACK_ALLOCATION_LIMIT)
564 {
565 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> mat(N, N);
566 for (const auto i : make_range(N))
567 for (const auto j : make_range(N))
568 mat(i, j) = (*this)(i, j);
569 mat = mat.inverse();
570 for (const auto i : make_range(N))
571 for (const auto j : make_range(N))
572 result(i, j) = mat(i, j);
573 }
574 else
575 {
576 const Eigen::Map<const Eigen::Matrix<T, N, N, Eigen::RowMajor>> mat(&_vals[0]);
577 Eigen::Map<Eigen::Matrix<T, N, N, Eigen::RowMajor>> res(&result._vals[0]);
578 res = mat.inverse();
579 }
580
581 return result;
582}
auto operator*(const T1 &a, const SymmetricRankFourTensorTempl< T2 > &b) -> typename std::enable_if< libMesh::ScalarTraits< T1 >::value, SymmetricRankFourTensorTempl< decltype(T1() *T2())> >::type
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
RankThreeTensor is designed to handle any N-dimensional third order tensor, r.
SymmetricRankFourTensorTempl is designed to handle an N-dimensional fourth order tensor with minor sy...
std::enable_if< libMesh::ScalarTraits< Scalar >::value, SymmetricRankFourTensorTempl & >::type operator=(const Scalar &libmesh_dbg_var(p))
Assignment-from-scalar operator.
void fillSymmetricIsotropicFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicFromInputVector takes 2 inputs to fill the the symmetric Rank-4 tensor with the...
static constexpr unsigned int N
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method)
fillFromInputVector takes some number of inputs to fill the Rank-4 tensor.
SymmetricRankFourTensorTempl< T > transposeMajor() const
Transpose the tensor by swapping the first pair with the second pair of indices This amounts to a reg...
T & operator()(unsigned int i, unsigned int j)
Gets the value for the indices specified. Takes indices ranging from 0-5 for i and j.
void fillSymmetricIsotropic(const T &i0, const T &i1)
Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.
void fillAxisymmetricRZFromInputVector(const std::vector< T > &input)
fillAxisymmetricRZFromInputVector takes 5 inputs to fill the axisymmetric Rank-4 tensor with the appr...
friend void dataLoad(std::istream &, SymmetricRankFourTensorTempl< T2 > &, void *)
SymmetricRankFourTensorTempl< T > operator-() const
-C_ijkl
void printReal(std::ostream &stm=Moose::out) const
Print the values of the rank four tensor.
static constexpr unsigned int full_index[6][6][4]
libMesh::VectorValue< T > sum3x1() const
Calculates the vector a[i] = sum over j Ciijj for i and j varying from 0 to 2.
void fillGeneralOrthotropicFromInputVector(const std::vector< T > &input)
fillGeneralOrhotropicFromInputVector takes 10 inputs to fill the Rank-4 tensor It defines a general o...
SymmetricRankFourTensorTempl< T > & operator+=(const SymmetricRankFourTensorTempl< T > &a)
C_ijkl += a_ijkl for all i, j, k, l.
static MooseEnum fillMethodEnum()
Static method for use in validParams for getting the "fill_method".
SymmetricRankFourTensorTempl< T > transposeIj() const
Transpose the tensor by swapping the first two indices - a no-op.
void fillSymmetric9FromInputVector(const T2 &input)
fillSymmetric9FromInputVector takes 9 inputs to fill in the Rank-4 tensor with the appropriate crysta...
auto operator+(const SymmetricRankFourTensorTempl< T2 > &a) const -> SymmetricRankFourTensorTempl< decltype(T()+T2())>
C_ijkl + a_ijkl.
bool isIsotropic() const
checks if the tensor is isotropic
auto operator*(const SymmetricRankTwoTensorTempl< T2 > &b) const -> SymmetricRankTwoTensorTempl< decltype(T() *T2())>
C_ijkl*a_kl.
void fillPrincipalFromInputVector(const std::vector< T > &input)
fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C11...
void fillSymmetricIsotropicEandNu(const T &E, const T &nu)
void print(std::ostream &stm=Moose::out) const
Print the rank four tensor.
friend void dataStore(std::ostream &, SymmetricRankFourTensorTempl< T2 > &, void *)
static SymmetricRankFourTensorTempl< T > rotationMatrix(const TypeTensor< T > &R)
Build a 6x6 rotation matrix MEHRABADI, MORTEZA M.; COWIN, STEPHEN C.
static SymmetricRankFourTensorTempl< T > identitySymmetricFour()
friend std::ostream & operator<<(std::ostream &os, const SymmetricRankFourTensorTempl< T > &t)
void rotate(const TypeTensor< T > &R)
Rotate the tensor using C_ijkl = R_im R_jn R_ko R_lp C_mnop.
SymmetricRankFourTensorTempl< T > & operator=(const SymmetricRankFourTensorTempl< T > &a)=default
copies values from a into this tensor
const T & operator()(unsigned int i, unsigned int j) const
Gets the value for the indices specified.
std::array< T, N2 > _vals
The values of the rank-four tensor.
static constexpr unsigned int Ndim
tensor dimension, Mandel matrix dimension, and Mandel matrix size
void fillSymmetric21FromInputVector(const T2 &input)
fillSymmetric21FromInputVector takes 21 inputs to fill in the Rank-4 tensor with the appropriate crys...
T sum3x3() const
Calculates the sum of Ciijj for i and j varying from 0 to 2.
bool isSymmetric() const
checks if the tensor is symmetric
SymmetricRankFourTensorTempl(const SymmetricRankFourTensorTempl< T > &a)=default
Copy assignment operator must be defined if used.
auto operator/(const T2 &a) const -> typename std::enable_if< libMesh::ScalarTraits< T2 >::value, SymmetricRankFourTensorTempl< decltype(T()/T2())> >::type
C_ijkl/a.
static constexpr Real mandelFactor(unsigned int i, unsigned int j)
returns the 1, sqrt(2), or 2 prefactor in the Mandel notation for the indices i,j ranging from 0-5.
SymmetricRankFourTensorTempl< T > & operator/=(const T &a)
C_ijkl /= a for all i, j, k, l.
static SymmetricRankFourTensorTempl< T > identity()
SymmetricRankFourTensorTempl< T > invSymm() const
This returns A_ijkl such that C_ijkl*A_klmn = 0.5*(de_im de_jn + de_in de_jm) This routine assumes th...
static constexpr unsigned int N2
FillMethod
To fill up the 36 entries in the 4th-order tensor, fillFromInputVector is called with one of the foll...
SymmetricRankFourTensorTempl< T > & operator*=(const T &a)
C_ijkl *= a.
void fillSymmetricIsotropicEandNuFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicEandNuFromInputVector is a variation of the fillSymmetricIsotropicFromInputVect...
SymmetricRankFourTensorTempl< T > & operator-=(const SymmetricRankFourTensorTempl< T > &a)
C_ijkl -= a_ijkl.
SymmetricRankTwoTensorTempl is designed to handle the Stress or Strain Tensor for an anisotropic mate...
static constexpr Real mandelFactor(unsigned int i)
returns the 1 or sqrt(2) prefactor in the Mandel notation for the index i ranging from 0-5.
void mooseSetToZero< ADSymmetricRankFourTensor >(ADSymmetricRankFourTensor &v)
void mooseSetToZero< SymmetricRankFourTensor >(SymmetricRankFourTensor &v)
Helper function template specialization to set an object to zero.
We need to instantiate the following CompareTypes to tell the compiler that ADReal is a subtype of Ch...
auto raw_value(const Eigen::Map< T > &in)
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
typename tuple_n< Index, T >::template type<> tuple_of
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static value_type value(const SymmetricRankFourTensorTempl< T > &in)
SymmetricRankFourTensorTempl< typename RawType< T >::value_type > value_type