v0.14.0
MatrixFunction.hpp
Go to the documentation of this file.
1 /** \file FunctionMatrix.hpp
2  \brief Get function from matrix
3  \ingroup ftensor
4 
5  For reference see \cite miehe2001algorithms
6 
7  Usage:
8 
9  To calculate exponent of matrix, first and second derivatives
10  \code
11  auto f = [](double v) { return exp(v); };
12  auto d_f = [](double v) { return exp(v); };
13  auto dd_f = [](double v) { return exp(v); };
14  \endcode
15 
16  Calculate matrix here t_L are vector of eigen values, and t_N is matrix of
17  eigen vectors.
18  \code
19  auto t_A = EigenMatrix::getMat(t_L, t_N, f);
20  \endcode
21  Return t_A is symmetric tensor rank two.
22 
23  Calculate derivative
24  \code
25  auto t_P = EigenMatrix::getDiffMat(t_L, t_N, f, d_f ,nb);
26  \endcode
27  where return t_SL is 4th order tensor (symmetry on first two and
28  second to indices, i.e. minor symmetrise)
29 
30  Calculate second derivative, L, such that S:L, for given S,
31  \code
32  FTensor::Tensor2<double, 3, 3> t_S{
33 
34  1., 0., 0.,
35 
36  0., 1., 0.,
37 
38  0., 0., 1.};
39 
40  auto t_SL = EigenMatrix::getDiffDiffMat( t_L, t_N, f, d_f, dd_f, t_S, nb)
41  \endcode
42  where return t_SL is 4th order tensor (symmetry on first two and
43  second to indices, i.e. minor symmetrise)
44 
45  You can calculate eigen values using lapack.
46 
47  Eiegn values should be sorted such that unique values are first, and last eiegn
48  value is reapitting. For example if eiegn values are \f[ \lambda = \{1,1,2} \f]
49  should be sorted such that
50  \f[
51  \lambda = \{1,2,1}
52  \f]
53  Eigen vectors should be updated, such that order of eigen vectors follow order
54  of eigen values.
55 
56  *
57  */
58 
59 #pragma once
60 
61 namespace EigenMatrix {
62 
63 template <typename T, int Dim> using Val = const FTensor::Tensor1<T, Dim>;
64 template <typename T, int Dim> using Vec = const FTensor::Tensor2<T, Dim, Dim>;
65 template <typename T, int Dim>
67 
68 template <typename T> using Fun = boost::function<T(const T)>;
69 
70 /**
71  * @copydoc EigenMatrix::getMat
72  */
75 
76 /**
77  * @copydoc EigenMatrix::getMat
78  */
82 
83 /**
84  * @copydoc EigenMatrix::getMat
85  */
88 
89 /**
90  * @copydoc EigenMatrix::getMat
91  */
95 
96 /**
97  * @brief Get the Mat object
98  *
99  * \f[
100  * \mathbf{B} = f(\mathbf{A})
101  * \f]
102  *
103  * \f[
104  * B_{ij} = \sum_{a}^d f(\lambda^a) n^a_i n^a_j
105  * \f]
106  * where \f$a\f$ is eigen value number.
107  *
108  * @param t_val eigen values
109  * @param t_vec eigen vector
110  * @param f function
111  * @return FTensor::Tensor2_symmetric<double, 3>
112  */
113 template <typename A, typename B>
114 auto inline getMat(A &&t_val, B &&t_vec, Fun<double> f) {
115  return getMatSpecial(std::forward<A>(t_val), std::forward<B>(t_vec), f);
116 }
117 
118 /**
119  * @copydoc EigenMatrix::getDiffMat
120  */
121 FTensor::Ddg<double, 3, 3> getDiffMatSpecial(Val<double, 3> &t_val,
122  Vec<double, 3> &t_vec,
123  Fun<double> f, Fun<double> d_f,
124  const int nb);
125 /**
126  * @copydoc EigenMatrix::getDiffMat
127  */
130  Vec<FTensor::PackPtr<double *, 1>, 3> &t_vec, Fun<double> f,
131  Fun<double> d_f, const int nb);
132 
133 /**
134  * @copydoc EigenMatrix::getDiffMat
135  */
136 FTensor::Ddg<double, 2, 2> getDiffMatSpecial(Val<double, 2> &t_val,
137  Vec<double, 2> &t_vec,
138  Fun<double> f, Fun<double> d_f,
139  const int nb);
140 
141 /**
142  * @copydoc EigenMatrix::getDiffMat
143  */
146  Vec<FTensor::PackPtr<double *, 1>, 2> &t_vec, Fun<double> f,
147  Fun<double> d_f, const int nb);
148 
149 /**
150  * @brief Get the Diff Mat object
151  *
152  * \f[
153  * P_{ijkl} = \frac{\partial B_{ij}}{\partial A_{kl}}
154  * \f]
155  *
156  * \note Eigen vector are in rows.
157  *
158  * @param t_val eigen values
159  * @param t_vec eigen vector
160  * @param f function
161  * @param d_f directive of function
162  * @param nb number of nonequal eigen valuse
163  * @return FTensor::Ddg<double, 3, 3>
164  */
165 template <typename A, typename B>
166 inline auto getDiffMat(A &&t_val, B &&t_vec, Fun<double> f, Fun<double> d_f,
167  const int nb) {
168  return getDiffMatSpecial(std::forward<A>(t_val), std::forward<B>(t_vec), f,
169  d_f, nb);
170 }
171 
172 /**
173  * @copydoc EigenMatrix::getDiffDiffMat
174  */
176 getDiffDiffMatSpecial(Val<double, 3> &t_val, Vec<double, 3> &t_vec,
177  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
178  FTensor::Tensor2_symmetric<double, 3> &t_S, const int nb);
179 
180 /**
181  * @copydoc EigenMatrix::getDiffDiffMat
182  */
186  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
187  FTensor::Tensor2_symmetric<double, 3> &t_S, const int nb);
188 
189 /**
190  * @copydoc EigenMatrix::getDiffDiffMat
191  */
193 getDiffDiffMatSpecial(Val<double, 3> &t_val, Vec<double, 3> &t_vec,
194  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
195  FTensor::Tensor2<double, 3, 3> &t_S, const int nb);
196 /**
197  * @copydoc EigenMatrix::getDiffDiffMat
198  */
202  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
203  FTensor::Tensor2<double, 3, 3> &t_S, const int nb);
204 
205 /**
206  * @copydoc EigenMatrix::getDiffDiffMat
207  */
210  Vec<FTensor::PackPtr<double *, 1>, 3> &t_vec, Fun<double> f,
211  Fun<double> d_f, Fun<double> dd_f,
213  const int nb);
214 
215 /**
216  * @copydoc EigenMatrix::getDiffDiffMat
217  */
219 getDiffDiffMatSpecial(Val<double, 2> &t_val, Vec<double, 2> &t_vec,
220  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
221  FTensor::Tensor2<double, 2, 2> &t_S, const int nb);
222 
223 /**
224  * @copydoc EigenMatrix::getDiffDiffMat
225  */
227 getDiffDiffMatSpecial(Val<double, 2> &t_val, Vec<double, 2> &t_vec,
228  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
229  FTensor::Tensor2_symmetric<double, 2> &t_S, const int nb);
230 
231 /**
232  * @copydoc EigenMatrix::getDiffDiffMat
233  */
237  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
238  FTensor::Tensor2<double, 2, 2> &t_S, const int nb);
239 
240 /**
241  * @copydoc EigenMatrix::getDiffDiffMat
242  */
246  Fun<double> f, Fun<double> d_f, Fun<double> dd_f,
247  FTensor::Tensor2_symmetric<double, 2> &t_S, const int nb);
248 
249 /**
250  * @copydoc EigenMatrix::getDiffDiffMat
251  */
254  Vec<FTensor::PackPtr<double *, 1>, 2> &t_vec, Fun<double> f,
255  Fun<double> d_f, Fun<double> dd_f,
257  const int nb);
258 
259 /**
260  * @brief Get the Diff Diff Mat object
261  *
262  * \f[
263  * LS_{klmn} =
264  * S_{ij} \frac{\partial^2 B_{ij}}{\partial A_{kl} \partial A_{mn} }
265  * \f]
266  *
267  * \note Eigen vector are in rows.
268  *
269  * @param t_val eigen values
270  * @param t_vec eigen vectors
271  * @param f function
272  * @param d_f directive of function
273  * @param dd_f second directive of function
274  * @param t_S S tensor
275  * @param nb number of nonzero eigen values
276  * @return FTensor::Ddg<double, 3, 3>
277  */
278 template <typename A, typename B, typename C>
279 inline auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun<double> f, Fun<double> d_f,
280  Fun<double> dd_f, C &&t_S, const int nb) {
281  return getDiffDiffMatSpecial(std::forward<A>(t_val), std::forward<B>(t_vec),
282  f, d_f, dd_f, std::forward<C>(t_S), nb);
283 }
284 
285 } // namespace EigenMatrix
FTensor::Tensor1
Definition: Tensor1_value.hpp:8
EigenMatrix::getMatSpecial
FTensor::Tensor2_symmetric< double, 3 > getMatSpecial(Val< double, 3 > &t_val, Vec< double, 3 > &t_vec, Fun< double > f)
Get the Mat object.
Definition: MatrixFunction.cpp:54
HenckyOps::d_f
auto d_f
Definition: HenckyOps.hpp:16
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
FTensor::Tensor2_symmetric
Definition: Tensor2_symmetric_value.hpp:13
FTensor::Tensor2
Definition: Tensor2_value.hpp:16
EigenMatrix::getMat
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
Definition: MatrixFunction.hpp:114
EigenMatrix::getDiffMat
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
Definition: MatrixFunction.hpp:166
EigenMatrix
Definition: MatrixFunction.cpp:8
EigenMatrix::getDiffMatSpecial
FTensor::Ddg< double, 3, 3 > getDiffMatSpecial(Val< double, 3 > &t_val, Vec< double, 3 > &t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
Definition: MatrixFunction.cpp:64
EigenMatrix::Val
const FTensor::Tensor1< T, Dim > Val
Definition: MatrixFunction.hpp:63
FTensor::PackPtr
Definition: FTensor.hpp:54
HenckyOps::dd_f
auto dd_f
Definition: HenckyOps.hpp:17
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
FTensor::Ddg< double, 3, 3 >
EigenMatrix::Vec
const FTensor::Tensor2< T, Dim, Dim > Vec
Definition: MatrixFunction.hpp:64
EigenMatrix::Fun
boost::function< T(const T)> Fun
Definition: MatrixFunction.hpp:68
EigenMatrix::getDiffDiffMatSpecial
FTensor::Ddg< double, 3, 3 > getDiffDiffMatSpecial(Val< double, 3 > &t_val, Vec< double, 3 > &t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, FTensor::Tensor2< double, 3, 3 > &t_S, const int nb)
Get the Diff Diff Mat object.
Definition: MatrixFunction.cpp:80
EigenMatrix::getDiffDiffMat
auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, C &&t_S, const int nb)
Get the Diff Diff Mat object.
Definition: MatrixFunction.hpp:279