23#include "libmesh/libmesh.h"
24#include "libmesh/vector_value.h"
25#include "libmesh/utility.h"
28#include <petscblaslapack.h>
37constexpr std::array<Real, SymmetricRankTwoTensorTempl<T>::N>
52 return MooseEnum(
"autodetect=0 isotropic1=1 diagonal3=3 symmetric6=6",
"autodetect");
58 std::fill(_vals.begin(), _vals.end(), 0.0);
74 mooseError(
"Unknown SymmetricRankTwoTensorTempl initialization pattern.");
80 const T & S11,
const T & S22,
const T & S33,
const T & S23,
const T & S13,
const T & S12)
85 _vals[3] = mandelFactor(3) * S23;
86 _vals[4] = mandelFactor(4) * S13;
87 _vals[5] = mandelFactor(5) * S12;
94 _vals[5] / mandelFactor(5),
95 _vals[4] / mandelFactor(4),
96 _vals[5] / mandelFactor(5),
98 _vals[3] / mandelFactor(3),
99 _vals[4] / mandelFactor(4),
100 _vals[3] / mandelFactor(3),
118 _vals[3] = (S23 + S32) / mandelFactor(3);
119 _vals[4] = (S13 + S31) / mandelFactor(4);
120 _vals[5] = (S12 + S21) / mandelFactor(5);
126 const T & S11,
const T & S22,
const T & S33,
const T & S23,
const T & S13,
const T & S12)
144 _vals[3] = (a(1, 2) + a(2, 1)) / mandelFactor(3);
145 _vals[4] = (a(0, 2) + a(2, 0)) / mandelFactor(4);
146 _vals[5] = (a(0, 1) + a(1, 0)) / mandelFactor(5);
155 _vals[3] = (a(1, 2) + a(2, 1)) / mandelFactor(3);
156 _vals[4] = (a(0, 2) + a(2, 0)) / mandelFactor(4);
157 _vals[5] = (a(0, 1) + a(1, 0)) / mandelFactor(5);
164 const TypeVector<T> & v1,
165 const TypeVector<T> & v2)
168 v0(0), v1(0), v2(0), v0(1), v1(1), v2(1), v0(2), v1(2), v2(2));
176 if (fill_method != autodetect && fill_method != input.size())
177 mooseError(
"Expected an input vector size of ",
179 " to fill the SymmetricRankTwoTensorTempl");
181 switch (input.size())
205 _vals[3] = mandelFactor(3) * input[3];
206 _vals[4] = mandelFactor(4) * input[4];
207 _vals[5] = mandelFactor(5) * input[5];
211 mooseError(
"Please check the number of entries in the input vector for building "
212 "a SymmetricRankTwoTensorTempl. It must be 1, 3, 6");
220 switch (scalar_variable.
size())
223 _vals[0] = scalar_variable[0];
232 _vals[0] = scalar_variable[0];
233 _vals[1] = scalar_variable[1];
237 _vals[5] = mandelFactor(5) * scalar_variable[2];
241 _vals[0] = scalar_variable[0];
242 _vals[1] = scalar_variable[1];
243 _vals[2] = scalar_variable[2];
244 _vals[3] = mandelFactor(3) * scalar_variable[3];
245 _vals[4] = mandelFactor(4) * scalar_variable[4];
246 _vals[5] = mandelFactor(5) * scalar_variable[5];
250 mooseError(
"Only FIRST, THIRD, or SIXTH order scalar variable can be used to build "
251 "a SymmetricRankTwoTensorTempl.");
279 _vals[0], _vals[5] / mandelFactor(5), _vals[4] / mandelFactor(4));
282 _vals[5] / mandelFactor(5), _vals[1], _vals[3] / mandelFactor(3));
285 _vals[4] / mandelFactor(4), _vals[3] / mandelFactor(3), _vals[2]);
296 a(1, 0) * a(1, 0) + a(1, 1) * a(1, 1) + a(1, 2) * a(1, 2),
297 a(2, 0) * a(2, 0) + a(2, 1) * a(2, 1) + a(2, 2) * a(2, 2),
298 a(1, 0) * a(2, 0) + a(1, 1) * a(2, 1) + a(1, 2) * a(2, 2),
299 a(0, 0) * a(2, 0) + a(0, 1) * a(2, 1) + a(0, 2) * a(2, 2),
300 a(0, 0) * a(1, 0) + a(0, 1) * a(1, 1) + a(0, 2) * a(1, 2));
324 a(0, 1) * a(0, 1) + a(1, 1) * a(1, 1) + a(2, 1) * a(2, 1),
325 a(0, 2) * a(0, 2) + a(1, 2) * a(1, 2) + a(2, 2) * a(2, 2),
326 a(0, 1) * a(0, 2) + a(1, 1) * a(1, 2) + a(2, 1) * a(2, 2),
327 a(0, 0) * a(0, 2) + a(1, 0) * a(1, 2) + a(2, 0) * a(2, 2),
328 a(0, 0) * a(0, 1) + a(1, 0) * a(1, 1) + a(2, 0) * a(2, 1));
335 return timesTranspose(a);
343 a(0, 0), a(0, 1), a(0, 2), a(1, 0), a(1, 1), a(1, 2), a(2, 0), a(2, 1), a(2, 2)) *
365 for (std::size_t i = 0; i < N; ++i)
373 for (std::size_t i = 0; i < N; ++i)
374 _vals[i] += a.
_vals[i];
382 for (std::size_t i = 0; i < N; ++i)
383 _vals[i] -= a.
_vals[i];
388template <
typename T2>
393 for (std::size_t i = 0; i < N; ++i)
394 result(i) = _vals[i] + a(i);
399template <
typename T2>
405 for (std::size_t i = 0; i < N; ++i)
406 result(i) = _vals[i] - a(i);
415 return (*
this) * -1.0;
422 for (std::size_t i = 0; i < N; ++i)
431 for (std::size_t i = 0; i < N; ++i)
441 for (
unsigned int i = 0; i < N; ++i)
442 sum += _vals[i] * b.
_vals[i];
451 unsigned int index = 0;
452 for (
unsigned int i = 0; i < N; ++i)
454 const T & a = _vals[i];
455 for (
unsigned int j = 0; j < N; ++j)
466 deviatoric.
addIa(-1.0 / 3.0 * this->tr());
474 return _vals[0] * _vals[1] + _vals[0] * _vals[2] + _vals[1] * _vals[2] -
475 (_vals[3] * _vals[3] + _vals[4] * _vals[4] + _vals[5] * _vals[5]) / 2.0;
483 result = Utility::pow<2>(_vals[0] - _vals[1]) / 6.0;
484 result += Utility::pow<2>(_vals[0] - _vals[2]) / 6.0;
485 result += Utility::pow<2>(_vals[1] - _vals[2]) / 6.0;
486 result += Utility::pow<2>(_vals[5]) / 2.0;
487 result += Utility::pow<2>(_vals[4]) / 2.0;
488 result += Utility::pow<2>(_vals[3]) / 2.0;
505 for (
auto i : make_range(N))
506 for (
auto j : make_range(N))
507 result(i, j) = 0.5 * (i == j) + 0.5 * (i == j) - (1.0 / 3.0) * (i < 3) * (j < 3);
523 const auto d = det();
525 mooseException(
"Matrix not invertible");
527 _vals[2] * _vals[1] - _vals[3] * _vals[3] / 2.0,
528 _vals[2] * _vals[0] - _vals[4] * _vals[4] / 2.0,
529 _vals[0] * _vals[1] - _vals[5] * _vals[5] / 2.0,
533 return inv * 1.0 / d;
560 const T s3 = secondInvariant() / 3.0;
562 s(0) * s(2) - s(4) * s(4) / 2.0 + s3,
563 s(0) * s(1) - s(5) * s(5) / 2.0 + s3,
576 for (
auto i : make_range(N))
577 for (
auto j : make_range(N))
594 d2(3, 3) -= s(0) / 2.0;
600 d2(4, 4) -= s(1) / 2.0;
606 d2(5, 5) -= s(2) / 2.0;
608 for (
auto i : make_range(N))
609 for (
auto j : make_range(N))
619 return _vals[0] * (_vals[2] * _vals[1] - _vals[3] * _vals[3] / 2.0) -
631 _vals[2] * _vals[1] - _vals[3] * _vals[3] / 2.0,
632 _vals[0] * _vals[2] - _vals[4] * _vals[4] / 2.0,
633 _vals[0] * _vals[1] - _vals[5] * _vals[5] / 2.0,
643 for (std::size_t i = 0; i < N; ++i)
644 stm << std::setw(15) << _vals[i] << std::endl;
651 for (std::size_t i = 0; i < N; ++i)
659 for (
unsigned int i = 0; i < 3; ++i)
667 T norm = _vals[0] * _vals[0];
668 for (
unsigned int i = 1; i < N; ++i)
669 norm += _vals[i] * _vals[i];
671 return norm == 0.0 ? 0.0 : sqrt(norm);
678 mooseError(
"The syev method is only supported for Real valued tensors");
683 std::vector<Real> & eigvals,
684 std::vector<Real> & a)
const;
691 symmetricEigenvaluesEigenvectors(eigvals, a);
703 "symmetricEigenvaluesEigenvectors is only available for ordered tensor component types");
730 v(0) * v(0), v(1) * v(1), v(2) * v(2), v(1) * v(2), v(0) * v(2), v(0) * v(1));
738 for (
auto i : make_range(N))
739 for (
auto j : make_range(N))
740 result(j) += (*this)(i)*b(i, j);
748 std::copy(identityCoords.begin(), identityCoords.end(), _vals.begin());
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
unsigned int size() const
The number of elements that can currently be stored in the array.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
static Real rand()
This method returns the next random number (Real format) from the generator.
static void seed(unsigned int seed)
The method seeds the random number generator.
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
SymmetricRankFourTensorTempl is designed to handle an N-dimensional fourth order tensor with minor sy...
static SymmetricRankFourTensorTempl< T > rotationMatrix(const TypeTensor< T > &R)
Build a 6x6 rotation matrix MEHRABADI, MORTEZA M.; COWIN, STEPHEN C.
std::array< T, N2 > _vals
The values of the rank-four tensor.
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.
SymmetricRankTwoTensorTempl is designed to handle the Stress or Strain Tensor for an anisotropic mate...
FillMethod
To fill up the 6 entries in the 2nd-order tensor, fillFromInputVector is called with one of the follo...
T generalSecondInvariant() const
Calculates the second invariant (I2) of a tensor.
libMesh::VectorValue< T > row(const unsigned int n) const
get the specified row of the tensor
void rotate(const TypeTensor< T > &R)
rotates the tensor data given a rank two tensor rotation tensor _vals[i][j] = R_ij * R_jl * _vals[k][...
SymmetricRankTwoTensorTempl< T > deviatoric() const
returns A_ij - de_ij*tr(A)/3, where A are the _vals
SymmetricRankTwoTensorTempl< T > dsecondInvariant() const
Denote the _vals[i][j] by A_ij, then this returns d(secondInvariant)/dA_ij.
void syev(const char *calculation_type, std::vector< T > &eigvals, std::vector< T > &a) const
Uses the petscblaslapack.h LAPACKsyev_ routine to find, for symmetric _vals: (1) the eigenvalues (if ...
void symmetricEigenvaluesEigenvectors(std::vector< T > &eigvals, RankTwoTensorTempl< T > &eigvecs) const
computes eigenvalues and eigenvectors, assuming tens is symmetric, and places them in ascending order...
SymmetricRankFourTensorTempl< T > d2secondInvariant() const
Denote the _vals[i][j] by A_ij, then this returns d^2(secondInvariant)/dA_ij/dA_kl.
T L2norm() const
Sqrt(_vals[i][j]*_vals[i][j])
void fillFromScalarVariable(const VariableValue &scalar_variable)
fillFromScalarVariable takes FIRST/THIRD/SIXTH order scalar variable to fill in the Rank-2 tensor.
SymmetricRankTwoTensorTempl< T > initialContraction(const SymmetricRankFourTensorTempl< T > &b) const
returns this_ij * b_ijkl
SymmetricRankTwoTensorTempl< T > transpose() const
Returns a matrix that is the transpose of the matrix this was called on.
SymmetricRankFourTensorTempl< T > d2thirdInvariant() const
Denote the _vals[i][j] by A_ij, then this returns d^2(thirdInvariant)/dA_ij/dA_kl.
SymmetricRankTwoTensorTempl< T > operator-() const
returns -_vals
SymmetricRankTwoTensorTempl< T > dthirdInvariant() const
Denote the _vals[i][j] by A_ij, then this returns d(thirdInvariant()/dA_ij.
static void initRandom(unsigned int)
This function initializes random seed based on a user-defined number.
static SymmetricRankTwoTensorTempl< T > selfOuterProduct(const TypeVector< T > &)
SymmetricRankTwoTensorTempl<T> from outer product of a vector with itself.
SymmetricRankTwoTensorTempl< T > & operator/=(const T &a)
performs _vals /= a
SymmetricRankTwoTensorTempl< T > & operator*=(const T &a)
performs _vals *= a
static SymmetricRankTwoTensorTempl< T > timesTranspose(const RankTwoTensorTempl< T > &)
return the matrix multiplied with its transpose A*A^T (guaranteed symmetric)
SymmetricRankTwoTensorTempl< typename libMesh::CompareTypes< T, T2 >::supertype > operator+(const SymmetricRankTwoTensorTempl< T2 > &a) const
returns _vals + a
T doubleContraction(const SymmetricRankTwoTensorTempl< T > &a) const
returns _vals_ij * a_ij (sum on i, j)
SymmetricRankTwoTensorTempl< T > inverse() const
retuns the inverse of the tensor
void addIa(const T &a)
Add identity times a to _vals.
static SymmetricRankTwoTensorTempl< T > genRandomSymmTensor(T, T)
This function generates a random symmetric rank two tensor.
SymmetricRankFourTensorTempl< T > outerProduct(const SymmetricRankTwoTensorTempl< T > &a) const
returns C_ijkl = a_ij * b_kl
SymmetricRankTwoTensorTempl< T > dtrace() const
Denote the _vals[i][j] by A_ij, then this returns d(trace)/dA_ij.
void print(std::ostream &stm=Moose::out) const
Print the rank two tensor.
static MooseEnum fillMethodEnum()
Static method for use in validParams for getting the "fill_method".
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method=autodetect)
fillFromInputVector takes 1, 3, or 6 inputs to fill in the symmmetric Rank-2 tensor.
SymmetricRankTwoTensorTempl< T > square() const
Returns the matrix squared.
SymmetricRankTwoTensorTempl< T > ddet() const
Denote the _vals[i][j] by A_ij, then this returns d(det)/dA_ij.
SymmetricRankTwoTensorTempl< T > & operator+=(const SymmetricRankTwoTensorTempl< T > &a)
adds a to _vals
void zero()
Set all components to zero.
T thirdInvariant() const
Denote the _vals[i][j] by A_ij, then S_ij = A_ij - de_ij*tr(A)/3 Then this returns det(S + S....
void printReal(std::ostream &stm=Moose::out) const
Print the Real part of the ADReal rank two tensor.
static SymmetricRankTwoTensorTempl< T > plusTranspose(const RankTwoTensorTempl< T > &)
return the matrix plus its transpose A-A^T (guaranteed symmetric)
T secondInvariant() const
Denote the _vals[i][j] by A_ij, then S_ij = A_ij - de_ij*tr(A)/3 Then this returns (S_ij + S_ji)*(S_i...
SymmetricRankTwoTensorTempl< T > & operator-=(const SymmetricRankTwoTensorTempl< T > &a)
sets _vals -= a and returns vals
T trace() const
returns the trace of the tensor, ie _vals[i][i] (sum i = 0, 1, 2)
static SymmetricRankTwoTensorTempl fromRawComponents(const T &S11, const T &S22, const T &S33, const T &S23, const T &S13, const T &S12)
static SymmetricRankTwoTensorTempl< T > transposeTimes(const RankTwoTensorTempl< T > &)
return the matrix multiplied with its transpose A^T*A (guaranteed symmetric)
void setToIdentity()
set the tensor to the identity matrix
SymmetricRankTwoTensorTempl()
Default constructor; fills to zero.
void symmetricEigenvalues(std::vector< T > &eigvals) const
computes eigenvalues, assuming tens is symmetric, and places them in ascending order in eigvals
static SymmetricRankTwoTensorTempl initializeSymmetric(const TypeVector< T > &v0, const TypeVector< T > &v1, const TypeVector< T > &v2)
named constructor for initializing symmetrically
void mooseSetToZero< SymmetricRankTwoTensor >(SymmetricRankTwoTensor &v)
Helper function template specialization to set an object to zero.
void mooseSetToZero< ADSymmetricRankTwoTensor >(ADSymmetricRankTwoTensor &v)
Helper function template specialization to set an object to zero.
static constexpr Real sqrt2
std::sqrt is not constexpr, so we add sqrt(2) as a constant (used in Mandel notation)