https://mooseframework.inl.gov
RankTwoTensorImplementation.C
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 
11 
12 template <>
13 void
14 RankTwoTensor::printReal(std::ostream & stm) const
15 {
16  this->print(stm);
17 }
18 
19 template <>
20 void
21 ADRankTwoTensor::printReal(std::ostream & stm) const
22 {
23  const ADRankTwoTensor & a = *this;
24  for (const auto i : make_range(N))
25  {
26  for (const auto j : make_range(N))
27  stm << std::setw(15) << a(i, j).value() << ' ';
28  stm << std::endl;
29  }
30 }
31 
32 template <>
33 void
34 ADRankTwoTensor::printADReal(unsigned int nDual, std::ostream & stm) const
35 {
36  const ADRankTwoTensor & a = *this;
37  for (const auto i : make_range(N))
38  {
39  for (const auto j : make_range(N))
40  {
41  stm << std::setw(15) << a(i, j).value() << " {";
42  for (const auto k : make_range(nDual))
43  stm << std::setw(5) << a(i, j).derivatives()[k] << ' ';
44  stm << " }";
45  }
46  stm << std::endl;
47  }
48 }
49 
50 template <>
51 void
52 RankTwoTensor::syev(const char * calculation_type,
53  std::vector<Real> & eigvals,
54  std::vector<Real> & a) const
55 {
56  eigvals.resize(N);
57  a.resize(N * N);
58 
59  // prepare data for the LAPACKsyev_ routine (which comes from petscblaslapack.h)
60  PetscBLASInt nd = N;
61  PetscBLASInt lwork = 66 * nd;
62  PetscBLASInt info;
63  std::vector<PetscScalar> work(lwork);
64 
65  for (const auto i : make_range(N))
66  for (const auto j : make_range(N))
67  // a is destroyed by dsyev, and if calculation_type == "V" then eigenvectors are placed
68  // there Note the explicit symmeterisation
69  a[i * N + j] = 0.5 * (this->operator()(i, j) + this->operator()(j, i));
70 
71  // compute the eigenvalues only (if calculation_type == "N"),
72  // or both the eigenvalues and eigenvectors (if calculation_type == "V")
73  // assume upper triangle of a is stored (second "U")
74  LAPACKsyev_(calculation_type, "U", &nd, &a[0], &nd, &eigvals[0], &work[0], &lwork, &info);
75 
76  if (info != 0)
77  mooseException(
78  "In computing the eigenvalues and eigenvectors for the symmetric rank-2 tensor (",
80  "), the PETSC LAPACK syev routine returned error code ",
81  info);
82 }
83 
84 template <>
85 void
86 RankTwoTensor::symmetricEigenvalues(std::vector<Real> & eigvals) const
87 {
88  std::vector<Real> a;
89  syev("N", eigvals, a);
90 }
91 
92 template <>
93 void
94 RankTwoTensor::symmetricEigenvaluesEigenvectors(std::vector<Real> & eigvals,
95  RankTwoTensor & eigvecs) const
96 {
97  std::vector<Real> a;
98  syev("V", eigvals, a);
99 
100  for (const auto i : make_range(N))
101  for (const auto j : make_range(N))
102  eigvecs(j, i) = a[i * N + j];
103 }
104 
105 template <>
106 void
107 ADRankTwoTensor::symmetricEigenvaluesEigenvectors(std::vector<ADReal> & eigvals,
108  ADRankTwoTensor & eigvecs) const
109 {
110  typedef Eigen::Matrix<ADReal, N, N> RankTwoMatrix;
111  RankTwoMatrix self;
112  for (const auto i : make_range(N))
113  for (unsigned int j = i; j < N; ++j)
114  {
115  auto & v = self(j, i);
116  v = (*this)(i, j);
117  if (i != j && MooseUtils::absoluteFuzzyEqual(v, 0.0))
118  v.value() = 0.0;
119  }
120 
121  Eigen::SelfAdjointEigenSolver<RankTwoMatrix> es;
122  es.compute(self);
123 
124  const auto & lambda = es.eigenvalues();
125  eigvals.resize(N);
126  for (const auto i : make_range(N))
127  eigvals[i] = lambda(i);
128 
129  const auto & v = es.eigenvectors();
130  for (const auto i : make_range(N))
131  for (const auto j : make_range(N))
132  eigvecs(i, j) = v(i, j);
133 }
134 
135 template <>
136 void
138 {
139  const RankTwoTensor & a = *this;
140  RankTwoTensor c, diag, evec;
141  PetscScalar cmat[N][N], work[10];
142  PetscReal w[N];
143 
144  // prepare data for the LAPACKsyev_ routine (which comes from petscblaslapack.h)
145  PetscBLASInt nd = N, lwork = 10, info;
146 
147  c = a.transpose() * a;
148 
149  for (const auto i : make_range(N))
150  for (const auto j : make_range(N))
151  cmat[i][j] = c(i, j);
152 
153  LAPACKsyev_("V", "U", &nd, &cmat[0][0], &nd, w, work, &lwork, &info);
154 
155  if (info != 0)
156  mooseException(
157  "In computing the eigenvalues and eigenvectors of a symmetric rank-2 tensor, the "
158  "PETSC LAPACK syev routine returned error code ",
159  info);
160 
161  diag.zero();
162 
163  for (const auto i : make_range(N))
164  diag(i, i) = std::sqrt(w[i]);
165 
166  for (const auto i : make_range(N))
167  for (const auto j : make_range(N))
168  evec(i, j) = cmat[i][j];
169 
170  rot = a * (evec.transpose() * diag * evec).inverse();
171 }
RankTwoTensorTempl< T > inverse() const
Return the inverse of this second order tensor.
void printADReal(unsigned int nDual, std::ostream &stm=Moose::out) const
Print the Real part of the RankTwoTensorTempl<ADReal> along with its first nDual dual numbers...
void symmetricEigenvalues(std::vector< T > &eigvals) const
computes eigenvalues, assuming tens is symmetric, and places them in ascending order in eigvals ...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
MPI_Info info
void print(std::ostream &stm=Moose::out) const
Print the rank two tensor.
static constexpr unsigned int N
Tensor dimension, i.e.
Definition: RankTwoTensor.h:95
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
void printReal(std::ostream &stm=Moose::out) const
Print the Real part of the RankTwoTensorTempl<ADReal>
RankTwoTensorTempl< T > transpose() const
Return the tensor transposed.
void symmetricEigenvaluesEigenvectors(std::vector< T > &eigvals, RankTwoTensorTempl< T > &eigvecs) const
computes eigenvalues and eigenvectors, assuming tens is symmetric, and places them in ascending order...
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
Definition: RankTwoTensor.h:87
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 _coords: (1) the eigenvalues (i...
IntRange< T > make_range(T beg, T end)
void getRUDecompositionRotation(RankTwoTensorTempl< T > &rot) const
Uses the petscblaslapack.h LAPACKsyev_ routine to perform RU decomposition and obtain the rotation te...
const T & operator()(const unsigned int i, const unsigned int j) const