https://mooseframework.inl.gov
FactorizedRankTwoTensor.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 "RankTwoTensor.h"
13 #include "SymmetricRankTwoTensor.h"
14 
15 // forward declarations
16 template <typename>
18 
34 template <typename T>
36 {
37 public:
39  typedef typename T::value_type value_type;
40 
43 
46 
49  {
50  if (!A.isSymmetric())
51  mooseError("The tensor is not symmetric.");
52  A.symmetricEigenvaluesEigenvectors(_eigvals, _eigvecs);
53  }
54 
55  // Construct from the factorization
56  // Assume that regardless of the type of T, the eigenvectors are always stored as as a full second
57  // order tensor, e.g. the eigenvector matrix of a symmetric second order tensor isn't symmetric in
58  // general. Hence we don't take advantage of orthonormal and/or unitary second order tensors.
59  FactorizedRankTwoTensorTempl(const std::vector<typename T::value_type> & eigvals,
62  {
63  }
64 
65  // @{ getters
66  template <typename T2 = T>
67  T2 get() const
68  {
69  return static_cast<T2>(assemble());
70  }
71  template <typename T2 = T>
72  T2 get()
73  {
74  return static_cast<T2>(assemble());
75  }
76  const std::vector<typename T::value_type> & eigvals() const { return _eigvals; }
77  std::vector<typename T::value_type> eigvals() { return _eigvals; }
80  // @}
81 
82  void print(std::ostream & stm = Moose::out) const;
83 
84  // Returns _A rotated by R.
87 
90 
91  // @{ Assignment operators
94  // @}
95 
97  FactorizedRankTwoTensorTempl<T> & operator*=(const typename T::value_type & a);
98 
100  template <typename T2>
101  FactorizedRankTwoTensorTempl<T> operator*(const T2 & a) const;
102 
104  FactorizedRankTwoTensorTempl<T> & operator/=(const typename T::value_type & a);
105 
107  template <typename T2>
108  FactorizedRankTwoTensorTempl<T> operator/(const T2 & a) const;
109 
111  bool operator==(const T & A) const;
112 
114  bool operator==(const FactorizedRankTwoTensorTempl<T> & A) const;
115 
118 
120  void addIa(const typename T::value_type & a);
121 
123  typename T::value_type trace() const;
124 
126  typename T::value_type det() const;
127 
128 private:
129  // Assemble the tensor from the factorization
131  {
133  return _eigvals[0] * R2T::selfOuterProduct(_eigvecs.column(0)) +
134  _eigvals[1] * R2T::selfOuterProduct(_eigvecs.column(1)) +
135  _eigvals[2] * R2T::selfOuterProduct(_eigvecs.column(2));
136  }
137 
138  // The eigen values of _A;
139  std::vector<typename T::value_type> _eigvals;
140 
141  // The eigen vectors of _A;
143 };
144 
145 namespace MathUtils
146 {
147 #define FactorizedRankTwoTensorOperatorMapBody(operator) \
148  { \
149  std::vector<typename T::value_type> op_eigvals; \
150  for (const auto & eigval : A.eigvals()) \
151  op_eigvals.push_back(operator); \
152  return FactorizedRankTwoTensorTempl<T>(op_eigvals, A.eigvecs()); \
153  }
154 
155 #define FactorizedRankTwoTensorOperatorMapUnary(operatorname, operator) \
156  template <typename T> \
157  FactorizedRankTwoTensorTempl<T> operatorname(const FactorizedRankTwoTensorTempl<T> & A) \
158  { \
159  FactorizedRankTwoTensorOperatorMapBody(operator) \
160  } \
161  static_assert(true, "")
162 
163 #define FactorizedRankTwoTensorOperatorMapBinary(operatorname, operator) \
164  template <typename T, typename T2> \
165  FactorizedRankTwoTensorTempl<T> operatorname(const FactorizedRankTwoTensorTempl<T> & A, \
166  const T2 & arg) \
167  { \
168  if constexpr (libMesh::ScalarTraits<T2>::value) \
169  { \
170  FactorizedRankTwoTensorOperatorMapBody(operator) \
171  } \
172  } \
173  static_assert(true, "")
174 
175 #define FactorizedRankTwoTensorOperatorMapDerivativeBody(operator, derivative) \
176  { \
177  std::vector<typename T::value_type> op_eigvals, op_derivs; \
178  for (const auto & eigval : A.eigvals()) \
179  { \
180  op_eigvals.push_back(operator); \
181  op_derivs.push_back(derivative); \
182  } \
183  \
184  RankFourTensorTempl<typename T::value_type> P, Gab, Gba; \
185  typedef RankTwoTensorTempl<typename T::value_type> R2T; \
186  \
187  for (auto a : make_range(3)) \
188  { \
189  const auto Ma = R2T::selfOuterProduct(A.eigvecs().column(a)); \
190  P += op_derivs[a] * Ma.outerProduct(Ma); \
191  } \
192  \
193  for (auto a : make_range(3)) \
194  for (auto b : make_range(a)) \
195  { \
196  const auto Ma = R2T::selfOuterProduct(A.eigvecs().column(a)); \
197  const auto Mb = R2T::selfOuterProduct(A.eigvecs().column(b)); \
198  \
199  usingTensorIndices(i_, j_, k_, l_); \
200  Gab = Ma.template times<i_, k_, j_, l_>(Mb) + Ma.template times<i_, l_, j_, k_>(Mb); \
201  Gba = Mb.template times<i_, k_, j_, l_>(Ma) + Mb.template times<i_, l_, j_, k_>(Ma); \
202  \
203  Real theta_ab; \
204  if (!MooseUtils::absoluteFuzzyEqual(A.eigvals()[a], A.eigvals()[b])) \
205  theta_ab = 0.5 * (op_eigvals[a] - op_eigvals[b]) / (A.eigvals()[a] - A.eigvals()[b]); \
206  else \
207  theta_ab = 0.25 * (op_derivs[a] + op_derivs[b]); \
208  \
209  P += theta_ab * (Gab + Gba); \
210  } \
211  return P; \
212  }
213 
214 #define FactorizedRankTwoTensorOperatorMapDerivativeUnary(derivativename, operator, derivative) \
215  template <typename T> \
216  RankFourTensorTempl<typename T::value_type> derivativename( \
217  const FactorizedRankTwoTensorTempl<T> & A) \
218  { \
219  FactorizedRankTwoTensorOperatorMapDerivativeBody(operator, derivative) \
220  } \
221  static_assert(true, "")
222 
223 #define FactorizedRankTwoTensorOperatorMapDerivativeBinary(derivativename, operator, derivative) \
224  template <typename T, typename T2> \
225  RankFourTensorTempl<typename T::value_type> derivativename( \
226  const FactorizedRankTwoTensorTempl<T> & A, const T2 & arg) \
227  { \
228  if constexpr (libMesh::ScalarTraits<T2>::value) \
229  { \
230  FactorizedRankTwoTensorOperatorMapDerivativeBody(operator, derivative) \
231  } \
232  } \
233  static_assert(true, "")
234 
235 // TODO: While the macros are here, in the future we could instantiate other operator maps like
236 // trignometry functions.
237 // @{
240 
243 
246  std::sqrt(eigval),
247  std::pow(eigval, -1. / 2.) / 2.);
248 
249 FactorizedRankTwoTensorOperatorMapUnary(cbrt, std::cbrt(eigval));
251  std::cbrt(eigval),
252  std::pow(eigval, -2. / 3.) / 3.);
253 
256  std::pow(eigval, arg),
257  arg * std::pow(eigval, arg - 1));
258 // @}
259 } // end namespace MathUtils
260 
261 template <typename T>
262 template <typename T2>
265 {
266  if constexpr (libMesh::ScalarTraits<T2>::value)
267  {
269  for (auto & eigval : A._eigvals)
270  eigval *= a;
271  return A;
272  }
273 }
274 
275 template <typename T>
276 template <typename T2>
279 {
280  if constexpr (libMesh::ScalarTraits<T2>::value)
281  {
283  for (auto & eigval : A._eigvals)
284  eigval /= a;
285  return A;
286  }
287 }
288 
T::value_type trace() const
trace of _A
std::vector< typename T::value_type > eigvals()
T::value_type value_type
For generic programming.
FactorizedRankTwoTensorTempl< T > & operator/=(const typename T::value_type &a)
performs _A /= a in place, also updates eigen values
FactorizedRankTwoTensorTempl< T > & operator*=(const typename T::value_type &a)
performs _A *= a in place, also updates eigen values
auto exp(const T &)
FactorizedRankTwoTensorTempl< T > rotated(const RankTwoTensorTempl< typename T::value_type > &R) const
T::value_type det() const
determinant of _A
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
const RankTwoTensorTempl< typename T::value_type > & eigvecs() const
RankTwoTensorTempl< typename T::value_type > _eigvecs
std::vector< typename T::value_type > _eigvals
FactorizedRankTwoTensorOperatorMapDerivativeUnary(dlog, std::log(eigval), 1/eigval)
FactorizedRankTwoTensorTempl< T > operator*(const T2 &a) const
returns _A * a, also updates eigen values
FactorizedRankTwoTensorTempl< ADSymmetricRankTwoTensor > ADFactorizedSymmetricRankTwoTensor
FactorizedRankTwoTensorTempl(const std::vector< typename T::value_type > &eigvals, const RankTwoTensorTempl< typename T::value_type > &eigvecs)
FactorizedRankTwoTensorTempl< T > transpose() const
Returns the transpose of _A.
FactorizedRankTwoTensorTempl< SymmetricRankTwoTensor > FactorizedSymmetricRankTwoTensor
FactorizedRankTwoTensorOperatorMapBinary(pow, std::pow(eigval, arg))
FactorizedRankTwoTensorTempl is designed to perform the spectral decomposition of an underlying symme...
RankTwoTensorTempl< typename T::value_type > eigvecs()
libMesh::VectorValue< T > column(const unsigned int i) const
Get the i-th column of the second order tensor.
const std::vector< typename T::value_type > & eigvals() const
auto log(const T &)
FactorizedRankTwoTensorTempl< RankTwoTensor > FactorizedRankTwoTensor
FactorizedRankTwoTensorOperatorMapUnary(log, std::log(eigval))
FactorizedRankTwoTensorTempl()=delete
No default constructor.
void print(std::ostream &stm=Moose::out) const
void addIa(const typename T::value_type &a)
add identity times a to _A
FactorizedRankTwoTensorTempl(const T &A)
Constructor if the factorization isn&#39;t known a priori.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
FactorizedRankTwoTensorTempl< T > & operator=(const FactorizedRankTwoTensorTempl< T > &A)
bool operator==(const T &A) const
Defines logical equality with another second order tensor.
RankTwoTensorTempl< typename T::value_type > assemble() const
T pow(T x, int e)
Definition: MathUtils.h:91
MooseUnits pow(const MooseUnits &, int)
Definition: Units.C:537
FactorizedRankTwoTensorTempl< T > inverse() const
inverse of _A
FactorizedRankTwoTensorOperatorMapDerivativeBinary(dpow, std::pow(eigval, arg), arg *std::pow(eigval, arg - 1))
FactorizedRankTwoTensorTempl< T > operator/(const T2 &a) const
returns _A / a, also updates eigen values
FactorizedRankTwoTensorTempl< ADRankTwoTensor > ADFactorizedRankTwoTensor