LCOV - code coverage report
Current view: top level - include/utils - SymmetricRankTwoTensorImplementation.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 8601ad Lines: 331 383 86.4 %
Date: 2025-07-18 13:27:08 Functions: 53 179 29.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "SymmetricRankTwoTensor.h"
      13             : 
      14             : // MOOSE includes
      15             : #include "MooseEnum.h"
      16             : #include "ColumnMajorMatrix.h"
      17             : #include "MooseRandom.h"
      18             : #include "SymmetricRankFourTensor.h"
      19             : #include "Conversion.h"
      20             : #include "MooseArray.h"
      21             : #include "MathUtils.h"
      22             : 
      23             : #include "libmesh/libmesh.h"
      24             : #include "libmesh/vector_value.h"
      25             : #include "libmesh/utility.h"
      26             : 
      27             : // PETSc includes
      28             : #include <petscblaslapack.h>
      29             : 
      30             : // C++ includes/sqrt
      31             : #include <iomanip>
      32             : #include <ostream>
      33             : #include <vector>
      34             : #include <array>
      35             : 
      36             : template <typename T>
      37             : constexpr std::array<Real, SymmetricRankTwoTensorTempl<T>::N>
      38             :     SymmetricRankTwoTensorTempl<T>::identityCoords;
      39             : 
      40             : namespace MathUtils
      41             : {
      42             : template <>
      43             : void mooseSetToZero<SymmetricRankTwoTensor>(SymmetricRankTwoTensor & v);
      44             : template <>
      45             : void mooseSetToZero<ADSymmetricRankTwoTensor>(ADSymmetricRankTwoTensor & v);
      46             : }
      47             : 
      48             : template <typename T>
      49             : MooseEnum
      50           0 : SymmetricRankTwoTensorTempl<T>::fillMethodEnum()
      51             : {
      52           0 :   return MooseEnum("autodetect=0 isotropic1=1 diagonal3=3 symmetric6=6", "autodetect");
      53             : }
      54             : 
      55             : template <typename T>
      56        2802 : SymmetricRankTwoTensorTempl<T>::SymmetricRankTwoTensorTempl()
      57             : {
      58        2802 :   std::fill(_vals.begin(), _vals.end(), 0.0);
      59        2802 : }
      60             : 
      61             : template <typename T>
      62          21 : SymmetricRankTwoTensorTempl<T>::SymmetricRankTwoTensorTempl(const InitMethod init)
      63             : {
      64          21 :   switch (init)
      65             :   {
      66          20 :     case initNone:
      67          20 :       break;
      68             : 
      69           1 :     case initIdentity:
      70           1 :       setToIdentity();
      71           1 :       break;
      72             : 
      73           0 :     default:
      74           0 :       mooseError("Unknown SymmetricRankTwoTensorTempl initialization pattern.");
      75             :   }
      76          21 : }
      77             : 
      78             : template <typename T>
      79         225 : SymmetricRankTwoTensorTempl<T>::SymmetricRankTwoTensorTempl(
      80           0 :     const T & S11, const T & S22, const T & S33, const T & S23, const T & S13, const T & S12)
      81             : {
      82         225 :   _vals[0] = S11;
      83         225 :   _vals[1] = S22;
      84         225 :   _vals[2] = S33;
      85         225 :   _vals[3] = mandelFactor(3) * S23;
      86         225 :   _vals[4] = mandelFactor(4) * S13;
      87         225 :   _vals[5] = mandelFactor(5) * S12;
      88         225 : }
      89             : 
      90             : template <typename T>
      91          68 : SymmetricRankTwoTensorTempl<T>::operator RankTwoTensorTempl<T>()
      92             : {
      93          68 :   return RankTwoTensorTempl<T>(_vals[0],
      94          68 :                                _vals[5] / mandelFactor(5),
      95          68 :                                _vals[4] / mandelFactor(4),
      96          68 :                                _vals[5] / mandelFactor(5),
      97          68 :                                _vals[1],
      98          68 :                                _vals[3] / mandelFactor(3),
      99          68 :                                _vals[4] / mandelFactor(4),
     100         136 :                                _vals[3] / mandelFactor(3),
     101         204 :                                _vals[2]);
     102             : }
     103             : 
     104             : template <typename T>
     105           1 : SymmetricRankTwoTensorTempl<T>::SymmetricRankTwoTensorTempl(const T & S11,
     106             :                                                             const T & S21,
     107             :                                                             const T & S31,
     108             :                                                             const T & S12,
     109             :                                                             const T & S22,
     110             :                                                             const T & S32,
     111             :                                                             const T & S13,
     112             :                                                             const T & S23,
     113           0 :                                                             const T & S33)
     114             : {
     115           1 :   _vals[0] = S11;
     116           1 :   _vals[1] = S22;
     117           1 :   _vals[2] = S33;
     118           1 :   _vals[3] = (S23 + S32) / mandelFactor(3);
     119           1 :   _vals[4] = (S13 + S31) / mandelFactor(4);
     120           1 :   _vals[5] = (S12 + S21) / mandelFactor(5);
     121           1 : }
     122             : 
     123             : template <typename T>
     124             : SymmetricRankTwoTensorTempl<T>
     125           3 : SymmetricRankTwoTensorTempl<T>::fromRawComponents(
     126             :     const T & S11, const T & S22, const T & S33, const T & S23, const T & S13, const T & S12)
     127             : {
     128           3 :   SymmetricRankTwoTensorTempl<T> ret(SymmetricRankTwoTensorTempl<T>::initNone);
     129           3 :   ret._vals[0] = S11;
     130           3 :   ret._vals[1] = S22;
     131           3 :   ret._vals[2] = S33;
     132           3 :   ret._vals[3] = S23;
     133           3 :   ret._vals[4] = S13;
     134           3 :   ret._vals[5] = S12;
     135           3 :   return ret;
     136           0 : }
     137             : 
     138             : template <typename T>
     139           0 : SymmetricRankTwoTensorTempl<T>::SymmetricRankTwoTensorTempl(const TensorValue<T> & a)
     140             : {
     141           0 :   _vals[0] = a(0, 0);
     142           0 :   _vals[1] = a(1, 1);
     143           0 :   _vals[2] = a(2, 2);
     144           0 :   _vals[3] = (a(1, 2) + a(2, 1)) / mandelFactor(3);
     145           0 :   _vals[4] = (a(0, 2) + a(2, 0)) / mandelFactor(4);
     146           0 :   _vals[5] = (a(0, 1) + a(1, 0)) / mandelFactor(5);
     147           0 : }
     148             : 
     149             : template <typename T>
     150           0 : SymmetricRankTwoTensorTempl<T>::SymmetricRankTwoTensorTempl(const TypeTensor<T> & a)
     151             : {
     152           0 :   _vals[0] = a(0, 0);
     153           0 :   _vals[1] = a(1, 1);
     154           0 :   _vals[2] = a(2, 2);
     155           0 :   _vals[3] = (a(1, 2) + a(2, 1)) / mandelFactor(3);
     156           0 :   _vals[4] = (a(0, 2) + a(2, 0)) / mandelFactor(4);
     157           0 :   _vals[5] = (a(0, 1) + a(1, 0)) / mandelFactor(5);
     158           0 : }
     159             : 
     160             : /// named constructor for initializing symmetrically
     161             : template <typename T>
     162             : SymmetricRankTwoTensorTempl<T>
     163           1 : SymmetricRankTwoTensorTempl<T>::initializeSymmetric(const TypeVector<T> & v0,
     164             :                                                     const TypeVector<T> & v1,
     165             :                                                     const TypeVector<T> & v2)
     166             : {
     167             :   return SymmetricRankTwoTensorTempl<T>(
     168           1 :       v0(0), v1(0), v2(0), v0(1), v1(1), v2(1), v0(2), v1(2), v2(2));
     169             : }
     170             : 
     171             : template <typename T>
     172             : void
     173          82 : SymmetricRankTwoTensorTempl<T>::fillFromInputVector(const std::vector<T> & input,
     174             :                                                     FillMethod fill_method)
     175             : {
     176          82 :   if (fill_method != autodetect && fill_method != input.size())
     177           0 :     mooseError("Expected an input vector size of ",
     178             :                fill_method,
     179             :                " to fill the SymmetricRankTwoTensorTempl");
     180             : 
     181          82 :   switch (input.size())
     182             :   {
     183           1 :     case 1:
     184           1 :       _vals[0] = input[0];
     185           1 :       _vals[1] = input[0];
     186           1 :       _vals[2] = input[0];
     187           1 :       _vals[3] = 0.0;
     188           1 :       _vals[4] = 0.0;
     189           1 :       _vals[5] = 0.0;
     190           1 :       break;
     191             : 
     192           1 :     case 3:
     193           1 :       _vals[0] = input[0];
     194           1 :       _vals[1] = input[1];
     195           1 :       _vals[2] = input[2];
     196           1 :       _vals[3] = 0.0;
     197           1 :       _vals[4] = 0.0;
     198           1 :       _vals[5] = 0.0;
     199           1 :       break;
     200             : 
     201          79 :     case 6:
     202          79 :       _vals[0] = input[0];
     203          79 :       _vals[1] = input[1];
     204          79 :       _vals[2] = input[2];
     205          79 :       _vals[3] = mandelFactor(3) * input[3];
     206          79 :       _vals[4] = mandelFactor(4) * input[4];
     207          79 :       _vals[5] = mandelFactor(5) * input[5];
     208          79 :       break;
     209             : 
     210           1 :     default:
     211           1 :       mooseError("Please check the number of entries in the input vector for building "
     212             :                  "a SymmetricRankTwoTensorTempl. It must be 1, 3, 6");
     213             :   }
     214          81 : }
     215             : 
     216             : template <typename T>
     217             : void
     218           4 : SymmetricRankTwoTensorTempl<T>::fillFromScalarVariable(const VariableValue & scalar_variable)
     219             : {
     220           4 :   switch (scalar_variable.size())
     221             :   {
     222           1 :     case 1:
     223           1 :       _vals[0] = scalar_variable[0];
     224           1 :       _vals[1] = 0.0;
     225           1 :       _vals[2] = 0.0;
     226           1 :       _vals[3] = 0.0;
     227           1 :       _vals[4] = 0.0;
     228           1 :       _vals[5] = 0.0;
     229           1 :       break;
     230             : 
     231           1 :     case 3:
     232           1 :       _vals[0] = scalar_variable[0];
     233           1 :       _vals[1] = scalar_variable[1];
     234           1 :       _vals[2] = 0.0;
     235           1 :       _vals[3] = 0.0;
     236           1 :       _vals[4] = 0.0;
     237           1 :       _vals[5] = mandelFactor(5) * scalar_variable[2];
     238           1 :       break;
     239             : 
     240           1 :     case 6:
     241           1 :       _vals[0] = scalar_variable[0];
     242           1 :       _vals[1] = scalar_variable[1];
     243           1 :       _vals[2] = scalar_variable[2];
     244           1 :       _vals[3] = mandelFactor(3) * scalar_variable[3];
     245           1 :       _vals[4] = mandelFactor(4) * scalar_variable[4];
     246           1 :       _vals[5] = mandelFactor(5) * scalar_variable[5];
     247           1 :       break;
     248             : 
     249           1 :     default:
     250           1 :       mooseError("Only FIRST, THIRD, or SIXTH order scalar variable can be used to build "
     251             :                  "a SymmetricRankTwoTensorTempl.");
     252             :   }
     253           3 : }
     254             : 
     255             : template <typename T>
     256             : void
     257           1 : SymmetricRankTwoTensorTempl<T>::rotate(const TypeTensor<T> & R)
     258             : {
     259           1 :   auto M = SymmetricRankFourTensorTempl<T>::rotationMatrix(R);
     260           1 :   *this = M * (*this);
     261           1 : }
     262             : 
     263             : template <typename T>
     264             : SymmetricRankTwoTensorTempl<T>
     265           4 : SymmetricRankTwoTensorTempl<T>::transpose() const
     266             : {
     267           4 :   return *this;
     268             : }
     269             : 
     270             : /// multiply vector v with row n of this tensor
     271             : template <typename T>
     272             : libMesh::VectorValue<T>
     273           3 : SymmetricRankTwoTensorTempl<T>::row(const unsigned int n) const
     274             : {
     275           3 :   switch (n)
     276             :   {
     277           1 :     case 0:
     278             :       return libMesh::VectorValue<T>(
     279           1 :           _vals[0], _vals[5] / mandelFactor(5), _vals[4] / mandelFactor(4));
     280           1 :     case 1:
     281             :       return libMesh::VectorValue<T>(
     282           1 :           _vals[5] / mandelFactor(5), _vals[1], _vals[3] / mandelFactor(3));
     283           1 :     case 2:
     284             :       return libMesh::VectorValue<T>(
     285           1 :           _vals[4] / mandelFactor(4), _vals[3] / mandelFactor(3), _vals[2]);
     286           0 :     default:
     287           0 :       mooseError("Invalid row");
     288             :   }
     289             : }
     290             : 
     291             : template <typename T>
     292             : SymmetricRankTwoTensorTempl<T>
     293           1 : SymmetricRankTwoTensorTempl<T>::timesTranspose(const RankTwoTensorTempl<T> & a)
     294             : {
     295           1 :   return SymmetricRankTwoTensorTempl<T>(a(0, 0) * a(0, 0) + a(0, 1) * a(0, 1) + a(0, 2) * a(0, 2),
     296           1 :                                         a(1, 0) * a(1, 0) + a(1, 1) * a(1, 1) + a(1, 2) * a(1, 2),
     297           1 :                                         a(2, 0) * a(2, 0) + a(2, 1) * a(2, 1) + a(2, 2) * a(2, 2),
     298           1 :                                         a(1, 0) * a(2, 0) + a(1, 1) * a(2, 1) + a(1, 2) * a(2, 2),
     299           1 :                                         a(0, 0) * a(2, 0) + a(0, 1) * a(2, 1) + a(0, 2) * a(2, 2),
     300           2 :                                         a(0, 0) * a(1, 0) + a(0, 1) * a(1, 1) + a(0, 2) * a(1, 2));
     301             : }
     302             : 
     303             : template <typename T>
     304             : SymmetricRankTwoTensorTempl<T>
     305           3 : SymmetricRankTwoTensorTempl<T>::timesTranspose(const SymmetricRankTwoTensorTempl<T> & a)
     306             : {
     307           3 :   return SymmetricRankTwoTensorTempl<T>::fromRawComponents(
     308           3 :       a._vals[0] * a._vals[0] + a._vals[4] * a._vals[4] / 2.0 + a._vals[5] * a._vals[5] / 2.0,
     309           3 :       a._vals[1] * a._vals[1] + a._vals[3] * a._vals[3] / 2.0 + a._vals[5] * a._vals[5] / 2.0,
     310           3 :       a._vals[2] * a._vals[2] + a._vals[3] * a._vals[3] / 2.0 + a._vals[4] * a._vals[4] / 2.0,
     311           3 :       a._vals[1] * a._vals[3] + a._vals[2] * a._vals[3] +
     312           3 :           a._vals[4] * a._vals[5] / MathUtils::sqrt2,
     313           3 :       a._vals[0] * a._vals[4] + a._vals[2] * a._vals[4] +
     314           3 :           a._vals[3] * a._vals[5] / MathUtils::sqrt2,
     315           6 :       a._vals[0] * a._vals[5] + a._vals[1] * a._vals[5] +
     316           9 :           a._vals[3] * a._vals[4] / MathUtils::sqrt2);
     317             : }
     318             : 
     319             : template <typename T>
     320             : SymmetricRankTwoTensorTempl<T>
     321           1 : SymmetricRankTwoTensorTempl<T>::transposeTimes(const RankTwoTensorTempl<T> & a)
     322             : {
     323           1 :   return SymmetricRankTwoTensorTempl<T>(a(0, 0) * a(0, 0) + a(1, 0) * a(1, 0) + a(2, 0) * a(2, 0),
     324           1 :                                         a(0, 1) * a(0, 1) + a(1, 1) * a(1, 1) + a(2, 1) * a(2, 1),
     325           1 :                                         a(0, 2) * a(0, 2) + a(1, 2) * a(1, 2) + a(2, 2) * a(2, 2),
     326           1 :                                         a(0, 1) * a(0, 2) + a(1, 1) * a(1, 2) + a(2, 1) * a(2, 2),
     327           1 :                                         a(0, 0) * a(0, 2) + a(1, 0) * a(1, 2) + a(2, 0) * a(2, 2),
     328           2 :                                         a(0, 0) * a(0, 1) + a(1, 0) * a(1, 1) + a(2, 0) * a(2, 1));
     329             : }
     330             : 
     331             : template <typename T>
     332             : SymmetricRankTwoTensorTempl<T>
     333           1 : SymmetricRankTwoTensorTempl<T>::transposeTimes(const SymmetricRankTwoTensorTempl<T> & a)
     334             : {
     335           1 :   return timesTranspose(a);
     336             : }
     337             : 
     338             : template <typename T>
     339             : SymmetricRankTwoTensorTempl<T>
     340           0 : SymmetricRankTwoTensorTempl<T>::plusTranspose(const RankTwoTensorTempl<T> & a)
     341             : {
     342           0 :   return SymmetricRankTwoTensorTempl<T>(
     343           0 :              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)) *
     344           0 :          2.0;
     345             : }
     346             : 
     347             : template <typename T>
     348             : SymmetricRankTwoTensorTempl<T>
     349          10 : SymmetricRankTwoTensorTempl<T>::plusTranspose(const SymmetricRankTwoTensorTempl<T> & a)
     350             : {
     351          10 :   return a * 2.0;
     352             : }
     353             : 
     354             : template <typename T>
     355             : SymmetricRankTwoTensorTempl<T>
     356           1 : SymmetricRankTwoTensorTempl<T>::square() const
     357             : {
     358           1 :   return SymmetricRankTwoTensorTempl<T>::timesTranspose(*this);
     359             : }
     360             : 
     361             : template <typename T>
     362             : void
     363           1 : SymmetricRankTwoTensorTempl<T>::zero()
     364             : {
     365           7 :   for (std::size_t i = 0; i < N; ++i)
     366           6 :     _vals[i] = 0.0;
     367           1 : }
     368             : 
     369             : template <typename T>
     370             : SymmetricRankTwoTensorTempl<T> &
     371           1 : SymmetricRankTwoTensorTempl<T>::operator+=(const SymmetricRankTwoTensorTempl<T> & a)
     372             : {
     373           7 :   for (std::size_t i = 0; i < N; ++i)
     374           6 :     _vals[i] += a._vals[i];
     375           1 :   return *this;
     376             : }
     377             : 
     378             : template <typename T>
     379             : SymmetricRankTwoTensorTempl<T> &
     380           1 : SymmetricRankTwoTensorTempl<T>::operator-=(const SymmetricRankTwoTensorTempl<T> & a)
     381             : {
     382           7 :   for (std::size_t i = 0; i < N; ++i)
     383           6 :     _vals[i] -= a._vals[i];
     384           1 :   return *this;
     385             : }
     386             : 
     387             : template <typename T>
     388             : template <typename T2>
     389             : SymmetricRankTwoTensorTempl<typename libMesh::CompareTypes<T, T2>::supertype>
     390           1 : SymmetricRankTwoTensorTempl<T>::operator+(const SymmetricRankTwoTensorTempl<T2> & a) const
     391             : {
     392           1 :   SymmetricRankTwoTensorTempl<typename libMesh::CompareTypes<T, T2>::supertype> result;
     393           7 :   for (std::size_t i = 0; i < N; ++i)
     394           6 :     result(i) = _vals[i] + a(i);
     395           1 :   return result;
     396           0 : }
     397             : 
     398             : template <typename T>
     399             : template <typename T2>
     400             : SymmetricRankTwoTensorTempl<typename libMesh::CompareTypes<T, T2>::supertype>
     401          17 : SymmetricRankTwoTensorTempl<T>::operator-(const SymmetricRankTwoTensorTempl<T2> & a) const
     402             : {
     403          17 :   SymmetricRankTwoTensorTempl<typename libMesh::CompareTypes<T, T2>::supertype> result(
     404             :       SymmetricRankTwoTensorTempl<typename libMesh::CompareTypes<T, T2>::supertype>::initNone);
     405         119 :   for (std::size_t i = 0; i < N; ++i)
     406         102 :     result(i) = _vals[i] - a(i);
     407          17 :   return result;
     408           0 : }
     409             : 
     410             : /// returns -_vals
     411             : template <typename T>
     412             : SymmetricRankTwoTensorTempl<T>
     413           1 : SymmetricRankTwoTensorTempl<T>::operator-() const
     414             : {
     415           1 :   return (*this) * -1.0;
     416             : }
     417             : 
     418             : template <typename T>
     419             : SymmetricRankTwoTensorTempl<T> &
     420           1 : SymmetricRankTwoTensorTempl<T>::operator*=(const T & a)
     421             : {
     422           7 :   for (std::size_t i = 0; i < N; ++i)
     423           6 :     _vals[i] *= a;
     424           1 :   return *this;
     425             : }
     426             : 
     427             : template <typename T>
     428             : SymmetricRankTwoTensorTempl<T> &
     429           1 : SymmetricRankTwoTensorTempl<T>::operator/=(const T & a)
     430             : {
     431           7 :   for (std::size_t i = 0; i < N; ++i)
     432           6 :     _vals[i] /= a;
     433           1 :   return *this;
     434             : }
     435             : 
     436             : template <typename T>
     437             : T
     438           1 : SymmetricRankTwoTensorTempl<T>::doubleContraction(const SymmetricRankTwoTensorTempl<T> & b) const
     439             : {
     440           1 :   T sum = 0;
     441           7 :   for (unsigned int i = 0; i < N; ++i)
     442           6 :     sum += _vals[i] * b._vals[i];
     443           1 :   return sum;
     444           0 : }
     445             : 
     446             : template <typename T>
     447             : SymmetricRankFourTensorTempl<T>
     448           4 : SymmetricRankTwoTensorTempl<T>::outerProduct(const SymmetricRankTwoTensorTempl<T> & b) const
     449             : {
     450           4 :   SymmetricRankFourTensorTempl<T> result;
     451           4 :   unsigned int index = 0;
     452          28 :   for (unsigned int i = 0; i < N; ++i)
     453             :   {
     454          24 :     const T & a = _vals[i];
     455         168 :     for (unsigned int j = 0; j < N; ++j)
     456         144 :       result._vals[index++] = a * b._vals[j];
     457             :   }
     458           4 :   return result;
     459           0 : }
     460             : 
     461             : template <typename T>
     462             : SymmetricRankTwoTensorTempl<T>
     463          11 : SymmetricRankTwoTensorTempl<T>::deviatoric() const
     464             : {
     465          11 :   SymmetricRankTwoTensorTempl<T> deviatoric(*this);
     466          11 :   deviatoric.addIa(-1.0 / 3.0 * this->tr());
     467          11 :   return deviatoric;
     468           0 : }
     469             : 
     470             : template <typename T>
     471             : T
     472           2 : SymmetricRankTwoTensorTempl<T>::generalSecondInvariant() const
     473             : {
     474           2 :   return _vals[0] * _vals[1] + _vals[0] * _vals[2] + _vals[1] * _vals[2] -
     475           2 :          (_vals[3] * _vals[3] + _vals[4] * _vals[4] + _vals[5] * _vals[5]) / 2.0;
     476             : }
     477             : 
     478             : template <typename T>
     479             : T
     480           9 : SymmetricRankTwoTensorTempl<T>::secondInvariant() const
     481             : {
     482           0 :   T result;
     483           9 :   result = Utility::pow<2>(_vals[0] - _vals[1]) / 6.0;
     484           9 :   result += Utility::pow<2>(_vals[0] - _vals[2]) / 6.0;
     485           9 :   result += Utility::pow<2>(_vals[1] - _vals[2]) / 6.0;
     486           9 :   result += Utility::pow<2>(_vals[5]) / 2.0;
     487           9 :   result += Utility::pow<2>(_vals[4]) / 2.0;
     488           9 :   result += Utility::pow<2>(_vals[3]) / 2.0;
     489           9 :   return result;
     490           0 : }
     491             : 
     492             : template <typename T>
     493             : SymmetricRankTwoTensorTempl<T>
     494           2 : SymmetricRankTwoTensorTempl<T>::dsecondInvariant() const
     495             : {
     496           4 :   return SymmetricRankTwoTensorTempl<T>::plusTranspose(deviatoric()) * 0.5;
     497             : }
     498             : 
     499             : template <typename T>
     500             : SymmetricRankFourTensorTempl<T>
     501           1 : SymmetricRankTwoTensorTempl<T>::d2secondInvariant() const
     502             : {
     503           1 :   SymmetricRankFourTensorTempl<T> result;
     504             : 
     505           7 :   for (auto i : make_range(N))
     506          42 :     for (auto j : make_range(N))
     507          36 :       result(i, j) = 0.5 * (i == j) + 0.5 * (i == j) - (1.0 / 3.0) * (i < 3) * (j < 3);
     508             : 
     509           1 :   return result;
     510           0 : }
     511             : 
     512             : template <typename T>
     513             : T
     514           0 : SymmetricRankTwoTensorTempl<T>::trace() const
     515             : {
     516           0 :   return tr();
     517             : }
     518             : 
     519             : template <typename T>
     520             : SymmetricRankTwoTensorTempl<T>
     521           2 : SymmetricRankTwoTensorTempl<T>::inverse() const
     522             : {
     523           2 :   const auto d = det();
     524           2 :   if (d == 0.0)
     525           1 :     mooseException("Matrix not invertible");
     526           1 :   const SymmetricRankTwoTensorTempl<T> inv(
     527           1 :       _vals[2] * _vals[1] - _vals[3] * _vals[3] / 2.0,
     528           1 :       _vals[2] * _vals[0] - _vals[4] * _vals[4] / 2.0,
     529           1 :       _vals[0] * _vals[1] - _vals[5] * _vals[5] / 2.0,
     530           1 :       _vals[5] * _vals[4] / 2.0 - _vals[0] * _vals[3] / MathUtils::sqrt2,
     531           1 :       _vals[5] * _vals[3] / 2.0 - _vals[4] * _vals[1] / MathUtils::sqrt2,
     532           1 :       _vals[4] * _vals[3] / 2.0 - _vals[2] * _vals[5] / MathUtils::sqrt2);
     533           1 :   return inv * 1.0 / d;
     534           0 : }
     535             : 
     536             : template <typename T>
     537             : SymmetricRankTwoTensorTempl<T>
     538           2 : SymmetricRankTwoTensorTempl<T>::dtrace() const
     539             : {
     540           2 :   return SymmetricRankTwoTensorTempl<T>(1, 1, 1, 0, 0, 0);
     541             : }
     542             : 
     543             : template <typename T>
     544             : T
     545           4 : SymmetricRankTwoTensorTempl<T>::thirdInvariant() const
     546             : {
     547           4 :   const auto s = SymmetricRankTwoTensorTempl<T>::plusTranspose(deviatoric()) * 0.5;
     548           4 :   return s(0) * (s(1) * s(2) - s(3) / MathUtils::sqrt2 * s(3) / MathUtils::sqrt2) -
     549           4 :          s(5) / MathUtils::sqrt2 *
     550           4 :              (s(5) / MathUtils::sqrt2 * s(2) - s(3) / MathUtils::sqrt2 * s(4) / MathUtils::sqrt2) +
     551           4 :          s(4) / MathUtils::sqrt2 *
     552           4 :              (s(5) / MathUtils::sqrt2 * s(3) / MathUtils::sqrt2 - s(1) * s(4) / MathUtils::sqrt2);
     553           0 : }
     554             : 
     555             : template <typename T>
     556             : SymmetricRankTwoTensorTempl<T>
     557           2 : SymmetricRankTwoTensorTempl<T>::dthirdInvariant() const
     558             : {
     559           2 :   const auto s = SymmetricRankTwoTensorTempl<T>::plusTranspose(deviatoric()) * 0.5;
     560           2 :   const T s3 = secondInvariant() / 3.0;
     561           2 :   return SymmetricRankTwoTensorTempl<T>(s(1) * s(2) - s(3) * s(3) / 2.0 + s3,
     562           2 :                                         s(0) * s(2) - s(4) * s(4) / 2.0 + s3,
     563           2 :                                         s(0) * s(1) - s(5) * s(5) / 2.0 + s3,
     564           2 :                                         s(5) * s(4) / 2.0 - s(0) * s(3) / MathUtils::sqrt2,
     565           2 :                                         s(5) * s(3) / 2.0 - s(1) * s(4) / MathUtils::sqrt2,
     566           4 :                                         s(4) * s(3) / 2.0 - s(5) * s(2) / MathUtils::sqrt2);
     567           0 : }
     568             : 
     569             : template <typename T>
     570             : SymmetricRankFourTensorTempl<T>
     571           1 : SymmetricRankTwoTensorTempl<T>::d2thirdInvariant() const
     572             : {
     573           1 :   const auto s = SymmetricRankTwoTensorTempl<T>::plusTranspose(deviatoric()) * 0.5;
     574             : 
     575           1 :   SymmetricRankFourTensorTempl<T> d2;
     576           7 :   for (auto i : make_range(N))
     577          42 :     for (auto j : make_range(N))
     578          72 :       d2(i, j) = Real(i < 3) * s(j) / 3.0 / (j < 3 ? 1 : MathUtils::sqrt2) +
     579          36 :                  Real(j < 3) * s(i) / 3.0 / (i < 3 ? 1 : MathUtils::sqrt2);
     580             : 
     581           1 :   d2(0, 1) += s(2);
     582           1 :   d2(0, 2) += s(1);
     583           1 :   d2(0, 3) -= s(3) / MathUtils::sqrt2;
     584             : 
     585           1 :   d2(1, 0) += s(2);
     586           1 :   d2(1, 2) += s(0);
     587           1 :   d2(1, 4) -= s(4) / MathUtils::sqrt2;
     588             : 
     589           1 :   d2(2, 0) += s(1);
     590           1 :   d2(2, 1) += s(0);
     591           1 :   d2(2, 5) -= s(5) / MathUtils::sqrt2;
     592             : 
     593           1 :   d2(3, 0) -= s(3) / MathUtils::sqrt2;
     594           1 :   d2(3, 3) -= s(0) / 2.0;
     595           1 :   d2(3, 4) += s(5) / 2.0 / MathUtils::sqrt2;
     596           1 :   d2(3, 5) += s(4) / 2.0 / MathUtils::sqrt2;
     597             : 
     598           1 :   d2(4, 1) -= s(4) / MathUtils::sqrt2;
     599           1 :   d2(4, 3) += s(5) / 2.0 / MathUtils::sqrt2;
     600           1 :   d2(4, 4) -= s(1) / 2.0;
     601           1 :   d2(4, 5) += s(3) / 2.0 / MathUtils::sqrt2;
     602             : 
     603           1 :   d2(5, 2) -= s(5) / MathUtils::sqrt2;
     604           1 :   d2(5, 3) += s(4) / 2.0 / MathUtils::sqrt2;
     605           1 :   d2(5, 4) += s(3) / 2.0 / MathUtils::sqrt2;
     606           1 :   d2(5, 5) -= s(2) / 2.0;
     607             : 
     608           7 :   for (auto i : make_range(N))
     609          42 :     for (auto j : make_range(N))
     610          36 :       d2(i, j) *= SymmetricRankFourTensorTempl<T>::mandelFactor(i, j);
     611             : 
     612           2 :   return d2;
     613           0 : }
     614             : 
     615             : template <typename T>
     616             : T
     617           6 : SymmetricRankTwoTensorTempl<T>::det() const
     618             : {
     619           6 :   return _vals[0] * (_vals[2] * _vals[1] - _vals[3] * _vals[3] / 2.0) -
     620           6 :          _vals[5] / MathUtils::sqrt2 *
     621           6 :              (_vals[2] * _vals[5] / MathUtils::sqrt2 - _vals[3] * _vals[4] / 2.0) +
     622           6 :          _vals[4] / MathUtils::sqrt2 *
     623           6 :              (_vals[3] * _vals[5] / 2.0 - _vals[1] * _vals[4] / MathUtils::sqrt2);
     624             : }
     625             : 
     626             : template <typename T>
     627             : SymmetricRankTwoTensorTempl<T>
     628           1 : SymmetricRankTwoTensorTempl<T>::ddet() const
     629             : {
     630             :   return SymmetricRankTwoTensorTempl<T>(
     631           1 :       _vals[2] * _vals[1] - _vals[3] * _vals[3] / 2.0,
     632           1 :       _vals[0] * _vals[2] - _vals[4] * _vals[4] / 2.0,
     633           1 :       _vals[0] * _vals[1] - _vals[5] * _vals[5] / 2.0,
     634           1 :       _vals[4] * _vals[5] / 2.0 - _vals[0] * _vals[3] / MathUtils::sqrt2,
     635           1 :       _vals[5] * _vals[3] / 2.0 - _vals[4] * _vals[1] / MathUtils::sqrt2,
     636           2 :       _vals[4] * _vals[3] / 2.0 - _vals[5] * _vals[2] / MathUtils::sqrt2);
     637             : }
     638             : 
     639             : template <typename T>
     640             : void
     641           1 : SymmetricRankTwoTensorTempl<T>::print(std::ostream & stm) const
     642             : {
     643           7 :   for (std::size_t i = 0; i < N; ++i)
     644           6 :     stm << std::setw(15) << _vals[i] << std::endl;
     645           1 : }
     646             : 
     647             : template <typename T>
     648             : void
     649           1 : SymmetricRankTwoTensorTempl<T>::printReal(std::ostream & stm) const
     650             : {
     651           7 :   for (std::size_t i = 0; i < N; ++i)
     652           6 :     stm << std::setw(15) << MetaPhysicL::raw_value(_vals[i]) << std::endl;
     653           1 : }
     654             : 
     655             : template <typename T>
     656             : void
     657          12 : SymmetricRankTwoTensorTempl<T>::addIa(const T & a)
     658             : {
     659          48 :   for (unsigned int i = 0; i < 3; ++i)
     660          36 :     _vals[i] += a;
     661          12 : }
     662             : 
     663             : template <typename T>
     664             : T
     665          24 : SymmetricRankTwoTensorTempl<T>::L2norm() const
     666             : {
     667          24 :   T norm = _vals[0] * _vals[0];
     668         144 :   for (unsigned int i = 1; i < N; ++i)
     669         120 :     norm += _vals[i] * _vals[i];
     670          24 :   return norm == 0.0 ? 0.0 : std::sqrt(norm);
     671           0 : }
     672             : 
     673             : template <typename T>
     674             : void
     675           0 : SymmetricRankTwoTensorTempl<T>::syev(const char *, std::vector<T> &, std::vector<T> &) const
     676             : {
     677           0 :   mooseError("The syev method is only supported for Real valued tensors");
     678             : }
     679             : 
     680             : template <>
     681             : void SymmetricRankTwoTensor::syev(const char * calculation_type,
     682             :                                   std::vector<Real> & eigvals,
     683             :                                   std::vector<Real> & a) const;
     684             : 
     685             : template <typename T>
     686             : void
     687           0 : SymmetricRankTwoTensorTempl<T>::symmetricEigenvalues(std::vector<T> & eigvals) const
     688             : {
     689           0 :   RankTwoTensorTempl<T> a;
     690           0 :   symmetricEigenvaluesEigenvectors(eigvals, a);
     691           0 : }
     692             : 
     693             : template <>
     694             : void SymmetricRankTwoTensor::symmetricEigenvalues(std::vector<Real> & eigvals) const;
     695             : 
     696             : template <typename T>
     697             : void
     698           1 : SymmetricRankTwoTensorTempl<T>::symmetricEigenvaluesEigenvectors(std::vector<T> &,
     699             :                                                                  RankTwoTensorTempl<T> &) const
     700             : {
     701           1 :   mooseError(
     702             :       "symmetricEigenvaluesEigenvectors is only available for ordered tensor component types");
     703             : }
     704             : 
     705             : template <>
     706             : void SymmetricRankTwoTensor::symmetricEigenvaluesEigenvectors(std::vector<Real> & eigvals,
     707             :                                                               RankTwoTensor & eigvecs) const;
     708             : 
     709             : template <typename T>
     710             : void
     711           1 : SymmetricRankTwoTensorTempl<T>::initRandom(unsigned int rand_seed)
     712             : {
     713           1 :   MooseRandom::seed(rand_seed);
     714           1 : }
     715             : 
     716             : template <typename T>
     717             : SymmetricRankTwoTensorTempl<T>
     718           1 : SymmetricRankTwoTensorTempl<T>::genRandomSymmTensor(T scale, T offset)
     719             : {
     720           7 :   auto r = [&]() { return (MooseRandom::rand() + offset) * scale; };
     721           1 :   return SymmetricRankTwoTensorTempl<T>(r(), r(), r(), r(), r(), r());
     722             : }
     723             : 
     724             : template <typename T>
     725             : SymmetricRankTwoTensorTempl<T>
     726          10 : SymmetricRankTwoTensorTempl<T>::selfOuterProduct(const TypeVector<T> & v)
     727             : {
     728             :   return SymmetricRankTwoTensorTempl<T>(
     729          10 :       v(0) * v(0), v(1) * v(1), v(2) * v(2), v(1) * v(2), v(0) * v(2), v(0) * v(1));
     730             : }
     731             : 
     732             : template <typename T>
     733             : SymmetricRankTwoTensorTempl<T>
     734           1 : SymmetricRankTwoTensorTempl<T>::initialContraction(const SymmetricRankFourTensorTempl<T> & b) const
     735             : {
     736           1 :   SymmetricRankTwoTensorTempl<T> result;
     737           7 :   for (auto i : make_range(N))
     738          42 :     for (auto j : make_range(N))
     739          36 :       result(j) += (*this)(i)*b(i, j);
     740           1 :   return result;
     741           0 : }
     742             : 
     743             : template <typename T>
     744             : void
     745           1 : SymmetricRankTwoTensorTempl<T>::setToIdentity()
     746             : {
     747           1 :   std::copy(identityCoords.begin(), identityCoords.end(), _vals.begin());
     748           1 : }

Generated by: LCOV version 1.14