v0.15.0
Loading...
Searching...
No Matches
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
61namespace EigenMatrix {
62
63template <typename T, int Dim> using Val = const FTensor::Tensor1<T, Dim>;
64template <typename T, int Dim> using Vec = const FTensor::Tensor2<T, Dim, Dim>;
65template <typename T, int Dim>
67
68template <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 */
113template <typename A, typename B>
114auto 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 */
122 Vec<double, 3> &t_vec,
124 const int nb);
125/**
126 * @copydoc EigenMatrix::getDiffMat
127 */
131 Fun<double> d_f, const int nb);
132
133/**
134 * @copydoc EigenMatrix::getDiffMat
135 */
137 Vec<double, 2> &t_vec,
139 const int nb);
140
141/**
142 * @copydoc EigenMatrix::getDiffMat
143 */
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 */
165template <typename A, typename B>
166inline 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 */
176getDiffDiffMatSpecial(Val<double, 3> &t_val, Vec<double, 3> &t_vec,
178 FTensor::Tensor2_symmetric<double, 3> &t_S, const int nb);
179
180/**
181 * @copydoc EigenMatrix::getDiffDiffMat
182 */
185 Vec<FTensor::PackPtr<double *, 1>, 3> &t_vec,
187 FTensor::Tensor2_symmetric<double, 3> &t_S, const int nb);
188
189/**
190 * @copydoc EigenMatrix::getDiffDiffMat
191 */
193getDiffDiffMatSpecial(Val<double, 3> &t_val, Vec<double, 3> &t_vec,
195 FTensor::Tensor2<double, 3, 3> &t_S, const int nb);
196/**
197 * @copydoc EigenMatrix::getDiffDiffMat
198 */
201 Vec<FTensor::PackPtr<double *, 1>, 3> &t_vec,
203 FTensor::Tensor2<double, 3, 3> &t_S, const int nb);
204
205/**
206 * @copydoc EigenMatrix::getDiffDiffMat
207 */
211 Fun<double> d_f, Fun<double> dd_f,
213 const int nb);
214
215/**
216 * @copydoc EigenMatrix::getDiffDiffMat
217 */
219getDiffDiffMatSpecial(Val<double, 2> &t_val, Vec<double, 2> &t_vec,
221 FTensor::Tensor2<double, 2, 2> &t_S, const int nb);
222
223/**
224 * @copydoc EigenMatrix::getDiffDiffMat
225 */
227getDiffDiffMatSpecial(Val<double, 2> &t_val, Vec<double, 2> &t_vec,
229 FTensor::Tensor2_symmetric<double, 2> &t_S, const int nb);
230
231/**
232 * @copydoc EigenMatrix::getDiffDiffMat
233 */
236 Vec<FTensor::PackPtr<double *, 1>, 2> &t_vec,
238 FTensor::Tensor2<double, 2, 2> &t_S, const int nb);
239
240/**
241 * @copydoc EigenMatrix::getDiffDiffMat
242 */
245 Vec<FTensor::PackPtr<double *, 1>, 2> &t_vec,
247 FTensor::Tensor2_symmetric<double, 2> &t_S, const int nb);
248
249/**
250 * @copydoc EigenMatrix::getDiffDiffMat
251 */
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 */
278template <typename A, typename B, typename C>
279inline 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
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
const FTensor::Tensor1< T, Dim > Val
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.
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.
boost::function< T(const T)> Fun
FTensor::Tensor2_symmetric< double, 3 > getMatSpecial(Val< double, 3 > &t_val, Vec< double, 3 > &t_vec, Fun< double > f)
Get the Mat object.
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.