https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
12template <>
13void
14RankTwoTensor::printReal(std::ostream & stm) const
15{
16 this->print(stm);
17}
18
19template <>
20void
21ADRankTwoTensor::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
32template <>
33void
34ADRankTwoTensor::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
50template <>
51void
52RankTwoTensor::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
84template <>
85void
86RankTwoTensor::symmetricEigenvalues(std::vector<Real> & eigvals) const
87{
88 std::vector<Real> a;
89 syev("N", eigvals, a);
90}
91
92template <>
93void
94RankTwoTensor::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
105template <>
106void
107ADRankTwoTensor::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
135template <>
136void
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);
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}
for(PetscInt i=0;i< nvars;++i)
void ErrorVector unsigned int
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
static constexpr unsigned int N
Tensor dimension, i.e.
void syev(const char *calculation_type, std::vector< Real > &eigvals, std::vector< Real > &a) const
Uses the petscblaslapack.h LAPACKsyev_ routine to find, for symmetric _coords: (1) the eigenvalues (i...
RankTwoTensorTempl< T > inverse() const
Return the inverse of this second order tensor.
void getRUDecompositionRotation(RankTwoTensorTempl< Real > &rot) const
Uses the petscblaslapack.h LAPACKsyev_ routine to perform RU decomposition and obtain the rotation te...
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 print(std::ostream &stm=Moose::out) const
Print the rank two tensor.
void symmetricEigenvalues(std::vector< Real > &eigvals) const
computes eigenvalues, assuming tens is symmetric, and places them in ascending order in eigvals
void symmetricEigenvaluesEigenvectors(std::vector< Real > &eigvals, RankTwoTensorTempl< Real > &eigvecs) const
computes eigenvalues and eigenvectors, assuming tens is symmetric, and places them in ascending order...
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.
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64
MPI_Info info
IntRange< T > make_range(T beg, T end)